3 # This script processes the output of 'perf script' and prints raw data in the
4 # the following format:
6 # BINARY_NAME EVENT NUM_IPS
10 # INSTRUCTION_PTR_NUM_IPS
12 # The perf data may be recorded with -g or not.
18 # Positions of various fields within a line. Assumes lines look like this:
19 # BINARY EVENT IP FUNCTION
20 # hhvm cycles: d87415 HPHP::ObjectData::destruct()
27 def remove_raw_annotation(header
):
28 """For non-generic events, perf adds a 'raw' annotation before the
29 event id: remove it and return the modified header."""
30 fields
= header
.split(None)
31 if (fields
[EVENT_FIELD
] == 'raw'):
33 return ' '.join(fields
)
35 def extract_function(long_symbol
):
36 short_symbol
= long_symbol
.split('(', 1)[0]
37 if short_symbol
== "":
42 if state
== WITH_STACKTRACES
:
47 header
= remove_raw_annotation(header
)
49 fields
= header
.split(None)
50 binary_name
= fields
[BINARY_NAME_FIELD
]
51 event
= fields
[EVENT_FIELD
][:-1]
55 # perf record was called without "-g"
57 entry
= (int(fields
[IP_FIELD
], 16),
58 extract_function(fields
[FUNCTION_FIELD
]))
59 trace_entries
.append(entry
)
61 # Sometimes you get weird garbage from perf script (This
62 # fix is motivated by a record that had spaces in the
63 # binary name, sigh). Ignore and move on.
65 elif state
== WITH_STACKTRACES
:
66 # perf record was called with "-g"
69 for line
in record
[1:]:
70 line_fields
= line
.split(None)
71 entry
= (int(line_fields
[0], 16),
72 extract_function(line_fields
[1]))
73 trace_entries
.append(entry
)
75 print("%s %s %u" % (binary_name
, event
, len(trace_entries
)))
76 for entry
in trace_entries
:
77 print("0x%lx %s" % (entry
[0], entry
[1]))
88 line
= sys
.stdin
.readline()
94 if len(line
.split(None)) >= 4:
97 state
= WITH_STACKTRACES
101 for line
in sys
.stdin
:
107 # state == WITH_STACKTRACES
109 for line
in sys
.stdin
:
120 if __name__
== '__main__':
121 for record
in records():