diff options
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r-- | tools/perf/builtin-trace.c | 51 |
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 | ||
1837 | static 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 | |||
1836 | static void print_location(FILE *f, struct perf_sample *sample, | 1855 | static 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 | ||
2068 | static int trace__run(struct trace *trace, int argc, const char **argv) | 2087 | static 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 | ||
2228 | out_delete_evlist: | 2242 | out_delete_evlist: |
2229 | perf_evlist__delete(evlist); | 2243 | perf_evlist__delete(evlist); |
2230 | out: | 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 | ||
2515 | static 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 | |||
2501 | int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | 2523 | int 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 | ||