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 ---