builtin-trace.c (311baaf93c4b9e6a339722006d1a7c33e4283c0c) builtin-trace.c (f11b2803bb88655d90b88c787710b53100913bff)
1/*
2 * builtin-trace.c
3 *
4 * Builtin 'trace' command:
5 *
6 * Display a continuously updated trace of any workload, CPU, specific PID,
7 * system wide, etc. Default format is loosely strace like, but any other
8 * event may be specified using --event.

--- 161 unchanged lines hidden (view full) ---

170 bool multiple_threads;
171 bool summary;
172 bool summary_only;
173 bool failure_only;
174 bool show_comm;
175 bool print_sample;
176 bool show_tool_stats;
177 bool trace_syscalls;
1/*
2 * builtin-trace.c
3 *
4 * Builtin 'trace' command:
5 *
6 * Display a continuously updated trace of any workload, CPU, specific PID,
7 * system wide, etc. Default format is loosely strace like, but any other
8 * event may be specified using --event.

--- 161 unchanged lines hidden (view full) ---

170 bool multiple_threads;
171 bool summary;
172 bool summary_only;
173 bool failure_only;
174 bool show_comm;
175 bool print_sample;
176 bool show_tool_stats;
177 bool trace_syscalls;
178 bool libtraceevent_print;
178 bool kernel_syscallchains;
179 s16 args_alignment;
180 bool show_tstamp;
181 bool show_duration;
182 bool show_zeros;
183 bool show_arg_names;
184 bool show_string_prefix;
185 bool force;

--- 2206 unchanged lines hidden (view full) ---

2392static void bpf_output__fprintf(struct trace *trace,
2393 struct perf_sample *sample)
2394{
2395 binary__fprintf(sample->raw_data, sample->raw_size, 8,
2396 bpf_output__printer, NULL, trace->output);
2397 ++trace->nr_events_printed;
2398}
2399
179 bool kernel_syscallchains;
180 s16 args_alignment;
181 bool show_tstamp;
182 bool show_duration;
183 bool show_zeros;
184 bool show_arg_names;
185 bool show_string_prefix;
186 bool force;

--- 2206 unchanged lines hidden (view full) ---

2393static void bpf_output__fprintf(struct trace *trace,
2394 struct perf_sample *sample)
2395{
2396 binary__fprintf(sample->raw_data, sample->raw_size, 8,
2397 bpf_output__printer, NULL, trace->output);
2398 ++trace->nr_events_printed;
2399}
2400
2401static size_t trace__fprintf_tp_fields(struct trace *trace, struct evsel *evsel, struct perf_sample *sample,
2402 struct thread *thread, void *augmented_args, int augmented_args_size)
2403{
2404 char bf[2048];
2405 size_t size = sizeof(bf);
2406 struct tep_format_field *field = evsel->tp_format->format.fields;
2407 struct syscall_arg_fmt *arg = evsel->priv;
2408 size_t printed = 0;
2409 unsigned long val;
2410 u8 bit = 1;
2411 struct syscall_arg syscall_arg = {
2412 .augmented = {
2413 .size = augmented_args_size,
2414 .args = augmented_args,
2415 },
2416 .idx = 0,
2417 .mask = 0,
2418 .trace = trace,
2419 .thread = thread,
2420 .show_string_prefix = trace->show_string_prefix,
2421 };
2422
2423 for (; field && arg; field = field->next, ++syscall_arg.idx, bit <<= 1, ++arg) {
2424 if (syscall_arg.mask & bit)
2425 continue;
2426
2427 syscall_arg.fmt = arg;
2428 if (field->flags & TEP_FIELD_IS_ARRAY)
2429 val = (uintptr_t)(sample->raw_data + field->offset);
2430 else
2431 val = format_field__intval(field, sample, evsel->needs_swap);
2432 /*
2433 * Some syscall args need some mask, most don't and
2434 * return val untouched.
2435 */
2436 val = syscall_arg_fmt__mask_val(arg, &syscall_arg, val);
2437
2438 /*
2439 * Suppress this argument if its value is zero and
2440 * and we don't have a string associated in an
2441 * strarray for it.
2442 */
2443 if (val == 0 &&
2444 !trace->show_zeros &&
2445 !((arg->show_zero ||
2446 arg->scnprintf == SCA_STRARRAY ||
2447 arg->scnprintf == SCA_STRARRAYS) &&
2448 arg->parm))
2449 continue;
2450
2451 printed += scnprintf(bf + printed, size - printed, "%s", printed ? ", " : "");
2452
2453 /*
2454 * XXX Perhaps we should have a show_tp_arg_names,
2455 * leaving show_arg_names just for syscalls?
2456 */
2457 if (1 || trace->show_arg_names)
2458 printed += scnprintf(bf + printed, size - printed, "%s: ", field->name);
2459
2460 printed += syscall_arg_fmt__scnprintf_val(arg, bf + printed, size - printed, &syscall_arg, val);
2461 }
2462
2463 return printed + fprintf(trace->output, "%s", bf);
2464}
2465
2400static int trace__event_handler(struct trace *trace, struct evsel *evsel,
2401 union perf_event *event __maybe_unused,
2402 struct perf_sample *sample)
2403{
2404 struct thread *thread;
2405 int callchain_ret = 0;
2406 /*
2407 * Check if we called perf_evsel__disable(evsel) due to, for instance,

--- 44 unchanged lines hidden (view full) ---

2452
2453 fprintf(trace->output, "%s(", evsel->name);
2454
2455 if (perf_evsel__is_bpf_output(evsel)) {
2456 bpf_output__fprintf(trace, sample);
2457 } else if (evsel->tp_format) {
2458 if (strncmp(evsel->tp_format->name, "sys_enter_", 10) ||
2459 trace__fprintf_sys_enter(trace, evsel, sample)) {
2466static int trace__event_handler(struct trace *trace, struct evsel *evsel,
2467 union perf_event *event __maybe_unused,
2468 struct perf_sample *sample)
2469{
2470 struct thread *thread;
2471 int callchain_ret = 0;
2472 /*
2473 * Check if we called perf_evsel__disable(evsel) due to, for instance,

--- 44 unchanged lines hidden (view full) ---

2518
2519 fprintf(trace->output, "%s(", evsel->name);
2520
2521 if (perf_evsel__is_bpf_output(evsel)) {
2522 bpf_output__fprintf(trace, sample);
2523 } else if (evsel->tp_format) {
2524 if (strncmp(evsel->tp_format->name, "sys_enter_", 10) ||
2525 trace__fprintf_sys_enter(trace, evsel, sample)) {
2460 event_format__fprintf(evsel->tp_format, sample->cpu,
2461 sample->raw_data, sample->raw_size,
2462 trace->output);
2526 if (trace->libtraceevent_print) {
2527 event_format__fprintf(evsel->tp_format, sample->cpu,
2528 sample->raw_data, sample->raw_size,
2529 trace->output);
2530 } else {
2531 trace__fprintf_tp_fields(trace, evsel, sample, thread, NULL, 0);
2532 }
2463 ++trace->nr_events_printed;
2464
2465 if (evsel->max_events != ULONG_MAX && ++evsel->nr_events_printed == evsel->max_events) {
2466 evsel__disable(evsel);
2467 evsel__close(evsel);
2468 }
2469 }
2470 }

--- 1674 unchanged lines hidden (view full) ---

4145 } else if (!strcmp(var, "trace.show_prefix")) {
4146 trace->show_string_prefix = perf_config_bool(var, value);
4147 } else if (!strcmp(var, "trace.no_inherit")) {
4148 trace->opts.no_inherit = perf_config_bool(var, value);
4149 } else if (!strcmp(var, "trace.args_alignment")) {
4150 int args_alignment = 0;
4151 if (perf_config_int(&args_alignment, var, value) == 0)
4152 trace->args_alignment = args_alignment;
2533 ++trace->nr_events_printed;
2534
2535 if (evsel->max_events != ULONG_MAX && ++evsel->nr_events_printed == evsel->max_events) {
2536 evsel__disable(evsel);
2537 evsel__close(evsel);
2538 }
2539 }
2540 }

--- 1674 unchanged lines hidden (view full) ---

4215 } else if (!strcmp(var, "trace.show_prefix")) {
4216 trace->show_string_prefix = perf_config_bool(var, value);
4217 } else if (!strcmp(var, "trace.no_inherit")) {
4218 trace->opts.no_inherit = perf_config_bool(var, value);
4219 } else if (!strcmp(var, "trace.args_alignment")) {
4220 int args_alignment = 0;
4221 if (perf_config_int(&args_alignment, var, value) == 0)
4222 trace->args_alignment = args_alignment;
4223 } else if (!strcmp(var, "trace.tracepoint_beautifiers")) {
4224 if (strcasecmp(value, "libtraceevent") == 0)
4225 trace->libtraceevent_print = true;
4226 else if (strcasecmp(value, "libbeauty") == 0)
4227 trace->libtraceevent_print = false;
4153 }
4154out:
4155 return err;
4156}
4157
4158int cmd_trace(int argc, const char **argv)
4159{
4160 const char *trace_usage[] = {

--- 73 unchanged lines hidden (view full) ---

4234 "Show all syscalls and summary with statistics"),
4235 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
4236 "Trace pagefaults", parse_pagefaults, "maj"),
4237 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
4238 OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
4239 OPT_CALLBACK(0, "call-graph", &trace.opts,
4240 "record_mode[,record_size]", record_callchain_help,
4241 &record_parse_callchain_opt),
4228 }
4229out:
4230 return err;
4231}
4232
4233int cmd_trace(int argc, const char **argv)
4234{
4235 const char *trace_usage[] = {

--- 73 unchanged lines hidden (view full) ---

4309 "Show all syscalls and summary with statistics"),
4310 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
4311 "Trace pagefaults", parse_pagefaults, "maj"),
4312 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
4313 OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
4314 OPT_CALLBACK(0, "call-graph", &trace.opts,
4315 "record_mode[,record_size]", record_callchain_help,
4316 &record_parse_callchain_opt),
4317 OPT_BOOLEAN(0, "libtraceevent_print", &trace.libtraceevent_print,
4318 "Use libtraceevent to print the tracepoint arguments."),
4242 OPT_BOOLEAN(0, "kernel-syscall-graph", &trace.kernel_syscallchains,
4243 "Show the kernel callchains on the syscall exit path"),
4244 OPT_ULONG(0, "max-events", &trace.max_events,
4245 "Set the maximum number of events to print, exit after that is reached. "),
4246 OPT_UINTEGER(0, "min-stack", &trace.min_stack,
4247 "Set the minimum stack depth when parsing the callchain, "
4248 "anything below the specified depth will be ignored."),
4249 OPT_UINTEGER(0, "max-stack", &trace.max_stack,

--- 333 unchanged lines hidden ---
4319 OPT_BOOLEAN(0, "kernel-syscall-graph", &trace.kernel_syscallchains,
4320 "Show the kernel callchains on the syscall exit path"),
4321 OPT_ULONG(0, "max-events", &trace.max_events,
4322 "Set the maximum number of events to print, exit after that is reached. "),
4323 OPT_UINTEGER(0, "min-stack", &trace.min_stack,
4324 "Set the minimum stack depth when parsing the callchain, "
4325 "anything below the specified depth will be ignored."),
4326 OPT_UINTEGER(0, "max-stack", &trace.max_stack,

--- 333 unchanged lines hidden ---