Skip to content

Commit 69f2841

Browse files
tor-jeremiassenmathieupoirier
authored andcommitted
perf scripts: Add python scripts for CoreSight traces
Example scripts for CoreSight trace processing with perf script. Signed-off-by: Tor Jeremiassen <tor@ti.com>
1 parent 1265cc3 commit 69f2841

2 files changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# perf script event handlers, generated by perf script -g python
2+
# Licensed under the terms of the GNU GPL License version 2
3+
4+
# The common_* event handler fields are the most useful fields common to
5+
# all events. They don't necessarily correspond to the 'common_*' fields
6+
# in the format files. Those fields not available as handler params can
7+
# be retrieved using Python functions of the form common_*(context).
8+
# See the perf-trace-python Documentation for the list of available functions.
9+
10+
import os
11+
import sys
12+
13+
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
14+
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
15+
16+
from perf_trace_context import *
17+
from subprocess import *
18+
from Core import *
19+
import re;
20+
21+
from optparse import OptionParser
22+
23+
#
24+
# Add options to specify vmlinux file and the objdump executable
25+
#
26+
parser = OptionParser()
27+
parser.add_option("-k", "--vmlinux", dest="vmlinux_name",
28+
help="path to vmlinux file")
29+
parser.add_option("-d", "--objdump", dest="objdump_name",
30+
help="name of objdump executable (in path)")
31+
(options, args) = parser.parse_args()
32+
33+
if (options.objdump_name == None):
34+
sys.exit("No objdump executable specified - use -d or --objdump option")
35+
36+
# initialize global dicts and regular expression
37+
38+
build_ids = dict();
39+
mmaps = dict();
40+
disasm_cache = dict();
41+
disasm_re = re.compile("^\s*([0-9a-fA-F]+):")
42+
43+
cache_size = 16*1024
44+
45+
def trace_begin():
46+
cmd_output = check_output(["perf", "buildid-list"]).split('\n');
47+
bid_re = re.compile("([a-fA-f0-9]+)[ \t]([^ \n]+)")
48+
for line in cmd_output:
49+
m = bid_re.search(line)
50+
if (m != None) :
51+
build_ids[m.group(2)] = \
52+
os.environ['PERF_BUILDID_DIR'] + \
53+
m.group(2) + "/" + m.group(1);
54+
55+
if ((options.vmlinux_name != None) and ("[kernel.kallsyms]" in build_ids)):
56+
build_ids['[kernel.kallsyms]'] = options.vmlinux_name;
57+
else:
58+
del build_ids['[kernel.kallsyms]']
59+
60+
mmap_re = re.compile("PERF_RECORD_MMAP2 -?[0-9]+/[0-9]+: \[(0x[0-9a-fA-F]+).*:\s.*\s(.*.so)")
61+
cmd_output= check_output("perf script --show-mmap-events | fgrep PERF_RECORD_MMAP2",shell=True).split('\n')
62+
for line in cmd_output:
63+
m = mmap_re.search(line)
64+
if (m != None) :
65+
mmaps[m.group(2)] = int(m.group(1),0)
66+
67+
68+
69+
def trace_end():
70+
pass
71+
72+
def process_event(t):
73+
global cache_size
74+
global options
75+
76+
sample = t['sample']
77+
dso = t['dso']
78+
79+
# don't let the cache get too big, but don't bother with a fancy replacement policy
80+
# just clear it when it hits max size
81+
82+
if (len(disasm_cache) > cache_size):
83+
disasm_cache.clear();
84+
85+
addr_range = format(sample['ip'],"x") + ":" + format(sample['addr'],"x");
86+
87+
try:
88+
disasm_output = disasm_cache[addr_range];
89+
except:
90+
try:
91+
fname = build_ids[dso];
92+
except KeyError:
93+
if (dso == '[kernel.kallsyms]'):
94+
return;
95+
fname = dso;
96+
97+
if (dso in mmaps):
98+
offset = mmaps[dso];
99+
disasm = [options.objdump_name,"-d","-z", "--adjust-vma="+format(offset,"#x"),"--start-address="+format(sample['ip'],"#x"),"--stop-address="+format(sample['addr'],"#x"), fname]
100+
else:
101+
offset = 0
102+
disasm = [options.objdump_name,"-d","-z", "--start-address="+format(sample['ip'],"#x"),"--stop-address="+format(sample['addr'],"#x"),fname]
103+
disasm_output = check_output(disasm).split('\n')
104+
disasm_cache[addr_range] = disasm_output;
105+
106+
for line in disasm_output:
107+
m = disasm_re.search(line)
108+
if (m != None) :
109+
try:
110+
print "\t",line
111+
except:
112+
exit(1);
113+
else:
114+
continue;
115+
116+
def trace_unhandled(event_name, context, event_fields_dict):
117+
print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
118+
119+
def print_header(event_name, cpu, secs, nsecs, pid, comm):
120+
print "print_header"
121+
print "%-20s %5u %05u.%09u %8u %-20s " % \
122+
(event_name, cpu, secs, nsecs, pid, comm),
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#
2+
# Copyright(C) 2016 Linaro Limited. All rights reserved.
3+
# Author: Tor Jeremiassen <tor.jeremiassen@linaro.org>
4+
#
5+
# This program is free software; you can redistribute it and/or modify it
6+
# under the terms of the GNU General Public License version 2 as published by
7+
# the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful, but WITHOUT
10+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12+
# more details.
13+
#
14+
# You should have received a copy of the GNU General Public License along with
15+
# this program. If not, see <http://www.gnu.org/licenses/>.
16+
#
17+
18+
import os
19+
import sys
20+
21+
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
22+
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
23+
24+
from perf_trace_context import *
25+
26+
def trace_begin():
27+
pass;
28+
29+
def trace_end():
30+
pass
31+
32+
def process_event(t):
33+
34+
sample = t['sample']
35+
36+
print "range:",format(sample['ip'],"x"),"-",format(sample['addr'],"x")
37+
38+
def trace_unhandled(event_name, context, event_fields_dict):
39+
print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
40+
41+
def print_header(event_name, cpu, secs, nsecs, pid, comm):
42+
print "print_header"
43+
print "%-20s %5u %05u.%09u %8u %-20s " % \
44+
(event_name, cpu, secs, nsecs, pid, comm),

0 commit comments

Comments
 (0)