diff options
Diffstat (limited to 'tools/perf/scripts/python')
-rwxr-xr-x | tools/perf/scripts/python/bin/stackcollapse-record | 8 | ||||
-rwxr-xr-x | tools/perf/scripts/python/bin/stackcollapse-report | 3 | ||||
-rw-r--r-- | tools/perf/scripts/python/export-to-postgresql.py | 52 | ||||
-rw-r--r-- | tools/perf/scripts/python/netdev-times.py | 11 | ||||
-rwxr-xr-x | tools/perf/scripts/python/stackcollapse.py | 125 |
5 files changed, 175 insertions, 24 deletions
diff --git a/tools/perf/scripts/python/bin/stackcollapse-record b/tools/perf/scripts/python/bin/stackcollapse-record new file mode 100755 index 000000000000..9d8f9f0f3a17 --- /dev/null +++ b/tools/perf/scripts/python/bin/stackcollapse-record | |||
@@ -0,0 +1,8 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # | ||
4 | # stackcollapse.py can cover all type of perf samples including | ||
5 | # the tracepoints, so no special record requirements, just record what | ||
6 | # you want to analyze. | ||
7 | # | ||
8 | perf record "$@" | ||
diff --git a/tools/perf/scripts/python/bin/stackcollapse-report b/tools/perf/scripts/python/bin/stackcollapse-report new file mode 100755 index 000000000000..356b9656393d --- /dev/null +++ b/tools/perf/scripts/python/bin/stackcollapse-report | |||
@@ -0,0 +1,3 @@ | |||
1 | #!/bin/sh | ||
2 | # description: produce callgraphs in short form for scripting use | ||
3 | perf script -s "$PERF_EXEC_PATH"/scripts/python/stackcollapse.py -- "$@" | ||
diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 1b02cdc0cab6..7656ff8aa066 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py | |||
@@ -34,10 +34,9 @@ import datetime | |||
34 | # | 34 | # |
35 | # ubuntu: | 35 | # ubuntu: |
36 | # | 36 | # |
37 | # $ sudo apt-get install postgresql | 37 | # $ sudo apt-get install postgresql python-pyside.qtsql libqt4-sql-psql |
38 | # $ sudo su - postgres | 38 | # $ sudo su - postgres |
39 | # $ createuser <your user id here> | 39 | # $ createuser -s <your user id here> |
40 | # Shall the new role be a superuser? (y/n) y | ||
41 | # | 40 | # |
42 | # An example of using this script with Intel PT: | 41 | # An example of using this script with Intel PT: |
43 | # | 42 | # |
@@ -224,11 +223,14 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | |||
224 | 223 | ||
225 | perf_db_export_mode = True | 224 | perf_db_export_mode = True |
226 | perf_db_export_calls = False | 225 | perf_db_export_calls = False |
226 | perf_db_export_callchains = False | ||
227 | |||
227 | 228 | ||
228 | def usage(): | 229 | def usage(): |
229 | print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>]" | 230 | print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]" |
230 | print >> sys.stderr, "where: columns 'all' or 'branches'" | 231 | print >> sys.stderr, "where: columns 'all' or 'branches'" |
231 | print >> sys.stderr, " calls 'calls' => create calls table" | 232 | print >> sys.stderr, " calls 'calls' => create calls and call_paths table" |
233 | print >> sys.stderr, " callchains 'callchains' => create call_paths table" | ||
232 | raise Exception("Too few arguments") | 234 | raise Exception("Too few arguments") |
233 | 235 | ||
234 | if (len(sys.argv) < 2): | 236 | if (len(sys.argv) < 2): |
@@ -246,9 +248,11 @@ if columns not in ("all", "branches"): | |||
246 | 248 | ||
247 | branches = (columns == "branches") | 249 | branches = (columns == "branches") |
248 | 250 | ||
249 | if (len(sys.argv) >= 4): | 251 | for i in range(3,len(sys.argv)): |
250 | if (sys.argv[3] == "calls"): | 252 | if (sys.argv[i] == "calls"): |
251 | perf_db_export_calls = True | 253 | perf_db_export_calls = True |
254 | elif (sys.argv[i] == "callchains"): | ||
255 | perf_db_export_callchains = True | ||
252 | else: | 256 | else: |
253 | usage() | 257 | usage() |
254 | 258 | ||
@@ -359,14 +363,16 @@ else: | |||
359 | 'transaction bigint,' | 363 | 'transaction bigint,' |
360 | 'data_src bigint,' | 364 | 'data_src bigint,' |
361 | 'branch_type integer,' | 365 | 'branch_type integer,' |
362 | 'in_tx boolean)') | 366 | 'in_tx boolean,' |
367 | 'call_path_id bigint)') | ||
363 | 368 | ||
364 | if perf_db_export_calls: | 369 | if perf_db_export_calls or perf_db_export_callchains: |
365 | do_query(query, 'CREATE TABLE call_paths (' | 370 | do_query(query, 'CREATE TABLE call_paths (' |
366 | 'id bigint NOT NULL,' | 371 | 'id bigint NOT NULL,' |
367 | 'parent_id bigint,' | 372 | 'parent_id bigint,' |
368 | 'symbol_id bigint,' | 373 | 'symbol_id bigint,' |
369 | 'ip bigint)') | 374 | 'ip bigint)') |
375 | if perf_db_export_calls: | ||
370 | do_query(query, 'CREATE TABLE calls (' | 376 | do_query(query, 'CREATE TABLE calls (' |
371 | 'id bigint NOT NULL,' | 377 | 'id bigint NOT NULL,' |
372 | 'thread_id bigint,' | 378 | 'thread_id bigint,' |
@@ -428,7 +434,7 @@ do_query(query, 'CREATE VIEW comm_threads_view AS ' | |||
428 | '(SELECT tid FROM threads WHERE id = thread_id) AS tid' | 434 | '(SELECT tid FROM threads WHERE id = thread_id) AS tid' |
429 | ' FROM comm_threads') | 435 | ' FROM comm_threads') |
430 | 436 | ||
431 | if perf_db_export_calls: | 437 | if perf_db_export_calls or perf_db_export_callchains: |
432 | do_query(query, 'CREATE VIEW call_paths_view AS ' | 438 | do_query(query, 'CREATE VIEW call_paths_view AS ' |
433 | 'SELECT ' | 439 | 'SELECT ' |
434 | 'c.id,' | 440 | 'c.id,' |
@@ -444,6 +450,7 @@ if perf_db_export_calls: | |||
444 | '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,' | 450 | '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,' |
445 | '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name' | 451 | '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name' |
446 | ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id') | 452 | ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id') |
453 | if perf_db_export_calls: | ||
447 | do_query(query, 'CREATE VIEW calls_view AS ' | 454 | do_query(query, 'CREATE VIEW calls_view AS ' |
448 | 'SELECT ' | 455 | 'SELECT ' |
449 | 'calls.id,' | 456 | 'calls.id,' |
@@ -541,8 +548,9 @@ dso_file = open_output_file("dso_table.bin") | |||
541 | symbol_file = open_output_file("symbol_table.bin") | 548 | symbol_file = open_output_file("symbol_table.bin") |
542 | branch_type_file = open_output_file("branch_type_table.bin") | 549 | branch_type_file = open_output_file("branch_type_table.bin") |
543 | sample_file = open_output_file("sample_table.bin") | 550 | sample_file = open_output_file("sample_table.bin") |
544 | if perf_db_export_calls: | 551 | if perf_db_export_calls or perf_db_export_callchains: |
545 | call_path_file = open_output_file("call_path_table.bin") | 552 | call_path_file = open_output_file("call_path_table.bin") |
553 | if perf_db_export_calls: | ||
546 | call_file = open_output_file("call_table.bin") | 554 | call_file = open_output_file("call_table.bin") |
547 | 555 | ||
548 | def trace_begin(): | 556 | def trace_begin(): |
@@ -554,8 +562,8 @@ def trace_begin(): | |||
554 | comm_table(0, "unknown") | 562 | comm_table(0, "unknown") |
555 | dso_table(0, 0, "unknown", "unknown", "") | 563 | dso_table(0, 0, "unknown", "unknown", "") |
556 | symbol_table(0, 0, 0, 0, 0, "unknown") | 564 | symbol_table(0, 0, 0, 0, 0, "unknown") |
557 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | 565 | sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
558 | if perf_db_export_calls: | 566 | if perf_db_export_calls or perf_db_export_callchains: |
559 | call_path_table(0, 0, 0, 0) | 567 | call_path_table(0, 0, 0, 0) |
560 | 568 | ||
561 | unhandled_count = 0 | 569 | unhandled_count = 0 |
@@ -571,8 +579,9 @@ def trace_end(): | |||
571 | copy_output_file(symbol_file, "symbols") | 579 | copy_output_file(symbol_file, "symbols") |
572 | copy_output_file(branch_type_file, "branch_types") | 580 | copy_output_file(branch_type_file, "branch_types") |
573 | copy_output_file(sample_file, "samples") | 581 | copy_output_file(sample_file, "samples") |
574 | if perf_db_export_calls: | 582 | if perf_db_export_calls or perf_db_export_callchains: |
575 | copy_output_file(call_path_file, "call_paths") | 583 | copy_output_file(call_path_file, "call_paths") |
584 | if perf_db_export_calls: | ||
576 | copy_output_file(call_file, "calls") | 585 | copy_output_file(call_file, "calls") |
577 | 586 | ||
578 | print datetime.datetime.today(), "Removing intermediate files..." | 587 | print datetime.datetime.today(), "Removing intermediate files..." |
@@ -585,8 +594,9 @@ def trace_end(): | |||
585 | remove_output_file(symbol_file) | 594 | remove_output_file(symbol_file) |
586 | remove_output_file(branch_type_file) | 595 | remove_output_file(branch_type_file) |
587 | remove_output_file(sample_file) | 596 | remove_output_file(sample_file) |
588 | if perf_db_export_calls: | 597 | if perf_db_export_calls or perf_db_export_callchains: |
589 | remove_output_file(call_path_file) | 598 | remove_output_file(call_path_file) |
599 | if perf_db_export_calls: | ||
590 | remove_output_file(call_file) | 600 | remove_output_file(call_file) |
591 | os.rmdir(output_dir_name) | 601 | os.rmdir(output_dir_name) |
592 | print datetime.datetime.today(), "Adding primary keys" | 602 | print datetime.datetime.today(), "Adding primary keys" |
@@ -599,8 +609,9 @@ def trace_end(): | |||
599 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') | 609 | do_query(query, 'ALTER TABLE symbols ADD PRIMARY KEY (id)') |
600 | do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)') | 610 | do_query(query, 'ALTER TABLE branch_types ADD PRIMARY KEY (id)') |
601 | do_query(query, 'ALTER TABLE samples ADD PRIMARY KEY (id)') | 611 | do_query(query, 'ALTER TABLE samples ADD PRIMARY KEY (id)') |
602 | if perf_db_export_calls: | 612 | if perf_db_export_calls or perf_db_export_callchains: |
603 | do_query(query, 'ALTER TABLE call_paths ADD PRIMARY KEY (id)') | 613 | do_query(query, 'ALTER TABLE call_paths ADD PRIMARY KEY (id)') |
614 | if perf_db_export_calls: | ||
604 | do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') | 615 | do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') |
605 | 616 | ||
606 | print datetime.datetime.today(), "Adding foreign keys" | 617 | print datetime.datetime.today(), "Adding foreign keys" |
@@ -623,10 +634,11 @@ def trace_end(): | |||
623 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' | 634 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id),' |
624 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' | 635 | 'ADD CONSTRAINT todsofk FOREIGN KEY (to_dso_id) REFERENCES dsos (id),' |
625 | 'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols (id)') | 636 | 'ADD CONSTRAINT tosymbolfk FOREIGN KEY (to_symbol_id) REFERENCES symbols (id)') |
626 | if perf_db_export_calls: | 637 | if perf_db_export_calls or perf_db_export_callchains: |
627 | do_query(query, 'ALTER TABLE call_paths ' | 638 | do_query(query, 'ALTER TABLE call_paths ' |
628 | 'ADD CONSTRAINT parentfk FOREIGN KEY (parent_id) REFERENCES call_paths (id),' | 639 | 'ADD CONSTRAINT parentfk FOREIGN KEY (parent_id) REFERENCES call_paths (id),' |
629 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id)') | 640 | 'ADD CONSTRAINT symbolfk FOREIGN KEY (symbol_id) REFERENCES symbols (id)') |
641 | if perf_db_export_calls: | ||
630 | do_query(query, 'ALTER TABLE calls ' | 642 | do_query(query, 'ALTER TABLE calls ' |
631 | 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id),' | 643 | 'ADD CONSTRAINT threadfk FOREIGN KEY (thread_id) REFERENCES threads (id),' |
632 | 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' | 644 | 'ADD CONSTRAINT commfk FOREIGN KEY (comm_id) REFERENCES comms (id),' |
@@ -694,11 +706,11 @@ def branch_type_table(branch_type, name, *x): | |||
694 | value = struct.pack(fmt, 2, 4, branch_type, n, name) | 706 | value = struct.pack(fmt, 2, 4, branch_type, n, name) |
695 | branch_type_file.write(value) | 707 | branch_type_file.write(value) |
696 | 708 | ||
697 | def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, branch_type, in_tx, *x): | 709 | def sample_table(sample_id, evsel_id, machine_id, thread_id, comm_id, dso_id, symbol_id, sym_offset, ip, time, cpu, to_dso_id, to_symbol_id, to_sym_offset, to_ip, period, weight, transaction, data_src, branch_type, in_tx, call_path_id, *x): |
698 | if branches: | 710 | if branches: |
699 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiiiB", 17, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 4, branch_type, 1, in_tx) | 711 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiiiBiq", 18, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 4, branch_type, 1, in_tx, 8, call_path_id) |
700 | else: | 712 | else: |
701 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiB", 21, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx) | 713 | value = struct.pack("!hiqiqiqiqiqiqiqiqiqiqiiiqiqiqiqiqiqiqiqiiiBiq", 22, 8, sample_id, 8, evsel_id, 8, machine_id, 8, thread_id, 8, comm_id, 8, dso_id, 8, symbol_id, 8, sym_offset, 8, ip, 8, time, 4, cpu, 8, to_dso_id, 8, to_symbol_id, 8, to_sym_offset, 8, to_ip, 8, period, 8, weight, 8, transaction, 8, data_src, 4, branch_type, 1, in_tx, 8, call_path_id) |
702 | sample_file.write(value) | 714 | sample_file.write(value) |
703 | 715 | ||
704 | def call_path_table(cp_id, parent_id, symbol_id, ip, *x): | 716 | def call_path_table(cp_id, parent_id, symbol_id, ip, *x): |
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py index 4d21ef2d601d..4c6f09ac7d12 100644 --- a/tools/perf/scripts/python/netdev-times.py +++ b/tools/perf/scripts/python/netdev-times.py | |||
@@ -252,9 +252,10 @@ def irq__irq_handler_exit(name, context, cpu, sec, nsec, pid, comm, callchain, i | |||
252 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) | 252 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, irq, ret) |
253 | all_event_list.append(event_info) | 253 | all_event_list.append(event_info) |
254 | 254 | ||
255 | def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, dev_name): | 255 | def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, |
256 | dev_name, work=None, budget=None): | ||
256 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, | 257 | event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, |
257 | napi, dev_name) | 258 | napi, dev_name, work, budget) |
258 | all_event_list.append(event_info) | 259 | all_event_list.append(event_info) |
259 | 260 | ||
260 | def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr, | 261 | def net__netif_receive_skb(name, context, cpu, sec, nsec, pid, comm, callchain, skbaddr, |
@@ -354,11 +355,13 @@ def handle_irq_softirq_exit(event_info): | |||
354 | receive_hunk_list.append(rec_data) | 355 | receive_hunk_list.append(rec_data) |
355 | 356 | ||
356 | def handle_napi_poll(event_info): | 357 | def handle_napi_poll(event_info): |
357 | (name, context, cpu, time, pid, comm, napi, dev_name) = event_info | 358 | (name, context, cpu, time, pid, comm, napi, dev_name, |
359 | work, budget) = event_info | ||
358 | if cpu in net_rx_dic.keys(): | 360 | if cpu in net_rx_dic.keys(): |
359 | event_list = net_rx_dic[cpu]['event_list'] | 361 | event_list = net_rx_dic[cpu]['event_list'] |
360 | rec_data = {'event_name':'napi_poll', | 362 | rec_data = {'event_name':'napi_poll', |
361 | 'dev':dev_name, 'event_t':time} | 363 | 'dev':dev_name, 'event_t':time, |
364 | 'work':work, 'budget':budget} | ||
362 | event_list.append(rec_data) | 365 | event_list.append(rec_data) |
363 | 366 | ||
364 | def handle_netif_rx(event_info): | 367 | def handle_netif_rx(event_info): |
diff --git a/tools/perf/scripts/python/stackcollapse.py b/tools/perf/scripts/python/stackcollapse.py new file mode 100755 index 000000000000..5a605f70ef32 --- /dev/null +++ b/tools/perf/scripts/python/stackcollapse.py | |||
@@ -0,0 +1,125 @@ | |||
1 | # stackcollapse.py - format perf samples with one line per distinct call stack | ||
2 | # | ||
3 | # This script's output has two space-separated fields. The first is a semicolon | ||
4 | # separated stack including the program name (from the "comm" field) and the | ||
5 | # function names from the call stack. The second is a count: | ||
6 | # | ||
7 | # swapper;start_kernel;rest_init;cpu_idle;default_idle;native_safe_halt 2 | ||
8 | # | ||
9 | # The file is sorted according to the first field. | ||
10 | # | ||
11 | # Input may be created and processed using: | ||
12 | # | ||
13 | # perf record -a -g -F 99 sleep 60 | ||
14 | # perf script report stackcollapse > out.stacks-folded | ||
15 | # | ||
16 | # (perf script record stackcollapse works too). | ||
17 | # | ||
18 | # Written by Paolo Bonzini <pbonzini@redhat.com> | ||
19 | # Based on Brendan Gregg's stackcollapse-perf.pl script. | ||
20 | |||
21 | import os | ||
22 | import sys | ||
23 | from collections import defaultdict | ||
24 | from optparse import OptionParser, make_option | ||
25 | |||
26 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | ||
27 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | ||
28 | |||
29 | from perf_trace_context import * | ||
30 | from Core import * | ||
31 | from EventClass import * | ||
32 | |||
33 | # command line parsing | ||
34 | |||
35 | option_list = [ | ||
36 | # formatting options for the bottom entry of the stack | ||
37 | make_option("--include-tid", dest="include_tid", | ||
38 | action="store_true", default=False, | ||
39 | help="include thread id in stack"), | ||
40 | make_option("--include-pid", dest="include_pid", | ||
41 | action="store_true", default=False, | ||
42 | help="include process id in stack"), | ||
43 | make_option("--no-comm", dest="include_comm", | ||
44 | action="store_false", default=True, | ||
45 | help="do not separate stacks according to comm"), | ||
46 | make_option("--tidy-java", dest="tidy_java", | ||
47 | action="store_true", default=False, | ||
48 | help="beautify Java signatures"), | ||
49 | make_option("--kernel", dest="annotate_kernel", | ||
50 | action="store_true", default=False, | ||
51 | help="annotate kernel functions with _[k]") | ||
52 | ] | ||
53 | |||
54 | parser = OptionParser(option_list=option_list) | ||
55 | (opts, args) = parser.parse_args() | ||
56 | |||
57 | if len(args) != 0: | ||
58 | parser.error("unexpected command line argument") | ||
59 | if opts.include_tid and not opts.include_comm: | ||
60 | parser.error("requesting tid but not comm is invalid") | ||
61 | if opts.include_pid and not opts.include_comm: | ||
62 | parser.error("requesting pid but not comm is invalid") | ||
63 | |||
64 | # event handlers | ||
65 | |||
66 | lines = defaultdict(lambda: 0) | ||
67 | |||
68 | def process_event(param_dict): | ||
69 | def tidy_function_name(sym, dso): | ||
70 | if sym is None: | ||
71 | sym = '[unknown]' | ||
72 | |||
73 | sym = sym.replace(';', ':') | ||
74 | if opts.tidy_java: | ||
75 | # the original stackcollapse-perf.pl script gives the | ||
76 | # example of converting this: | ||
77 | # Lorg/mozilla/javascript/MemberBox;.<init>(Ljava/lang/reflect/Method;)V | ||
78 | # to this: | ||
79 | # org/mozilla/javascript/MemberBox:.init | ||
80 | sym = sym.replace('<', '') | ||
81 | sym = sym.replace('>', '') | ||
82 | if sym[0] == 'L' and sym.find('/'): | ||
83 | sym = sym[1:] | ||
84 | try: | ||
85 | sym = sym[:sym.index('(')] | ||
86 | except ValueError: | ||
87 | pass | ||
88 | |||
89 | if opts.annotate_kernel and dso == '[kernel.kallsyms]': | ||
90 | return sym + '_[k]' | ||
91 | else: | ||
92 | return sym | ||
93 | |||
94 | stack = list() | ||
95 | if 'callchain' in param_dict: | ||
96 | for entry in param_dict['callchain']: | ||
97 | entry.setdefault('sym', dict()) | ||
98 | entry['sym'].setdefault('name', None) | ||
99 | entry.setdefault('dso', None) | ||
100 | stack.append(tidy_function_name(entry['sym']['name'], | ||
101 | entry['dso'])) | ||
102 | else: | ||
103 | param_dict.setdefault('symbol', None) | ||
104 | param_dict.setdefault('dso', None) | ||
105 | stack.append(tidy_function_name(param_dict['symbol'], | ||
106 | param_dict['dso'])) | ||
107 | |||
108 | if opts.include_comm: | ||
109 | comm = param_dict["comm"].replace(' ', '_') | ||
110 | sep = "-" | ||
111 | if opts.include_pid: | ||
112 | comm = comm + sep + str(param_dict['sample']['pid']) | ||
113 | sep = "/" | ||
114 | if opts.include_tid: | ||
115 | comm = comm + sep + str(param_dict['sample']['tid']) | ||
116 | stack.append(comm) | ||
117 | |||
118 | stack_string = ';'.join(reversed(stack)) | ||
119 | lines[stack_string] = lines[stack_string] + 1 | ||
120 | |||
121 | def trace_end(): | ||
122 | list = lines.keys() | ||
123 | list.sort() | ||
124 | for stack in list: | ||
125 | print "%s %d" % (stack, lines[stack]) | ||