builtin-trace.c (ae6ba10d5090fc7e9095eaef3dcf06ba016725a6) | builtin-trace.c (ff7a4f98d52cd3f13b1f4f6f22208498b0c113f7) |
---|---|
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. --- 5 unchanged lines hidden (view full) --- 14 * http://lwn.net/Articles/415728/ ("Announcing a new utility: 'trace'") 15 * 16 * Released under the GPL v2. (and only v2, not any later version) 17 */ 18 19#include <traceevent/event-parse.h> 20#include <api/fs/tracing_path.h> 21#include <bpf/bpf.h> | 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. --- 5 unchanged lines hidden (view full) --- 14 * http://lwn.net/Articles/415728/ ("Announcing a new utility: 'trace'") 15 * 16 * Released under the GPL v2. (and only v2, not any later version) 17 */ 18 19#include <traceevent/event-parse.h> 20#include <api/fs/tracing_path.h> 21#include <bpf/bpf.h> |
22#include "util/bpf_map.h" |
|
22#include "builtin.h" 23#include "util/cgroup.h" 24#include "util/color.h" 25#include "util/config.h" 26#include "util/debug.h" 27#include "util/env.h" 28#include "util/event.h" 29#include "util/evlist.h" 30#include <subcmd/exec-cmd.h> 31#include "util/machine.h" | 23#include "builtin.h" 24#include "util/cgroup.h" 25#include "util/color.h" 26#include "util/config.h" 27#include "util/debug.h" 28#include "util/env.h" 29#include "util/event.h" 30#include "util/evlist.h" 31#include <subcmd/exec-cmd.h> 32#include "util/machine.h" |
33#include "util/map.h" 34#include "util/symbol.h" |
|
32#include "util/path.h" 33#include "util/session.h" 34#include "util/thread.h" 35#include <subcmd/parse-options.h> 36#include "util/strlist.h" 37#include "util/intlist.h" 38#include "util/thread_map.h" 39#include "util/stat.h" --- 40 unchanged lines hidden (view full) --- 80 struct syscall *table; 81 struct bpf_map *map; 82 struct { 83 struct perf_evsel *sys_enter, 84 *sys_exit, 85 *augmented; 86 } events; 87 } syscalls; | 35#include "util/path.h" 36#include "util/session.h" 37#include "util/thread.h" 38#include <subcmd/parse-options.h> 39#include "util/strlist.h" 40#include "util/intlist.h" 41#include "util/thread_map.h" 42#include "util/stat.h" --- 40 unchanged lines hidden (view full) --- 83 struct syscall *table; 84 struct bpf_map *map; 85 struct { 86 struct perf_evsel *sys_enter, 87 *sys_exit, 88 *augmented; 89 } events; 90 } syscalls; |
91 struct { 92 struct bpf_map *map; 93 } dump; |
|
88 struct record_opts opts; 89 struct perf_evlist *evlist; 90 struct machine *host; 91 struct thread *current; 92 struct cgroup *cgroup; 93 u64 base_time; 94 FILE *output; 95 unsigned long nr_events; --- 938 unchanged lines hidden (view full) --- 1034 1035#define TRACE_PFMAJ (1 << 0) 1036#define TRACE_PFMIN (1 << 1) 1037 1038static const size_t trace__entry_str_size = 2048; 1039 1040static struct file *thread_trace__files_entry(struct thread_trace *ttrace, int fd) 1041{ | 94 struct record_opts opts; 95 struct perf_evlist *evlist; 96 struct machine *host; 97 struct thread *current; 98 struct cgroup *cgroup; 99 u64 base_time; 100 FILE *output; 101 unsigned long nr_events; --- 938 unchanged lines hidden (view full) --- 1040 1041#define TRACE_PFMAJ (1 << 0) 1042#define TRACE_PFMIN (1 << 1) 1043 1044static const size_t trace__entry_str_size = 2048; 1045 1046static struct file *thread_trace__files_entry(struct thread_trace *ttrace, int fd) 1047{ |
1048 if (fd < 0) 1049 return NULL; 1050 |
|
1042 if (fd > ttrace->files.max) { 1043 struct file *nfiles = realloc(ttrace->files.table, (fd + 1) * sizeof(struct file)); 1044 1045 if (nfiles == NULL) 1046 return NULL; 1047 1048 if (ttrace->files.max != -1) { 1049 memset(nfiles + ttrace->files.max + 1, 0, --- 1711 unchanged lines hidden (view full) --- 2761 struct thread *thread = machine__find_thread(trace->host, pids[0], pids[0]); 2762 2763 while (thread && nr < ARRAY_SIZE(pids)) { 2764 struct thread *parent = machine__find_thread(trace->host, thread->ppid, thread->ppid); 2765 2766 if (parent == NULL) 2767 break; 2768 | 1051 if (fd > ttrace->files.max) { 1052 struct file *nfiles = realloc(ttrace->files.table, (fd + 1) * sizeof(struct file)); 1053 1054 if (nfiles == NULL) 1055 return NULL; 1056 1057 if (ttrace->files.max != -1) { 1058 memset(nfiles + ttrace->files.max + 1, 0, --- 1711 unchanged lines hidden (view full) --- 2770 struct thread *thread = machine__find_thread(trace->host, pids[0], pids[0]); 2771 2772 while (thread && nr < ARRAY_SIZE(pids)) { 2773 struct thread *parent = machine__find_thread(trace->host, thread->ppid, thread->ppid); 2774 2775 if (parent == NULL) 2776 break; 2777 |
2769 if (!strcmp(thread__comm_str(parent), "sshd")) { | 2778 if (!strcmp(thread__comm_str(parent), "sshd") || 2779 strstarts(thread__comm_str(parent), "gnome-terminal")) { |
2770 pids[nr++] = parent->tid; 2771 break; 2772 } 2773 thread = parent; 2774 } 2775 2776 err = perf_evlist__set_tp_filter_pids(trace->evlist, nr, pids); 2777 if (!err && trace->filter_pids.map) --- 208 unchanged lines hidden (view full) --- 2986 trace->syscalls.events.sys_exit->filter); 2987 } 2988 } 2989 2990 err = perf_evlist__apply_filters(evlist, &evsel); 2991 if (err < 0) 2992 goto out_error_apply_filters; 2993 | 2780 pids[nr++] = parent->tid; 2781 break; 2782 } 2783 thread = parent; 2784 } 2785 2786 err = perf_evlist__set_tp_filter_pids(trace->evlist, nr, pids); 2787 if (!err && trace->filter_pids.map) --- 208 unchanged lines hidden (view full) --- 2996 trace->syscalls.events.sys_exit->filter); 2997 } 2998 } 2999 3000 err = perf_evlist__apply_filters(evlist, &evsel); 3001 if (err < 0) 3002 goto out_error_apply_filters; 3003 |
3004 if (trace->dump.map) 3005 bpf_map__fprintf(trace->dump.map, trace->output); 3006 |
|
2994 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); 2995 if (err < 0) 2996 goto out_error_mmap; 2997 2998 if (!target__none(&trace->opts.target) && !trace->opts.initial_delay) 2999 perf_evlist__enable(evlist); 3000 3001 if (forks) --- 673 unchanged lines hidden (view full) --- 3675 .show_duration = true, 3676 .show_arg_names = true, 3677 .args_alignment = 70, 3678 .trace_syscalls = false, 3679 .kernel_syscallchains = false, 3680 .max_stack = UINT_MAX, 3681 .max_events = ULONG_MAX, 3682 }; | 3007 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages); 3008 if (err < 0) 3009 goto out_error_mmap; 3010 3011 if (!target__none(&trace->opts.target) && !trace->opts.initial_delay) 3012 perf_evlist__enable(evlist); 3013 3014 if (forks) --- 673 unchanged lines hidden (view full) --- 3688 .show_duration = true, 3689 .show_arg_names = true, 3690 .args_alignment = 70, 3691 .trace_syscalls = false, 3692 .kernel_syscallchains = false, 3693 .max_stack = UINT_MAX, 3694 .max_events = ULONG_MAX, 3695 }; |
3696 const char *map_dump_str = NULL; |
|
3683 const char *output_name = NULL; 3684 const struct option trace_options[] = { 3685 OPT_CALLBACK('e', "event", &trace, "event", 3686 "event/syscall selector. use 'perf list' to list available events", 3687 trace__parse_events_option), 3688 OPT_BOOLEAN(0, "comm", &trace.show_comm, 3689 "show the thread COMM next to its id"), 3690 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"), --- 16 unchanged lines hidden (view full) --- 3707 OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages", 3708 "number of mmap data pages", 3709 perf_evlist__parse_mmap_pages), 3710 OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user", 3711 "user to profile"), 3712 OPT_CALLBACK(0, "duration", &trace, "float", 3713 "show only events with duration > N.M ms", 3714 trace__set_duration), | 3697 const char *output_name = NULL; 3698 const struct option trace_options[] = { 3699 OPT_CALLBACK('e', "event", &trace, "event", 3700 "event/syscall selector. use 'perf list' to list available events", 3701 trace__parse_events_option), 3702 OPT_BOOLEAN(0, "comm", &trace.show_comm, 3703 "show the thread COMM next to its id"), 3704 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"), --- 16 unchanged lines hidden (view full) --- 3721 OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages", 3722 "number of mmap data pages", 3723 perf_evlist__parse_mmap_pages), 3724 OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user", 3725 "user to profile"), 3726 OPT_CALLBACK(0, "duration", &trace, "float", 3727 "show only events with duration > N.M ms", 3728 trace__set_duration), |
3729#ifdef HAVE_LIBBPF_SUPPORT 3730 OPT_STRING(0, "map-dump", &map_dump_str, "BPF map", "BPF map to periodically dump"), 3731#endif |
|
3715 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), 3716 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 3717 OPT_BOOLEAN('T', "time", &trace.full_time, 3718 "Show full timestamp, not time relative to first start"), 3719 OPT_BOOLEAN(0, "failure", &trace.failure_only, 3720 "Show only syscalls that failed"), 3721 OPT_BOOLEAN('s', "summary", &trace.summary_only, 3722 "Show only syscall summary with statistics"), --- 78 unchanged lines hidden (view full) --- 3801 if (err) { 3802 bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf)); 3803 pr_err("ERROR: Setup BPF stdout failed: %s\n", bf); 3804 goto out; 3805 } 3806 3807 err = -1; 3808 | 3732 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), 3733 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 3734 OPT_BOOLEAN('T', "time", &trace.full_time, 3735 "Show full timestamp, not time relative to first start"), 3736 OPT_BOOLEAN(0, "failure", &trace.failure_only, 3737 "Show only syscalls that failed"), 3738 OPT_BOOLEAN('s', "summary", &trace.summary_only, 3739 "Show only syscall summary with statistics"), --- 78 unchanged lines hidden (view full) --- 3818 if (err) { 3819 bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf)); 3820 pr_err("ERROR: Setup BPF stdout failed: %s\n", bf); 3821 goto out; 3822 } 3823 3824 err = -1; 3825 |
3826 if (map_dump_str) { 3827 trace.dump.map = bpf__find_map_by_name(map_dump_str); 3828 if (trace.dump.map == NULL) { 3829 pr_err("ERROR: BPF map \"%s\" not found\n", map_dump_str); 3830 goto out; 3831 } 3832 } 3833 |
|
3809 if (trace.trace_pgfaults) { 3810 trace.opts.sample_address = true; 3811 trace.opts.sample_time = true; 3812 } 3813 3814 if (trace.opts.mmap_pages == UINT_MAX) 3815 mmap_pages_user_set = false; 3816 --- 43 unchanged lines hidden (view full) --- 3860 evlist__for_each_entry(trace.evlist, evsel) { 3861 bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0; 3862 3863 if (raw_syscalls_sys_exit) { 3864 trace.raw_augmented_syscalls = true; 3865 goto init_augmented_syscall_tp; 3866 } 3867 | 3834 if (trace.trace_pgfaults) { 3835 trace.opts.sample_address = true; 3836 trace.opts.sample_time = true; 3837 } 3838 3839 if (trace.opts.mmap_pages == UINT_MAX) 3840 mmap_pages_user_set = false; 3841 --- 43 unchanged lines hidden (view full) --- 3885 evlist__for_each_entry(trace.evlist, evsel) { 3886 bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0; 3887 3888 if (raw_syscalls_sys_exit) { 3889 trace.raw_augmented_syscalls = true; 3890 goto init_augmented_syscall_tp; 3891 } 3892 |
3868 if (strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_enter") == 0) { | 3893 if (trace.syscalls.events.augmented->priv == NULL && 3894 strstr(perf_evsel__name(evsel), "syscalls:sys_enter")) { |
3869 struct perf_evsel *augmented = trace.syscalls.events.augmented; 3870 if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || 3871 perf_evsel__init_augmented_syscall_tp_args(augmented)) 3872 goto out; 3873 augmented->handler = trace__sys_enter; 3874 } 3875 3876 if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) { --- 80 unchanged lines hidden --- | 3895 struct perf_evsel *augmented = trace.syscalls.events.augmented; 3896 if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || 3897 perf_evsel__init_augmented_syscall_tp_args(augmented)) 3898 goto out; 3899 augmented->handler = trace__sys_enter; 3900 } 3901 3902 if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) { --- 80 unchanged lines hidden --- |