tor-jeremiassen | 69f2841 | 2016-02-17 10:58:21 -0600 | [diff] [blame^] | 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), |