diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7228d141a789..2f3ff69fc4e7 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -22,6 +22,7 @@ #include "util/thread_map.h" #include "util/stat.h" #include "util/thread-stack.h" +#include "util/time-utils.h" #include <linux/bitmap.h> #include <linux/stringify.h> #include <linux/time64.h> @@ -66,6 +67,8 @@ enum perf_output_field { PERF_OUTPUT_WEIGHT = 1U << 18, PERF_OUTPUT_BPF_OUTPUT = 1U << 19, PERF_OUTPUT_CALLINDENT = 1U << 20, + PERF_OUTPUT_INSN = 1U << 21, + PERF_OUTPUT_INSNLEN = 1U << 22, }; struct output_option { @@ -93,6 +96,8 @@ struct output_option { {.str = "weight", .field = PERF_OUTPUT_WEIGHT}, {.str = "bpf-output", .field = PERF_OUTPUT_BPF_OUTPUT}, {.str = "callindent", .field = PERF_OUTPUT_CALLINDENT}, + {.str = "insn", .field = PERF_OUTPUT_INSN}, + {.str = "insnlen", .field = PERF_OUTPUT_INSNLEN}, }; /* default set to maintain compatibility with current format */ @@ -437,7 +442,6 @@ static void print_sample_start(struct perf_sample *sample, { struct perf_event_attr *attr = &evsel->attr; unsigned long secs; - unsigned long usecs; unsigned long long nsecs; if (PRINT_FIELD(COMM)) { @@ -467,11 +471,14 @@ static void print_sample_start(struct perf_sample *sample, nsecs = sample->time; secs = nsecs / NSEC_PER_SEC; nsecs -= secs * NSEC_PER_SEC; - usecs = nsecs / NSEC_PER_USEC; + if (nanosecs) printf("%5lu.%09llu: ", secs, nsecs); - else - printf("%5lu.%06lu: ", secs, usecs); + else { + char sample_time[32]; + timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time)); + printf("%12s: ", sample_time); + } } } @@ -624,6 +631,20 @@ static void print_sample_callindent(struct perf_sample *sample, printf("%*s", spacing - len, ""); } +static void print_insn(struct perf_sample *sample, + struct perf_event_attr *attr) +{ + if (PRINT_FIELD(INSNLEN)) + printf(" ilen: %d", sample->insn_len); + if (PRINT_FIELD(INSN)) { + int i; + + printf(" insn:"); + for (i = 0; i < sample->insn_len; i++) + printf(" %02x", (unsigned char)sample->insn[i]); + } +} + static void print_sample_bts(struct perf_sample *sample, struct perf_evsel *evsel, struct thread *thread, @@ -668,6 +689,8 @@ static void print_sample_bts(struct perf_sample *sample, if (print_srcline_last) map__fprintf_srcline(al->map, al->addr, "\n ", stdout); + print_insn(sample, attr); + printf("\n"); } @@ -811,6 +834,8 @@ struct perf_script { struct cpu_map *cpus; struct thread_map *threads; int name_width; + const char *time_str; + struct perf_time_interval ptime; }; static int perf_evlist__max_name_len(struct perf_evlist *evlist) @@ -911,7 +936,7 @@ static void process_event(struct perf_script *script, if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) print_sample_bpf_output(sample); - + print_insn(sample, attr); printf("\n"); } @@ -992,6 +1017,9 @@ static int process_sample_event(struct perf_tool *tool, struct perf_script *scr = container_of(tool, struct perf_script, tool); struct addr_location al; + if (perf_time__skip_sample(&scr->ptime, sample->time)) + return 0; + if (debug_mode) { if (sample->time < last_timestamp) { pr_err("Samples misordered, previous: %" PRIu64 @@ -2124,11 +2152,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) "Valid types: hw,sw,trace,raw. " "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "addr,symoff,period,iregs,brstack,brstacksym,flags," - "bpf-output,callindent", parse_output_fields), + "bpf-output,callindent,insn,insnlen", parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", "only consider these symbols"), + OPT_STRING(0, "stop-bt", &symbol_conf.bt_stop_list_str, "symbol[,symbol...]", + "Stop display of callgraph at these symbols"), OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", "only display events for these comms"), @@ -2162,7 +2192,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) "Enable symbol demangling"), OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, "Enable kernel symbol demangling"), - + OPT_STRING(0, "time", &script.time_str, "str", + "Time span of interest (start,stop)"), OPT_END() }; const char * const script_subcommands[] = { "record", "report", NULL }; @@ -2441,6 +2472,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) if (err < 0) goto out_delete; + /* needs to be parsed after looking up reference time */ + if (perf_time__parse_str(&script.ptime, script.time_str) != 0) { + pr_err("Invalid time string\n"); + return -EINVAL; + } + err = __cmd_script(&script); flush_scripting(); |