aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r--tools/perf/builtin-trace.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index feabd08ec90d..a44ac9336219 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1219,6 +1219,7 @@ struct trace {
1219 struct syscall *table; 1219 struct syscall *table;
1220 } syscalls; 1220 } syscalls;
1221 struct record_opts opts; 1221 struct record_opts opts;
1222 struct perf_evlist *evlist;
1222 struct machine *host; 1223 struct machine *host;
1223 struct thread *current; 1224 struct thread *current;
1224 u64 base_time; 1225 u64 base_time;
@@ -1833,6 +1834,24 @@ out_dump:
1833 return 0; 1834 return 0;
1834} 1835}
1835 1836
1837static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
1838 union perf_event *event __maybe_unused,
1839 struct perf_sample *sample)
1840{
1841 trace__printf_interrupted_entry(trace, sample);
1842 trace__fprintf_tstamp(trace, sample->time, trace->output);
1843 fprintf(trace->output, "(%9.9s): %s:", " ", evsel->name);
1844
1845 if (evsel->tp_format) {
1846 event_format__fprintf(evsel->tp_format, sample->cpu,
1847 sample->raw_data, sample->raw_size,
1848 trace->output);
1849 }
1850
1851 fprintf(trace->output, ")\n");
1852 return 0;
1853}
1854
1836static void print_location(FILE *f, struct perf_sample *sample, 1855static void print_location(FILE *f, struct perf_sample *sample,
1837 struct addr_location *al, 1856 struct addr_location *al,
1838 bool print_dso, bool print_sym) 1857 bool print_dso, bool print_sym)
@@ -2067,7 +2086,7 @@ static int perf_evlist__add_pgfault(struct perf_evlist *evlist,
2067 2086
2068static int trace__run(struct trace *trace, int argc, const char **argv) 2087static int trace__run(struct trace *trace, int argc, const char **argv)
2069{ 2088{
2070 struct perf_evlist *evlist = perf_evlist__new(); 2089 struct perf_evlist *evlist = trace->evlist;
2071 struct perf_evsel *evsel; 2090 struct perf_evsel *evsel;
2072 int err = -1, i; 2091 int err = -1, i;
2073 unsigned long before; 2092 unsigned long before;
@@ -2076,11 +2095,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
2076 2095
2077 trace->live = true; 2096 trace->live = true;
2078 2097
2079 if (evlist == NULL) {
2080 fprintf(trace->output, "Not enough memory to run!\n");
2081 goto out;
2082 }
2083
2084 if (trace->trace_syscalls && 2098 if (trace->trace_syscalls &&
2085 perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, 2099 perf_evlist__add_syscall_newtp(evlist, trace__sys_enter,
2086 trace__sys_exit)) 2100 trace__sys_exit))
@@ -2227,7 +2241,7 @@ out_disable:
2227 2241
2228out_delete_evlist: 2242out_delete_evlist:
2229 perf_evlist__delete(evlist); 2243 perf_evlist__delete(evlist);
2230out: 2244 trace->evlist = NULL;
2231 trace->live = false; 2245 trace->live = false;
2232 return err; 2246 return err;
2233{ 2247{
@@ -2498,6 +2512,14 @@ static int parse_pagefaults(const struct option *opt, const char *str,
2498 return 0; 2512 return 0;
2499} 2513}
2500 2514
2515static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
2516{
2517 struct perf_evsel *evsel;
2518
2519 evlist__for_each(evlist, evsel)
2520 evsel->handler = handler;
2521}
2522
2501int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 2523int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2502{ 2524{
2503 const char * const trace_usage[] = { 2525 const char * const trace_usage[] = {
@@ -2532,6 +2554,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2532 const char *output_name = NULL; 2554 const char *output_name = NULL;
2533 const char *ev_qualifier_str = NULL; 2555 const char *ev_qualifier_str = NULL;
2534 const struct option trace_options[] = { 2556 const struct option trace_options[] = {
2557 OPT_CALLBACK(0, "event", &trace.evlist, "event",
2558 "event selector. use 'perf list' to list available events",
2559 parse_events_option),
2535 OPT_BOOLEAN(0, "comm", &trace.show_comm, 2560 OPT_BOOLEAN(0, "comm", &trace.show_comm,
2536 "show the thread COMM next to its id"), 2561 "show the thread COMM next to its id"),
2537 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"), 2562 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
@@ -2573,6 +2598,15 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2573 int err; 2598 int err;
2574 char bf[BUFSIZ]; 2599 char bf[BUFSIZ];
2575 2600
2601 trace.evlist = perf_evlist__new();
2602 if (trace.evlist == NULL)
2603 return -ENOMEM;
2604
2605 if (trace.evlist == NULL) {
2606 pr_err("Not enough memory to run!\n");
2607 goto out;
2608 }
2609
2576 argc = parse_options(argc, argv, trace_options, trace_usage, 2610 argc = parse_options(argc, argv, trace_options, trace_usage,
2577 PARSE_OPT_STOP_AT_NON_OPTION); 2611 PARSE_OPT_STOP_AT_NON_OPTION);
2578 2612
@@ -2581,6 +2615,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2581 trace.opts.sample_time = true; 2615 trace.opts.sample_time = true;
2582 } 2616 }
2583 2617
2618 if (trace.evlist->nr_entries > 0)
2619 evlist__set_evsel_handler(trace.evlist, trace__event_handler);
2620
2584 if ((argc >= 1) && (strcmp(argv[0], "record") == 0)) 2621 if ((argc >= 1) && (strcmp(argv[0], "record") == 0))
2585 return trace__record(&trace, argc-1, &argv[1]); 2622 return trace__record(&trace, argc-1, &argv[1]);
2586 2623