diff options
author | Namhyung Kim <namhyung@kernel.org> | 2013-11-26 03:51:12 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-11-27 12:58:38 -0500 |
commit | ad7ebb9a48f59bad2714b64725653a73d78b686e (patch) | |
tree | ba1456286d67e8562a03b1232030a2dcea8110b7 | |
parent | 80b8b496ec6edaff01f9ab74dbe8a517cd718de8 (diff) |
perf script: Print comm, fork and exit events also
If --show-task-events option is given, also print internal COMM, FORK
and EXIT events. It would be helpful for debugging.
$ perf script --show-task-events
...
swapper 0 [009] 3350640.335261: sched:sched_switch: prev_comm=swapper/9
sleep 9486 [009] 3350640.335509: PERF_RECORD_COMM: sleep:9486
sleep 9486 [009] 3350640.335806: sched:sched_stat_runtime: comm=sleep pid=9486
firefox 2635 [003] 3350641.275896: PERF_RECORD_FORK(2635:9487):(2635:2635)
firefox 2635 [003] 3350641.275896: sched:sched_process_fork: comm=firefox pid=2635
sleep 9486 [009] 3350641.336009: PERF_RECORD_EXIT(9486:9486):(9486:9486)
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Suggested-by: Frederic Weisbecker <fweisbec@gmail.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1385455873-25865-1-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/Documentation/perf-script.txt | 3 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 105 |
2 files changed, 108 insertions, 0 deletions
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index e9cbfcddfa3f..67af9b77ea78 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt | |||
@@ -203,6 +203,9 @@ OPTIONS | |||
203 | --show-kernel-path:: | 203 | --show-kernel-path:: |
204 | Try to resolve the path of [kernel.kallsyms] | 204 | Try to resolve the path of [kernel.kallsyms] |
205 | 205 | ||
206 | --show-task-events | ||
207 | Display task related events (e.g. FORK, COMM, EXIT). | ||
208 | |||
206 | SEE ALSO | 209 | SEE ALSO |
207 | -------- | 210 | -------- |
208 | linkperf:perf-record[1], linkperf:perf-script-perl[1], | 211 | linkperf:perf-record[1], linkperf:perf-script-perl[1], |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9f3ba4404a14..e2b9aff6506e 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -572,6 +572,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
572 | struct perf_script { | 572 | struct perf_script { |
573 | struct perf_tool tool; | 573 | struct perf_tool tool; |
574 | struct perf_session *session; | 574 | struct perf_session *session; |
575 | bool show_task_events; | ||
575 | }; | 576 | }; |
576 | 577 | ||
577 | static int process_attr(struct perf_tool *tool, union perf_event *event, | 578 | static int process_attr(struct perf_tool *tool, union perf_event *event, |
@@ -602,6 +603,101 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, | |||
602 | return perf_evsel__check_attr(evsel, scr->session); | 603 | return perf_evsel__check_attr(evsel, scr->session); |
603 | } | 604 | } |
604 | 605 | ||
606 | static int process_comm_event(struct perf_tool *tool, | ||
607 | union perf_event *event, | ||
608 | struct perf_sample *sample, | ||
609 | struct machine *machine) | ||
610 | { | ||
611 | struct thread *thread; | ||
612 | struct perf_script *script = container_of(tool, struct perf_script, tool); | ||
613 | struct perf_session *session = script->session; | ||
614 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | ||
615 | int ret = -1; | ||
616 | |||
617 | thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); | ||
618 | if (thread == NULL) { | ||
619 | pr_debug("problem processing COMM event, skipping it.\n"); | ||
620 | return -1; | ||
621 | } | ||
622 | |||
623 | if (perf_event__process_comm(tool, event, sample, machine) < 0) | ||
624 | goto out; | ||
625 | |||
626 | if (!evsel->attr.sample_id_all) { | ||
627 | sample->cpu = 0; | ||
628 | sample->time = 0; | ||
629 | sample->tid = event->comm.tid; | ||
630 | sample->pid = event->comm.pid; | ||
631 | } | ||
632 | print_sample_start(sample, thread, evsel); | ||
633 | perf_event__fprintf(event, stdout); | ||
634 | ret = 0; | ||
635 | |||
636 | out: | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | static int process_fork_event(struct perf_tool *tool, | ||
641 | union perf_event *event, | ||
642 | struct perf_sample *sample, | ||
643 | struct machine *machine) | ||
644 | { | ||
645 | struct thread *thread; | ||
646 | struct perf_script *script = container_of(tool, struct perf_script, tool); | ||
647 | struct perf_session *session = script->session; | ||
648 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | ||
649 | |||
650 | if (perf_event__process_fork(tool, event, sample, machine) < 0) | ||
651 | return -1; | ||
652 | |||
653 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); | ||
654 | if (thread == NULL) { | ||
655 | pr_debug("problem processing FORK event, skipping it.\n"); | ||
656 | return -1; | ||
657 | } | ||
658 | |||
659 | if (!evsel->attr.sample_id_all) { | ||
660 | sample->cpu = 0; | ||
661 | sample->time = event->fork.time; | ||
662 | sample->tid = event->fork.tid; | ||
663 | sample->pid = event->fork.pid; | ||
664 | } | ||
665 | print_sample_start(sample, thread, evsel); | ||
666 | perf_event__fprintf(event, stdout); | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | static int process_exit_event(struct perf_tool *tool, | ||
671 | union perf_event *event, | ||
672 | struct perf_sample *sample, | ||
673 | struct machine *machine) | ||
674 | { | ||
675 | struct thread *thread; | ||
676 | struct perf_script *script = container_of(tool, struct perf_script, tool); | ||
677 | struct perf_session *session = script->session; | ||
678 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | ||
679 | |||
680 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); | ||
681 | if (thread == NULL) { | ||
682 | pr_debug("problem processing EXIT event, skipping it.\n"); | ||
683 | return -1; | ||
684 | } | ||
685 | |||
686 | if (!evsel->attr.sample_id_all) { | ||
687 | sample->cpu = 0; | ||
688 | sample->time = 0; | ||
689 | sample->tid = event->comm.tid; | ||
690 | sample->pid = event->comm.pid; | ||
691 | } | ||
692 | print_sample_start(sample, thread, evsel); | ||
693 | perf_event__fprintf(event, stdout); | ||
694 | |||
695 | if (perf_event__process_exit(tool, event, sample, machine) < 0) | ||
696 | return -1; | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
605 | static void sig_handler(int sig __maybe_unused) | 701 | static void sig_handler(int sig __maybe_unused) |
606 | { | 702 | { |
607 | session_done = 1; | 703 | session_done = 1; |
@@ -613,6 +709,13 @@ static int __cmd_script(struct perf_script *script) | |||
613 | 709 | ||
614 | signal(SIGINT, sig_handler); | 710 | signal(SIGINT, sig_handler); |
615 | 711 | ||
712 | /* override event processing functions */ | ||
713 | if (script->show_task_events) { | ||
714 | script->tool.comm = process_comm_event; | ||
715 | script->tool.fork = process_fork_event; | ||
716 | script->tool.exit = process_exit_event; | ||
717 | } | ||
718 | |||
616 | ret = perf_session__process_events(script->session, &script->tool); | 719 | ret = perf_session__process_events(script->session, &script->tool); |
617 | 720 | ||
618 | if (debug_mode) | 721 | if (debug_mode) |
@@ -1375,6 +1478,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1375 | "display extended information from perf.data file"), | 1478 | "display extended information from perf.data file"), |
1376 | OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, | 1479 | OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, |
1377 | "Show the path of [kernel.kallsyms]"), | 1480 | "Show the path of [kernel.kallsyms]"), |
1481 | OPT_BOOLEAN('\0', "show-task-events", &script.show_task_events, | ||
1482 | "Show the fork/comm/exit events"), | ||
1378 | OPT_END() | 1483 | OPT_END() |
1379 | }; | 1484 | }; |
1380 | const char * const script_usage[] = { | 1485 | const char * const script_usage[] = { |