Skip to content

Instantly share code, notes, and snippets.

@ynsta ynsta/sampler.py
Last active Apr 25, 2019

Embed
What would you like to do?
Statistic profiling on stm32f4 with openocd by dwt_pcsr sampling
#!/usr/bin/python2
# run openocd (0.9.0) with :
# $ openocd -f stlink-v2-1.cfg -f stm32f4x.cfg &> /dev/null"
# then run
# $ python2 sampler.py path_to_myelf_with_symbols
import sys
import time
import telnetlib
import subprocess
from bisect import bisect_right
import operator
class OpenOCDCMSampler(object):
def __init__(self, host='localhost', port=4444):
self.net = telnetlib.Telnet(host, port)
self.net.read_very_eager()
self.table = []
self.indexes = set()
def __del__(self):
self.net.write('exit\r\n')
self.net.read_until('exit\r\n', 1)
self.net.close()
def getpc(self):
self.net.write('mrw 0xE000101C\r\n')
res = self.net.read_until('\r\n\r> ', 1)
if res:
prefix = res[0:16]
num = res[16:-5]
res = res[-15:0]
if prefix == 'mrw 0xE000101C\r\n':
return int(num)
return 0
def initSymbols(self, elf, readelf='readelf'):
proc = subprocess.Popen([readelf, '-s', elf], stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
field = line.split()
try:
if field[3] == 'FUNC':
addr = int(field[1], 16)
func = field[7]
size = int(field[2])
if addr not in self.indexes:
self.table.append((addr, func, size))
self.indexes.add(addr)
except IndexError:
pass
self.table.sort()
self.addrs = [ x for (x, y, z) in self.table ]
def func(self, pc):
if pc == 0 or pc == 0xFFFFFFFF:
return ('', 0)
i = bisect_right(self.addrs, pc)
if i:
addr, symb, size = self.table[i-1]
if pc >= addr and pc <= addr + size:
return (symb, addr)
return ('', 0)
if __name__ == '__main__':
sampler = OpenOCDCMSampler('localhost', 4444)
sampler.initSymbols(sys.argv[1])
total = 0
countmap = { }
start = time.time()
try:
while True:
func, addr = sampler.func((sampler.getpc()))
if not addr:
continue
if func in countmap:
countmap[func] += 1
total += 1
else:
countmap[func] = 1
total += 1
cur = time.time()
if cur - start > 1.0:
tmp = sorted(countmap.items(), key=operator.itemgetter(1), reverse=True)
for k, v in tmp:
print '{:05.2f}% {}'.format((v * 100.) / total, k)
start = cur
print ''
except KeyboardInterrupt:
pass
@rossyeager

This comment has been minimized.

Copy link

commented Feb 8, 2018

Hi ynsta, what is the usage agreement on this code? do you mind if I use it? It is awesome btw, thanks for sharing with the world!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.