aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-trace.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2013-08-09 11:28:31 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-08-14 10:44:21 -0400
commit2ae3a312c0ccd8ff615372f00aab1700aac27474 (patch)
tree4f1a04fccc12b6ff58b2a10e6ca9f2fcaac4adbe /tools/perf/builtin-trace.c
parentc5885749e4ebe568cca969d43488a233e69e6454 (diff)
perf trace: Allow specifying which syscalls to trace
Similar to -e in strace, i.e. a comma separated list of syscall names to trace. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-5zku7q5wug3103k1dzn3yy63@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.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index da7ae01c8394..120fdfb3d920 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -5,6 +5,7 @@
5#include "util/machine.h" 5#include "util/machine.h"
6#include "util/thread.h" 6#include "util/thread.h"
7#include "util/parse-options.h" 7#include "util/parse-options.h"
8#include "util/strlist.h"
8#include "util/thread_map.h" 9#include "util/thread_map.h"
9 10
10#include <libaudit.h> 11#include <libaudit.h>
@@ -47,6 +48,7 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
47struct syscall { 48struct syscall {
48 struct event_format *tp_format; 49 struct event_format *tp_format;
49 const char *name; 50 const char *name;
51 bool filtered;
50 struct syscall_fmt *fmt; 52 struct syscall_fmt *fmt;
51}; 53};
52 54
@@ -110,6 +112,7 @@ struct trace {
110 struct perf_record_opts opts; 112 struct perf_record_opts opts;
111 struct machine host; 113 struct machine host;
112 u64 base_time; 114 u64 base_time;
115 struct strlist *ev_qualifier;
113 unsigned long nr_events; 116 unsigned long nr_events;
114 bool sched; 117 bool sched;
115 bool multiple_threads; 118 bool multiple_threads;
@@ -226,6 +229,16 @@ static int trace__read_syscall_info(struct trace *trace, int id)
226 229
227 sc = trace->syscalls.table + id; 230 sc = trace->syscalls.table + id;
228 sc->name = name; 231 sc->name = name;
232
233 if (trace->ev_qualifier && !strlist__find(trace->ev_qualifier, name)) {
234 sc->filtered = true;
235 /*
236 * No need to do read tracepoint information since this will be
237 * filtered out.
238 */
239 return 0;
240 }
241
229 sc->fmt = syscall_fmt__find(sc->name); 242 sc->fmt = syscall_fmt__find(sc->name);
230 243
231 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name); 244 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
@@ -302,11 +315,19 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
302 char *msg; 315 char *msg;
303 void *args; 316 void *args;
304 size_t printed = 0; 317 size_t printed = 0;
305 struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); 318 struct thread *thread;
306 struct syscall *sc = trace__syscall_info(trace, evsel, sample); 319 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
307 struct thread_trace *ttrace = thread__trace(thread); 320 struct thread_trace *ttrace;
321
322 if (sc == NULL)
323 return -1;
308 324
309 if (ttrace == NULL || sc == NULL) 325 if (sc->filtered)
326 return 0;
327
328 thread = machine__findnew_thread(&trace->host, sample->tid);
329 ttrace = thread__trace(thread);
330 if (ttrace == NULL)
310 return -1; 331 return -1;
311 332
312 args = perf_evsel__rawptr(evsel, sample, "args"); 333 args = perf_evsel__rawptr(evsel, sample, "args");
@@ -345,11 +366,19 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
345{ 366{
346 int ret; 367 int ret;
347 u64 duration = 0; 368 u64 duration = 0;
348 struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); 369 struct thread *thread;
349 struct thread_trace *ttrace = thread__trace(thread);
350 struct syscall *sc = trace__syscall_info(trace, evsel, sample); 370 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
371 struct thread_trace *ttrace;
372
373 if (sc == NULL)
374 return -1;
351 375
352 if (ttrace == NULL || sc == NULL) 376 if (sc->filtered)
377 return 0;
378
379 thread = machine__findnew_thread(&trace->host, sample->tid);
380 ttrace = thread__trace(thread);
381 if (ttrace == NULL)
353 return -1; 382 return -1;
354 383
355 ret = perf_evsel__intval(evsel, sample, "ret"); 384 ret = perf_evsel__intval(evsel, sample, "ret");
@@ -634,7 +663,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
634 .mmap_pages = 1024, 663 .mmap_pages = 1024,
635 }, 664 },
636 }; 665 };
666 const char *ev_qualifier_str = NULL;
637 const struct option trace_options[] = { 667 const struct option trace_options[] = {
668 OPT_STRING('e', "expr", &ev_qualifier_str, "expr",
669 "list of events to trace"),
638 OPT_STRING('p', "pid", &trace.opts.target.pid, "pid", 670 OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
639 "trace events on existing process id"), 671 "trace events on existing process id"),
640 OPT_STRING(0, "tid", &trace.opts.target.tid, "tid", 672 OPT_STRING(0, "tid", &trace.opts.target.tid, "tid",
@@ -660,6 +692,14 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
660 692
661 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 693 argc = parse_options(argc, argv, trace_options, trace_usage, 0);
662 694
695 if (ev_qualifier_str != NULL) {
696 trace.ev_qualifier = strlist__new(true, ev_qualifier_str);
697 if (trace.ev_qualifier == NULL) {
698 puts("Not enough memory to parse event qualifier");
699 return -ENOMEM;
700 }
701 }
702
663 err = perf_target__validate(&trace.opts.target); 703 err = perf_target__validate(&trace.opts.target);
664 if (err) { 704 if (err) {
665 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf)); 705 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf));