0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 from __future__ import print_function
0023
0024 import os
0025 import sys
0026 from collections import defaultdict
0027 from optparse import OptionParser, make_option
0028
0029 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
0030 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
0031
0032 from perf_trace_context import *
0033 from Core import *
0034 from EventClass import *
0035
0036
0037
0038 option_list = [
0039
0040 make_option("--include-tid", dest="include_tid",
0041 action="store_true", default=False,
0042 help="include thread id in stack"),
0043 make_option("--include-pid", dest="include_pid",
0044 action="store_true", default=False,
0045 help="include process id in stack"),
0046 make_option("--no-comm", dest="include_comm",
0047 action="store_false", default=True,
0048 help="do not separate stacks according to comm"),
0049 make_option("--tidy-java", dest="tidy_java",
0050 action="store_true", default=False,
0051 help="beautify Java signatures"),
0052 make_option("--kernel", dest="annotate_kernel",
0053 action="store_true", default=False,
0054 help="annotate kernel functions with _[k]")
0055 ]
0056
0057 parser = OptionParser(option_list=option_list)
0058 (opts, args) = parser.parse_args()
0059
0060 if len(args) != 0:
0061 parser.error("unexpected command line argument")
0062 if opts.include_tid and not opts.include_comm:
0063 parser.error("requesting tid but not comm is invalid")
0064 if opts.include_pid and not opts.include_comm:
0065 parser.error("requesting pid but not comm is invalid")
0066
0067
0068
0069 lines = defaultdict(lambda: 0)
0070
0071 def process_event(param_dict):
0072 def tidy_function_name(sym, dso):
0073 if sym is None:
0074 sym = '[unknown]'
0075
0076 sym = sym.replace(';', ':')
0077 if opts.tidy_java:
0078
0079
0080
0081
0082
0083 sym = sym.replace('<', '')
0084 sym = sym.replace('>', '')
0085 if sym[0] == 'L' and sym.find('/'):
0086 sym = sym[1:]
0087 try:
0088 sym = sym[:sym.index('(')]
0089 except ValueError:
0090 pass
0091
0092 if opts.annotate_kernel and dso == '[kernel.kallsyms]':
0093 return sym + '_[k]'
0094 else:
0095 return sym
0096
0097 stack = list()
0098 if 'callchain' in param_dict:
0099 for entry in param_dict['callchain']:
0100 entry.setdefault('sym', dict())
0101 entry['sym'].setdefault('name', None)
0102 entry.setdefault('dso', None)
0103 stack.append(tidy_function_name(entry['sym']['name'],
0104 entry['dso']))
0105 else:
0106 param_dict.setdefault('symbol', None)
0107 param_dict.setdefault('dso', None)
0108 stack.append(tidy_function_name(param_dict['symbol'],
0109 param_dict['dso']))
0110
0111 if opts.include_comm:
0112 comm = param_dict["comm"].replace(' ', '_')
0113 sep = "-"
0114 if opts.include_pid:
0115 comm = comm + sep + str(param_dict['sample']['pid'])
0116 sep = "/"
0117 if opts.include_tid:
0118 comm = comm + sep + str(param_dict['sample']['tid'])
0119 stack.append(comm)
0120
0121 stack_string = ';'.join(reversed(stack))
0122 lines[stack_string] = lines[stack_string] + 1
0123
0124 def trace_end():
0125 list = sorted(lines)
0126 for stack in list:
0127 print("%s %d" % (stack, lines[stack]))