summaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-trace.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-04-12 15:11:07 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-04-13 15:11:50 +0200
commit202ff9684a912c96e0f2fac65e34280a97ad3611 (patch)
treeb7063810c0240aa6ac293aba150d0ed34db85707 /tools/perf/builtin-trace.c
parentperf/x86/amd/uncore: Do not register a task ctx for uncore PMUs (diff)
downloadlinux-202ff9684a912c96e0f2fac65e34280a97ad3611.tar.xz
linux-202ff9684a912c96e0f2fac65e34280a97ad3611.zip
perf trace: Support callchains for --event too
We already were able to ask for callchains for a specific event: # trace -e nanosleep --call dwarf --event sched:sched_switch/call-graph=fp/ usleep 1 This would enable tracing just the "nanosleep" syscall, with callchains at syscall exit and would ask the kernel for frame pointer callchains to be enabled for the "sched:sched_switch" tracepoint event, its just that we were not resolving the callchain and printing it in 'perf trace', do it: # trace -e nanosleep --call dwarf --event sched:sched_switch/call-graph=fp/ usleep 1 0.425 ( 0.013 ms): usleep/6718 nanosleep(rqtp: 0x7ffcc1d16e20) ... 0.425 ( ): sched:sched_switch:usleep:6718 [120] S ==> swapper/2:0 [120]) __schedule+0xfe200402 ([kernel.kallsyms]) schedule+0xfe200035 ([kernel.kallsyms]) do_nanosleep+0xfe20006f ([kernel.kallsyms]) hrtimer_nanosleep+0xfe2000dc ([kernel.kallsyms]) sys_nanosleep+0xfe20007a ([kernel.kallsyms]) do_syscall_64+0xfe200062 ([kernel.kallsyms]) return_from_SYSCALL_64+0xfe200000 ([kernel.kallsyms]) __nanosleep+0xffff008b8cbe2010 (/usr/lib64/libc-2.22.so) 0.486 ( 0.073 ms): usleep/6718 ... [continued]: nanosleep()) = 0 __nanosleep+0x10 (/usr/lib64/libc-2.22.so) usleep+0x34 (/usr/lib64/libc-2.22.so) main+0x1eb (/usr/bin/usleep) __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so) _start+0x29 (/usr/bin/usleep) # Pretty compact, huh? DWARF callchains for raw_syscalls:sys_exit + frame pointer callchains for a tracepoint, if your hardware supports LBR, go wild with /call-graph=lbr/, guess the next step is to lift this from 'perf script': -F, --fields <str> comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr,symoff,period,iregs,brstack,brstacksym,flags Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Milian Wolff <milian.wolff@kdab.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-2e7yiv5hqdm8jywlmfivvx2v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r--tools/perf/builtin-trace.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 2ec53edcf649..a6e05e1bb350 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2114,6 +2114,28 @@ out_put:
return err;
}
+static int trace__fprintf_callchain(struct trace *trace, struct perf_evsel *evsel,
+ struct perf_sample *sample)
+{
+ struct addr_location al;
+ /* TODO: user-configurable print_opts */
+ const unsigned int print_opts = PRINT_IP_OPT_SYM |
+ PRINT_IP_OPT_DSO |
+ PRINT_IP_OPT_UNKNOWN_AS_ADDR;
+
+ if (sample->callchain == NULL)
+ return 0;
+
+ if (machine__resolve(trace->host, &al, sample) < 0) {
+ pr_err("Problem processing %s callchain, skipping...\n",
+ perf_evsel__name(evsel));
+ return 0;
+ }
+
+ return perf_evsel__fprintf_callchain(evsel, sample, &al, 38, print_opts,
+ scripting_max_stack, trace->output);
+}
+
static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
union perf_event *event __maybe_unused,
struct perf_sample *sample)
@@ -2193,21 +2215,7 @@ signed_print:
fputc('\n', trace->output);
- if (sample->callchain) {
- struct addr_location al;
- /* TODO: user-configurable print_opts */
- const unsigned int print_opts = PRINT_IP_OPT_SYM |
- PRINT_IP_OPT_DSO |
- PRINT_IP_OPT_UNKNOWN_AS_ADDR;
-
- if (machine__resolve(trace->host, &al, sample) < 0) {
- pr_err("problem processing %d event, skipping it.\n",
- event->header.type);
- goto out_put;
- }
- perf_evsel__fprintf_callchain(evsel, sample, &al, 38, print_opts,
- scripting_max_stack, trace->output);
- }
+ trace__fprintf_callchain(trace, evsel, sample);
out:
ttrace->entry_pending = false;
err = 0;
@@ -2355,6 +2363,9 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
}
fprintf(trace->output, ")\n");
+
+ trace__fprintf_callchain(trace, evsel, sample);
+
return 0;
}