| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 |
|
| 22 | from __future__ import print_function
|
| 23 |
|
| 24 | import os
|
| 25 | import sys
|
| 26 | from collections import defaultdict
|
| 27 | from optparse import OptionParser, make_option
|
| 28 |
|
| 29 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \
|
| 30 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
|
| 31 |
|
| 32 | from perf_trace_context import *
|
| 33 | from Core import *
|
| 34 | from EventClass import *
|
| 35 |
|
| 36 | |
| 37 |
|
| 38 | option_list = [
|
| 39 | |
| 40 | make_option("--include-tid", dest="include_tid",
|
| 41 | action="store_true", default=False,
|
| 42 | help="include thread id in stack"),
|
| 43 | make_option("--include-pid", dest="include_pid",
|
| 44 | action="store_true", default=False,
|
| 45 | help="include process id in stack"),
|
| 46 | make_option("--no-comm", dest="include_comm",
|
| 47 | action="store_false", default=True,
|
| 48 | help="do not separate stacks according to comm"),
|
| 49 | make_option("--tidy-java", dest="tidy_java",
|
| 50 | action="store_true", default=False,
|
| 51 | help="beautify Java signatures"),
|
| 52 | make_option("--kernel", dest="annotate_kernel",
|
| 53 | action="store_true", default=False,
|
| 54 | help="annotate kernel functions with _[k]")
|
| 55 | ]
|
| 56 |
|
| 57 | parser = OptionParser(option_list=option_list)
|
| 58 | (opts, args) = parser.parse_args()
|
| 59 |
|
| 60 | if len(args) != 0:
|
| 61 | parser.error("unexpected command line argument")
|
| 62 | if opts.include_tid and not opts.include_comm:
|
| 63 | parser.error("requesting tid but not comm is invalid")
|
| 64 | if opts.include_pid and not opts.include_comm:
|
| 65 | parser.error("requesting pid but not comm is invalid")
|
| 66 |
|
| 67 | |
| 68 |
|
| 69 | lines = defaultdict(lambda: 0)
|
| 70 |
|
| 71 | def process_event(param_dict):
|
| 72 | def tidy_function_name(sym, dso):
|
| 73 | if sym is None:
|
| 74 | sym = '[unknown]'
|
| 75 |
|
| 76 | sym = sym.replace(';', ':')
|
| 77 | if opts.tidy_java:
|
| 78 | |
| 79 | |
| 80 | |
| 81 | |
| 82 | |
| 83 | sym = sym.replace('<', '')
|
| 84 | sym = sym.replace('>', '')
|
| 85 | if sym[0] == 'L' and sym.find('/'):
|
| 86 | sym = sym[1:]
|
| 87 | try:
|
| 88 | sym = sym[:sym.index('(')]
|
| 89 | except ValueError:
|
| 90 | pass
|
| 91 |
|
| 92 | if opts.annotate_kernel and dso == '[kernel.kallsyms]':
|
| 93 | return sym + '_[k]'
|
| 94 | else:
|
| 95 | return sym
|
| 96 |
|
| 97 | stack = list()
|
| 98 | if 'callchain' in param_dict:
|
| 99 | for entry in param_dict['callchain']:
|
| 100 | entry.setdefault('sym', dict())
|
| 101 | entry['sym'].setdefault('name', None)
|
| 102 | entry.setdefault('dso', None)
|
| 103 | stack.append(tidy_function_name(entry['sym']['name'],
|
| 104 | entry['dso']))
|
| 105 | else:
|
| 106 | param_dict.setdefault('symbol', None)
|
| 107 | param_dict.setdefault('dso', None)
|
| 108 | stack.append(tidy_function_name(param_dict['symbol'],
|
| 109 | param_dict['dso']))
|
| 110 |
|
| 111 | if opts.include_comm:
|
| 112 | comm = param_dict["comm"].replace(' ', '_')
|
| 113 | sep = "-"
|
| 114 | if opts.include_pid:
|
| 115 | comm = comm + sep + str(param_dict['sample']['pid'])
|
| 116 | sep = "/"
|
| 117 | if opts.include_tid:
|
| 118 | comm = comm + sep + str(param_dict['sample']['tid'])
|
| 119 | stack.append(comm)
|
| 120 |
|
| 121 | stack_string = ';'.join(reversed(stack))
|
| 122 | lines[stack_string] = lines[stack_string] + 1
|
| 123 |
|
| 124 | def trace_end():
|
| 125 | list = sorted(lines)
|
| 126 | for stack in list:
|
| 127 | print("%s %d" % (stack, lines[stack]))
|