builtin-trace.c (0c82adcf141935b6312593a53f87342dbb12b704) | builtin-trace.c (598d02c5a07b60e5c824184cdaf697b70f3c452a) |
---|---|
1#include <traceevent/event-parse.h> 2#include "builtin.h" 3#include "util/color.h" 4#include "util/debug.h" 5#include "util/evlist.h" 6#include "util/machine.h" 7#include "util/session.h" 8#include "util/thread.h" --- 1164 unchanged lines hidden (view full) --- 1173 1174 return ttrace; 1175fail: 1176 color_fprintf(fp, PERF_COLOR_RED, 1177 "WARNING: not enough memory, dropping samples!\n"); 1178 return NULL; 1179} 1180 | 1#include <traceevent/event-parse.h> 2#include "builtin.h" 3#include "util/color.h" 4#include "util/debug.h" 5#include "util/evlist.h" 6#include "util/machine.h" 7#include "util/session.h" 8#include "util/thread.h" --- 1164 unchanged lines hidden (view full) --- 1173 1174 return ttrace; 1175fail: 1176 color_fprintf(fp, PERF_COLOR_RED, 1177 "WARNING: not enough memory, dropping samples!\n"); 1178 return NULL; 1179} 1180 |
1181#define TRACE_PFMAJ (1 << 0) 1182#define TRACE_PFMIN (1 << 1) 1183 |
|
1181struct trace { 1182 struct perf_tool tool; 1183 struct { 1184 int machine; 1185 int open_id; 1186 } audit; 1187 struct { 1188 int max; --- 18 unchanged lines hidden (view full) --- 1207 bool live; 1208 bool full_time; 1209 bool sched; 1210 bool multiple_threads; 1211 bool summary; 1212 bool summary_only; 1213 bool show_comm; 1214 bool show_tool_stats; | 1184struct trace { 1185 struct perf_tool tool; 1186 struct { 1187 int machine; 1188 int open_id; 1189 } audit; 1190 struct { 1191 int max; --- 18 unchanged lines hidden (view full) --- 1210 bool live; 1211 bool full_time; 1212 bool sched; 1213 bool multiple_threads; 1214 bool summary; 1215 bool summary_only; 1216 bool show_comm; 1217 bool show_tool_stats; |
1218 int trace_pgfaults; |
|
1215}; 1216 1217static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) 1218{ 1219 struct thread_trace *ttrace = thread->priv; 1220 1221 if (fd > ttrace->paths.max) { 1222 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); --- 545 unchanged lines hidden (view full) --- 1768 evsel->name, 1769 perf_evsel__strval(evsel, sample, "comm"), 1770 (pid_t)perf_evsel__intval(evsel, sample, "pid"), 1771 runtime, 1772 perf_evsel__intval(evsel, sample, "vruntime")); 1773 return 0; 1774} 1775 | 1219}; 1220 1221static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) 1222{ 1223 struct thread_trace *ttrace = thread->priv; 1224 1225 if (fd > ttrace->paths.max) { 1226 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); --- 545 unchanged lines hidden (view full) --- 1772 evsel->name, 1773 perf_evsel__strval(evsel, sample, "comm"), 1774 (pid_t)perf_evsel__intval(evsel, sample, "pid"), 1775 runtime, 1776 perf_evsel__intval(evsel, sample, "vruntime")); 1777 return 0; 1778} 1779 |
1780static void print_location(FILE *f, struct perf_sample *sample, 1781 struct addr_location *al, 1782 bool print_dso, bool print_sym) 1783{ 1784 1785 if ((verbose || print_dso) && al->map) 1786 fprintf(f, "%s@", al->map->dso->long_name); 1787 1788 if ((verbose || print_sym) && al->sym) 1789 fprintf(f, "%s+0x%lx", al->sym->name, 1790 al->addr - al->sym->start); 1791 else if (al->map) 1792 fprintf(f, "0x%lx", al->addr); 1793 else 1794 fprintf(f, "0x%lx", sample->addr); 1795} 1796 1797static int trace__pgfault(struct trace *trace, 1798 struct perf_evsel *evsel, 1799 union perf_event *event, 1800 struct perf_sample *sample) 1801{ 1802 struct thread *thread; 1803 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1804 struct addr_location al; 1805 char map_type = 'd'; 1806 1807 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); 1808 1809 thread__find_addr_location(thread, trace->host, cpumode, MAP__FUNCTION, 1810 sample->ip, &al); 1811 1812 trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output); 1813 1814 fprintf(trace->output, "%sfault [", 1815 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ? 1816 "maj" : "min"); 1817 1818 print_location(trace->output, sample, &al, false, true); 1819 1820 fprintf(trace->output, "] => "); 1821 1822 thread__find_addr_location(thread, trace->host, cpumode, MAP__VARIABLE, 1823 sample->addr, &al); 1824 1825 if (!al.map) { 1826 thread__find_addr_location(thread, trace->host, cpumode, 1827 MAP__FUNCTION, sample->addr, &al); 1828 1829 if (al.map) 1830 map_type = 'x'; 1831 else 1832 map_type = '?'; 1833 } 1834 1835 print_location(trace->output, sample, &al, true, false); 1836 1837 fprintf(trace->output, " (%c%c)\n", map_type, al.level); 1838 1839 return 0; 1840} 1841 |
|
1776static bool skip_sample(struct trace *trace, struct perf_sample *sample) 1777{ 1778 if ((trace->pid_list && intlist__find(trace->pid_list, sample->pid)) || 1779 (trace->tid_list && intlist__find(trace->tid_list, sample->tid))) 1780 return false; 1781 1782 if (trace->pid_list || trace->tid_list) 1783 return true; --- 98 unchanged lines hidden (view full) --- 1882 perf_evsel__delete(evsel); 1883 return; 1884 } 1885 1886 evsel->handler = trace__vfs_getname; 1887 perf_evlist__add(evlist, evsel); 1888} 1889 | 1842static bool skip_sample(struct trace *trace, struct perf_sample *sample) 1843{ 1844 if ((trace->pid_list && intlist__find(trace->pid_list, sample->pid)) || 1845 (trace->tid_list && intlist__find(trace->tid_list, sample->tid))) 1846 return false; 1847 1848 if (trace->pid_list || trace->tid_list) 1849 return true; --- 98 unchanged lines hidden (view full) --- 1948 perf_evsel__delete(evsel); 1949 return; 1950 } 1951 1952 evsel->handler = trace__vfs_getname; 1953 perf_evlist__add(evlist, evsel); 1954} 1955 |
1956static int perf_evlist__add_pgfault(struct perf_evlist *evlist, 1957 u64 config) 1958{ 1959 struct perf_evsel *evsel; 1960 struct perf_event_attr attr = { 1961 .type = PERF_TYPE_SOFTWARE, 1962 .mmap_data = 1, 1963 .sample_period = 1, 1964 }; 1965 1966 attr.config = config; 1967 1968 event_attr_init(&attr); 1969 1970 evsel = perf_evsel__new(&attr); 1971 if (!evsel) 1972 return -ENOMEM; 1973 1974 evsel->handler = trace__pgfault; 1975 perf_evlist__add(evlist, evsel); 1976 1977 return 0; 1978} 1979 |
|
1890static int trace__run(struct trace *trace, int argc, const char **argv) 1891{ 1892 struct perf_evlist *evlist = perf_evlist__new(); 1893 struct perf_evsel *evsel; 1894 int err = -1, i; 1895 unsigned long before; 1896 const bool forks = argc > 0; 1897 --- 4 unchanged lines hidden (view full) --- 1902 goto out; 1903 } 1904 1905 if (perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, trace__sys_exit)) 1906 goto out_error_tp; 1907 1908 perf_evlist__add_vfs_getname(evlist); 1909 | 1980static int trace__run(struct trace *trace, int argc, const char **argv) 1981{ 1982 struct perf_evlist *evlist = perf_evlist__new(); 1983 struct perf_evsel *evsel; 1984 int err = -1, i; 1985 unsigned long before; 1986 const bool forks = argc > 0; 1987 --- 4 unchanged lines hidden (view full) --- 1992 goto out; 1993 } 1994 1995 if (perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, trace__sys_exit)) 1996 goto out_error_tp; 1997 1998 perf_evlist__add_vfs_getname(evlist); 1999 |
2000 if ((trace->trace_pgfaults & TRACE_PFMAJ) && 2001 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ)) 2002 goto out_error_tp; 2003 2004 if ((trace->trace_pgfaults & TRACE_PFMIN) && 2005 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MIN)) 2006 goto out_error_tp; 2007 |
|
1910 if (trace->sched && 1911 perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", 1912 trace__sched_stat_runtime)) 1913 goto out_error_tp; 1914 1915 err = perf_evlist__create_maps(evlist, &trace->opts.target); 1916 if (err < 0) { 1917 fprintf(trace->output, "Problems parsing the target to trace, check your options!\n"); --- 64 unchanged lines hidden (view full) --- 1982 } 1983 1984 evsel = perf_evlist__id2evsel(evlist, sample.id); 1985 if (evsel == NULL) { 1986 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); 1987 goto next_event; 1988 } 1989 | 2008 if (trace->sched && 2009 perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", 2010 trace__sched_stat_runtime)) 2011 goto out_error_tp; 2012 2013 err = perf_evlist__create_maps(evlist, &trace->opts.target); 2014 if (err < 0) { 2015 fprintf(trace->output, "Problems parsing the target to trace, check your options!\n"); --- 64 unchanged lines hidden (view full) --- 2080 } 2081 2082 evsel = perf_evlist__id2evsel(evlist, sample.id); 2083 if (evsel == NULL) { 2084 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); 2085 goto next_event; 2086 } 2087 |
1990 if (sample.raw_data == NULL) { | 2088 if (evsel->attr.type == PERF_TYPE_TRACEPOINT && 2089 sample.raw_data == NULL) { |
1991 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", 1992 perf_evsel__name(evsel), sample.tid, 1993 sample.cpu, sample.raw_size); 1994 goto next_event; 1995 } 1996 1997 handler = evsel->handler; 1998 handler(trace, evsel, event, &sample); --- 265 unchanged lines hidden (view full) --- 2264 rename(filename, oldname); 2265 } 2266 2267 trace->output = fopen(filename, "w"); 2268 2269 return trace->output == NULL ? -errno : 0; 2270} 2271 | 2090 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", 2091 perf_evsel__name(evsel), sample.tid, 2092 sample.cpu, sample.raw_size); 2093 goto next_event; 2094 } 2095 2096 handler = evsel->handler; 2097 handler(trace, evsel, event, &sample); --- 265 unchanged lines hidden (view full) --- 2363 rename(filename, oldname); 2364 } 2365 2366 trace->output = fopen(filename, "w"); 2367 2368 return trace->output == NULL ? -errno : 0; 2369} 2370 |
2371static int parse_pagefaults(const struct option *opt, const char *str, 2372 int unset __maybe_unused) 2373{ 2374 int *trace_pgfaults = opt->value; 2375 2376 if (strcmp(str, "all") == 0) 2377 *trace_pgfaults |= TRACE_PFMAJ | TRACE_PFMIN; 2378 else if (strcmp(str, "maj") == 0) 2379 *trace_pgfaults |= TRACE_PFMAJ; 2380 else if (strcmp(str, "min") == 0) 2381 *trace_pgfaults |= TRACE_PFMIN; 2382 else 2383 return -1; 2384 2385 return 0; 2386} 2387 |
|
2272int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 2273{ 2274 const char * const trace_usage[] = { 2275 "perf trace [<options>] [<command>]", 2276 "perf trace [<options>] -- <command> [<options>]", 2277 "perf trace record [<options>] [<command>]", 2278 "perf trace record [<options>] -- <command> [<options>]", 2279 NULL --- 50 unchanged lines hidden (view full) --- 2330 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), 2331 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 2332 OPT_BOOLEAN('T', "time", &trace.full_time, 2333 "Show full timestamp, not time relative to first start"), 2334 OPT_BOOLEAN('s', "summary", &trace.summary_only, 2335 "Show only syscall summary with statistics"), 2336 OPT_BOOLEAN('S', "with-summary", &trace.summary, 2337 "Show all syscalls and summary with statistics"), | 2388int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 2389{ 2390 const char * const trace_usage[] = { 2391 "perf trace [<options>] [<command>]", 2392 "perf trace [<options>] -- <command> [<options>]", 2393 "perf trace record [<options>] [<command>]", 2394 "perf trace record [<options>] -- <command> [<options>]", 2395 NULL --- 50 unchanged lines hidden (view full) --- 2446 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), 2447 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 2448 OPT_BOOLEAN('T', "time", &trace.full_time, 2449 "Show full timestamp, not time relative to first start"), 2450 OPT_BOOLEAN('s', "summary", &trace.summary_only, 2451 "Show only syscall summary with statistics"), 2452 OPT_BOOLEAN('S', "with-summary", &trace.summary, 2453 "Show all syscalls and summary with statistics"), |
2454 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min", 2455 "Trace pagefaults", parse_pagefaults, "maj"), |
|
2338 OPT_END() 2339 }; 2340 int err; 2341 char bf[BUFSIZ]; 2342 2343 if ((argc > 1) && (strcmp(argv[1], "record") == 0)) 2344 return trace__record(argc-2, &argv[2]); 2345 2346 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 2347 2348 /* summary_only implies summary option, but don't overwrite summary if set */ 2349 if (trace.summary_only) 2350 trace.summary = trace.summary_only; 2351 | 2456 OPT_END() 2457 }; 2458 int err; 2459 char bf[BUFSIZ]; 2460 2461 if ((argc > 1) && (strcmp(argv[1], "record") == 0)) 2462 return trace__record(argc-2, &argv[2]); 2463 2464 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 2465 2466 /* summary_only implies summary option, but don't overwrite summary if set */ 2467 if (trace.summary_only) 2468 trace.summary = trace.summary_only; 2469 |
2470 if (trace.trace_pgfaults) { 2471 trace.opts.sample_address = true; 2472 trace.opts.sample_time = true; 2473 } 2474 |
|
2352 if (output_name != NULL) { 2353 err = trace__open_output(&trace, output_name); 2354 if (err < 0) { 2355 perror("failed to create output file"); 2356 goto out; 2357 } 2358 } 2359 --- 43 unchanged lines hidden --- | 2475 if (output_name != NULL) { 2476 err = trace__open_output(&trace, output_name); 2477 if (err < 0) { 2478 perror("failed to create output file"); 2479 goto out; 2480 } 2481 } 2482 --- 43 unchanged lines hidden --- |