19 #include <traceevent/event-parse.h> 20 #include <api/fs/tracing_path.h> 28 #include <subcmd/exec-cmd.h> 33 #include <subcmd/parse-options.h> 54 #include <linux/err.h> 55 #include <linux/filter.h> 56 #include <linux/kernel.h> 57 #include <linux/random.h> 58 #include <linux/stringify.h> 59 #include <linux/time64.h> 65 # define O_CLOEXEC 02000000 68 #ifndef F_LINUX_SPECIFIC_BASE 69 # define F_LINUX_SPECIFIC_BASE 1024 135 #define TP_UINT_FIELD(bits) \ 136 static u64 tp_field__u##bits(struct tp_field *field, struct perf_sample *sample) \ 139 memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \ 148 #define TP_UINT_FIELD__SWAPPED(bits) \ 149 static u64 tp_field__swapped_u##bits(struct tp_field *field, struct perf_sample *sample) \ 152 memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \ 153 return bswap_##bits(value);\ 161 struct format_field *format_field,
164 field->
offset = format_field->offset;
166 switch (format_field->size) {
171 field->
integer = needs_swap ? tp_field__swapped_u16 : tp_field__u16;
174 field->
integer = needs_swap ? tp_field__swapped_u32 : tp_field__u32;
177 field->
integer = needs_swap ? tp_field__swapped_u64 : tp_field__u64;
193 field->
offset = format_field->offset;
211 if (format_field == NULL)
217 #define perf_evsel__init_sc_tp_uint_field(evsel, name) \ 218 ({ struct syscall_tp *sc = evsel->priv;\ 219 perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); }) 227 if (format_field == NULL)
233 #define perf_evsel__init_sc_tp_ptr_field(evsel, name) \ 234 ({ struct syscall_tp *sc = evsel->priv;\ 235 perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); }) 246 if (evsel->
priv != NULL) {
282 #define perf_evsel__sc_tp_uint(evsel, name, sample) \ 283 ({ struct syscall_tp *fields = evsel->priv; \ 284 fields->name.integer(&fields->name, sample); }) 286 #define perf_evsel__sc_tp_ptr(evsel, name, sample) \ 287 ({ struct syscall_tp *fields = evsel->priv; \ 288 fields->name.pointer(&fields->name, sample); }) 295 return scnprintf(bf, size, intfmt, val);
297 return scnprintf(bf, size,
"%s", sa->
entries[idx]);
313 #define SCA_STRARRAY syscall_arg__scnprintf_strarray 320 #define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ 321 .nr_entries = ARRAY_SIZE(array), \ 338 return scnprintf(bf, size,
"%s", sa->
entries[idx]);
342 return scnprintf(bf, size,
"%d", arg->
val);
346 #define AT_FDCWD -100 355 return scnprintf(bf, size,
"CWD");
360 #define SCA_FDAT syscall_arg__scnprintf_fd_at 365 #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd 369 return scnprintf(bf, size,
"%#lx", arg->
val);
374 return scnprintf(bf, size,
"%d", arg->
val);
379 return scnprintf(bf, size,
"%ld", arg->
val);
383 "MAP_CREATE",
"MAP_LOOKUP_ELEM",
"MAP_UPDATE_ELEM",
"MAP_DELETE_ELEM",
384 "MAP_GET_NEXT_KEY",
"PROG_LOAD",
391 static const char *
itimers[] = {
"REAL",
"VIRTUAL",
"PROF", };
395 "GET_KEYRING_ID",
"JOIN_SESSION_KEYRING",
"UPDATE",
"REVOKE",
"CHOWN",
396 "SETPERM",
"DESCRIBE",
"CLEAR",
"LINK",
"UNLINK",
"SEARCH",
"READ",
397 "INSTANTIATE",
"NEGATE",
"SET_REQKEY_KEYRING",
"SET_TIMEOUT",
398 "ASSUME_AUTHORITY",
"GET_SECURITY",
"SESSION_TO_PARENT",
"REJECT",
399 "INSTANTIATE_IOV",
"INVALIDATE",
"GET_PERSISTENT",
403 static const char *
whences[] = {
"SET",
"CUR",
"END",
414 "DUPFD",
"GETFD",
"SETFD",
"GETFL",
"SETFL",
"GETLK",
"SETLK",
415 "SETLKW",
"SETOWN",
"GETOWN",
"SETSIG",
"GETSIG",
"GETLK64",
416 "SETLK64",
"SETLKW64",
"SETOWN_EX",
"GETOWN_EX",
422 "SETLEASE",
"GETLEASE",
"NOTIFY", [5] =
"CANCELLK",
"DUPFD_CLOEXEC",
423 "SETPIPE_SZ",
"GETPIPE_SZ",
"ADD_SEALS",
"GET_SEALS",
424 "GET_RW_HINT",
"SET_RW_HINT",
"GET_FILE_RW_HINT",
"SET_FILE_RW_HINT",
430 &strarray__fcntl_cmds,
431 &strarray__fcntl_linux_specific_cmds,
437 "CPU",
"FSIZE",
"DATA",
"STACK",
"CORE",
"RSS",
"NPROC",
"NOFILE",
438 "MEMLOCK",
"AS",
"LOCKS",
"SIGPENDING",
"MSGQUEUE",
"NICE",
"RTPRIO",
443 static const char *
sighow[] = {
"BLOCK",
"UNBLOCK",
"SETMASK", };
447 "REALTIME",
"MONOTONIC",
"PROCESS_CPUTIME_ID",
"THREAD_CPUTIME_ID",
448 "MONOTONIC_RAW",
"REALTIME_COARSE",
"MONOTONIC_COARSE",
"BOOTTIME",
449 "REALTIME_ALARM",
"BOOTTIME_ALARM",
"SGI_CYCLE",
"TAI" 454 "UNSPEC",
"LOCAL",
"INET",
"AX25",
"IPX",
"APPLETALK",
"NETROM",
455 "BRIDGE",
"ATMPVC",
"X25",
"INET6",
"ROSE",
"DECnet",
"NETBEUI",
456 "SECURITY",
"KEY",
"NETLINK",
"PACKET",
"ASH",
"ECONET",
"ATMSVC",
457 "RDS",
"SNA",
"IRDA",
"PPPOX",
"WANPIPE",
"LLC",
"IB",
"CAN",
"TIPC",
458 "BLUETOOTH",
"IUCV",
"RXRPC",
"ISDN",
"PHONET",
"IEEE802154",
"CAIF",
459 "ALG",
"NFC",
"VSOCK",
470 return scnprintf(bf, size,
"F");
472 if (mode & n##_OK) { \ 473 printed += scnprintf(bf + printed, size - printed, "%s", #n); \ 483 printed += scnprintf(bf + printed, size - printed,
"|%#x", mode);
488 #define SCA_ACCMODE syscall_arg__scnprintf_access_mode 493 #define SCA_FILENAME syscall_arg__scnprintf_filename 501 if (flags & O_##n) { \ 502 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ 511 printed += scnprintf(bf + printed, size - printed,
"%s%#x", printed ?
"|" :
"",
flags);
516 #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags 518 #ifndef GRND_NONBLOCK 519 #define GRND_NONBLOCK 0x0001 522 #define GRND_RANDOM 0x0002 531 if (flags & GRND_##n) { \ 532 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ 533 flags &= ~GRND_##n; \ 541 printed += scnprintf(bf + printed, size - printed,
"%s%#x", printed ?
"|" :
"",
flags);
546 #define SCA_GETRANDOM_FLAGS syscall_arg__scnprintf_getrandom_flags 548 #define STRARRAY(name, array) \ 549 { .scnprintf = SCA_STRARRAY, \ 550 .parm = &strarray__##array, } 585 .arg = { [1] = { .scnprintf =
SCA_ACCMODE, }, }, },
588 { .name =
"brk", .hexret =
true,
589 .arg = { [0] = { .scnprintf =
SCA_HEX, }, }, },
590 { .name =
"clock_gettime",
592 { .name =
"clone", .errpid =
true, .nr_args = 5,
594 [1] = { .name =
"child_stack", .scnprintf =
SCA_HEX, },
595 [2] = { .name =
"parent_tidptr", .scnprintf =
SCA_HEX, },
596 [3] = { .name =
"child_tidptr", .scnprintf =
SCA_HEX, },
597 [4] = { .name =
"tls", .scnprintf =
SCA_HEX, }, }, },
600 { .name =
"epoll_ctl",
602 { .name =
"eventfd2",
604 { .name =
"fchmodat",
605 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
606 { .name =
"fchownat",
607 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
610 .parm = &strarrays__fcntl_cmds_arrays,
611 .show_zero =
true, },
614 .arg = { [1] = { .scnprintf =
SCA_FLOCK, }, }, },
615 { .name =
"fstat", .alias =
"newfstat", },
616 { .name =
"fstatat", .alias =
"newfstatat", },
620 { .name =
"futimesat",
621 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
622 { .name =
"getitimer",
624 { .name =
"getpid", .errpid =
true, },
625 { .name =
"getpgid", .errpid =
true, },
626 { .name =
"getppid", .errpid =
true, },
627 { .name =
"getrandom",
629 { .name =
"getrlimit",
631 { .name =
"gettid", .errpid =
true, },
634 #if defined(__i386__) || defined(__x86_64__) 639 [2] = { .scnprintf =
SCA_HEX, }, }, },
641 [2] = { .scnprintf =
SCA_HEX, }, }, },
643 { .name =
"kcmp", .nr_args = 5,
644 .arg = { [0] = { .name =
"pid1", .scnprintf =
SCA_PID, },
645 [1] = { .name =
"pid2", .scnprintf =
SCA_PID, },
648 [4] = { .name =
"idx2", .scnprintf =
SCA_KCMP_IDX, }, }, },
652 .arg = { [1] = { .scnprintf =
SCA_SIGNUM, }, }, },
654 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
657 { .name =
"lstat", .alias =
"newlstat", },
659 .arg = { [0] = { .scnprintf =
SCA_HEX, },
662 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
664 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
666 .arg = { [0] = { .scnprintf =
SCA_HEX, }, }, },
667 { .name =
"mlockall",
668 .arg = { [0] = { .scnprintf =
SCA_HEX, }, }, },
669 { .name =
"mmap", .hexret =
true,
671 #if defined(__s390x__) 674 .arg = { [0] = { .scnprintf =
SCA_HEX, },
677 { .name =
"mprotect",
678 .arg = { [0] = { .scnprintf =
SCA_HEX, },
680 { .name =
"mq_unlink",
682 { .name =
"mremap", .hexret =
true,
683 .arg = { [0] = { .scnprintf =
SCA_HEX, },
685 [4] = { .scnprintf =
SCA_HEX, }, }, },
687 .arg = { [0] = { .scnprintf =
SCA_HEX, }, }, },
689 .arg = { [0] = { .scnprintf =
SCA_HEX, }, }, },
690 { .name =
"name_to_handle_at",
691 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
692 { .name =
"newfstatat",
693 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
696 { .name =
"open_by_handle_at",
697 .arg = { [0] = { .scnprintf =
SCA_FDAT, },
700 .arg = { [0] = { .scnprintf =
SCA_FDAT, },
702 { .name =
"perf_event_open",
703 .arg = { [2] = { .scnprintf =
SCA_INT, },
704 [3] = { .scnprintf =
SCA_FD, },
708 { .name =
"pkey_alloc",
710 { .name =
"pkey_free",
711 .arg = { [0] = { .scnprintf =
SCA_INT, }, }, },
712 { .name =
"pkey_mprotect",
713 .arg = { [0] = { .scnprintf =
SCA_HEX, },
715 [3] = { .scnprintf =
SCA_INT, }, }, },
716 { .name =
"poll", .timeout =
true, },
717 { .name =
"ppoll", .timeout =
true, },
718 { .name =
"prctl", .alias =
"arch_prctl",
722 { .name =
"pread", .alias =
"pread64", },
723 { .name =
"preadv", .alias =
"pread", },
724 { .name =
"prlimit64",
726 { .name =
"pwrite", .alias =
"pwrite64", },
727 { .name =
"readlinkat",
728 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
729 { .name =
"recvfrom",
731 { .name =
"recvmmsg",
735 { .name =
"renameat",
736 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
737 { .name =
"rt_sigaction",
738 .arg = { [0] = { .scnprintf =
SCA_SIGNUM, }, }, },
739 { .name =
"rt_sigprocmask",
741 { .name =
"rt_sigqueueinfo",
742 .arg = { [1] = { .scnprintf =
SCA_SIGNUM, }, }, },
743 { .name =
"rt_tgsigqueueinfo",
744 .arg = { [2] = { .scnprintf =
SCA_SIGNUM, }, }, },
745 { .name =
"sched_setscheduler",
750 { .name =
"select", .timeout =
true, },
751 { .name =
"sendmmsg",
757 { .name =
"set_tid_address", .errpid =
true, },
758 { .name =
"setitimer",
760 { .name =
"setrlimit",
765 { .name =
"socketpair",
768 { .name =
"stat", .alias =
"newstat", },
770 .arg = { [0] = { .scnprintf =
SCA_FDAT, },
777 { .name =
"symlinkat",
778 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
780 .arg = { [2] = { .scnprintf =
SCA_SIGNUM, }, }, },
782 .arg = { [1] = { .scnprintf =
SCA_SIGNUM, }, }, },
783 { .name =
"uname", .alias =
"newuname", },
784 { .name =
"unlinkat",
785 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
786 { .name =
"utimensat",
787 .arg = { [0] = { .scnprintf =
SCA_FDAT, }, }, },
788 { .name =
"wait4", .errpid =
true,
790 { .name =
"waitid", .errpid =
true,
797 return strcmp(name, fmt->
name);
825 double duration = (double)t / NSEC_PER_MSEC;
826 size_t printed = fprintf(fp,
"(");
829 printed += fprintf(fp,
" ");
830 else if (duration >= 1.0)
832 else if (duration >= 0.01)
836 return printed + fprintf(fp,
"): ");
900 "WARNING: not enough memory, dropping samples!\n");
913 #define TRACE_PFMAJ (1 << 0) 914 #define TRACE_PFMIN (1 << 1) 923 char **npath = realloc(ttrace->
paths.
table, (fd + 1) *
sizeof(
char *));
930 (fd - ttrace->
paths.
max) *
sizeof(
char *));
932 memset(npath, 0, (fd + 1) *
sizeof(
char *));
941 return ttrace->
paths.
table[fd] != NULL ? 0 : -1;
950 if (thread->
pid_ == thread->
tid) {
951 scnprintf(linkname,
sizeof(linkname),
952 "/proc/%d/fd/%d", thread->
pid_, fd);
954 scnprintf(linkname,
sizeof(linkname),
955 "/proc/%d/task/%d/fd/%d", thread->
pid_, thread->
tid, fd);
958 if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)
sizeof(pathname))
961 ret = readlink(linkname, pathname,
sizeof(pathname));
963 if (ret < 0 || ret > st.st_size)
966 pathname[ret] =
'\0';
995 size_t printed = scnprintf(bf, size,
"%d", fd);
999 printed += scnprintf(bf + printed, size - printed,
"<%s>", path);
1006 size_t printed = scnprintf(bf, size,
"%d", fd);
1013 printed += scnprintf(bf + printed, size - printed,
"<%s>", path);
1028 if (ttrace && fd >= 0 && fd <= ttrace->
paths.max)
1046 unsigned long ptr = arg->
val;
1049 return scnprintf(bf, size,
"%#x", ptr);
1062 double ts = (double)(tstamp - trace->
base_time) / NSEC_PER_MSEC;
1064 return fprintf(fp,
"%10.3f ", ts);
1078 return fprintf(fp,
" ? ");
1087 interrupted = sig == SIGINT;
1091 u64 duration,
bool duration_calculated, u64 tstamp, FILE *fp)
1099 printed += fprintf(fp,
"%d ", thread->
tid);
1110 switch (event->
header.type) {
1111 case PERF_RECORD_LOST:
1113 "LOST %" PRIu64
" events!\n", event->
lost.
lost);
1129 struct trace *
trace = container_of(tool,
struct trace, tool);
1141 pr_warning(
"Kernel address maps (/proc/{kallsyms,modules}) are restricted.\n\n" 1142 "Check /proc/sys/kernel/kptr_restrict.\n\n" 1143 "Kernel samples will not be resolved.\n");
1159 if (trace->
host == NULL)
1195 for (idx = 0; idx < nr_args; ++idx) {
1206 struct format_field *
field;
1209 for (field = sc->
args; field; field = field->next, ++idx) {
1213 if (strcmp(field->type,
"const char *") == 0 &&
1214 (strcmp(field->name,
"filename") == 0 ||
1215 strcmp(field->name,
"path") == 0 ||
1216 strcmp(field->name,
"pathname") == 0))
1218 else if (field->flags & FIELD_IS_POINTER)
1220 else if (strcmp(field->type,
"pid_t") == 0)
1222 else if (strcmp(field->type,
"umode_t") == 0)
1224 else if ((strcmp(field->type,
"int") == 0 ||
1225 strcmp(field->type,
"unsigned int") == 0 ||
1226 strcmp(field->type,
"long") == 0) &&
1227 (len = strlen(field->name)) >= 2 &&
1228 strcmp(field->name + len - 2,
"fd") == 0) {
1255 if (nsyscalls == NULL)
1262 memset(nsyscalls, 0, (
id + 1) *
sizeof(*sc));
1274 snprintf(tp_name,
sizeof(tp_name),
"sys_enter_%s", sc->
name);
1278 snprintf(tp_name,
sizeof(tp_name),
"sys_enter_%s", sc->
fmt->
alias);
1294 if (sc->
args && (!strcmp(sc->
args->name,
"__syscall_nr") || !strcmp(sc->
args->name,
"nr"))) {
1299 sc->
is_exit = !strcmp(name,
"exit_group") || !strcmp(name,
"exit");
1307 size_t nr_allocated;
1315 fputs(
"Error:\tNot enough memory for allocating events qualifier ids\n",
1325 const char *sc = pos->
s;
1334 fputs(
"Error:\tInvalid syscall ", trace->
output);
1337 fputs(
", ", trace->
output);
1340 fputs(sc, trace->
output);
1344 if (match_next == -1)
1357 if (entries == NULL) {
1359 fputs(
"\nError:\t Not enough memory for parsing\n", trace->
output);
1370 fputs(
"\nHint:\ttry 'perf list syscalls:sys_enter_*'" 1371 "\nHint:\tand: 'man syscalls'\n", trace->
output);
1391 unsigned char *p = arg->
args +
sizeof(
unsigned long) * idx;
1393 memcpy(&val, p,
sizeof(val));
1403 return scnprintf(bf, size,
"arg%d: ", arg->
idx);
1415 return scnprintf(bf, size,
"%ld", val);
1441 if (sc->
args != NULL) {
1442 struct format_field *
field;
1444 for (field = sc->
args; field;
1445 field = field->next, ++arg.
idx, bit <<= 1) {
1464 printed += scnprintf(bf + printed, size - printed,
1465 "%s%s: ", printed ?
", " :
"", field->name);
1479 printed += scnprintf(bf + printed, size - printed,
", ");
1513 fprintf(trace->
output,
"Invalid syscall %d id, skipping (%s, %" PRIu64
") ...\n",
1530 fprintf(trace->
output,
"Problems reading syscall %d",
id);
1533 fputs(
" information\n", trace->
output);
1549 stats = inode->
priv;
1550 if (stats == NULL) {
1551 stats =
malloc(
sizeof(
struct stats));
1590 double ts = (double)sample->
time / NSEC_PER_MSEC;
1592 printed += fprintf(trace->
output,
"%22s %10.3f %s %d/%d [%d]\n",
1636 printed += scnprintf(msg + printed, trace__entry_str_size - printed,
"%s(", sc->
name);
1639 args, trace, thread);
1652 if (trace->
current != thread) {
1668 evsel->
attr.sample_max_stack :
1702 bool duration_calculated =
false;
1733 duration_calculated =
true;
1739 if (callchain_ret == 0) {
1754 fprintf(trace->
output,
" ... [");
1759 if (sc->
fmt == NULL) {
1763 fprintf(trace->
output,
") = %ld", ret);
1764 }
else if (ret < 0) {
1767 const char *emsg = str_error_r(-ret, bf,
sizeof(bf)),
1770 fprintf(trace->
output,
") = -1 %s %s", e, emsg);
1773 fprintf(trace->
output,
") = 0 Timeout");
1783 fprintf(trace->
output,
") = %s", bf);
1785 fprintf(trace->
output,
") = %#lx", ret);
1789 if (child != NULL) {
1790 fprintf(trace->
output,
") = %ld", ret);
1798 fputc(
'\n', trace->
output);
1800 if (callchain_ret > 0)
1802 else if (callchain_ret < 0)
1818 size_t filename_len, entry_str_len, to_move;
1819 ssize_t remaining_space;
1830 filename_len = strlen(filename);
1831 if (filename_len == 0)
1850 entry_str_len = strlen(ttrace->
entry_str);
1851 remaining_space = trace__entry_str_size - entry_str_len - 1;
1852 if (remaining_space <= 0)
1855 if (filename_len > (
size_t)remaining_space) {
1856 filename += filename_len - remaining_space;
1857 filename_len = remaining_space;
1862 memmove(pos + filename_len, pos, to_move);
1863 memcpy(pos, filename, filename_len);
1878 double runtime_ms = (double)runtime / NSEC_PER_MSEC;
1894 fprintf(trace->
output,
"%s: comm=%s,pid=%u,runtime=%" PRIu64
",vruntime=%" PRIu64
")\n",
1904 unsigned int val,
void *extra __maybe_unused, FILE *fp)
1906 unsigned char ch = (
unsigned char)val;
1910 return fprintf(fp,
"%c",
isprint(ch) ? ch :
'.');
1938 int callchain_ret = 0;
1942 if (callchain_ret == 0) {
1953 fprintf(trace->
output,
"( ): ");
1965 fprintf(trace->
output,
"\n");
1967 if (callchain_ret > 0)
1969 else if (callchain_ret < 0)
1977 bool print_dso,
bool print_sym)
1984 fprintf(f,
"%s+0x%" PRIx64, al->
sym->
name,
1987 fprintf(f,
"0x%" PRIx64, al->
addr);
1989 fprintf(f,
"0x%" PRIx64, sample->
addr);
1999 char map_type =
'd';
2002 int callchain_ret = 0;
2008 if (callchain_ret == 0) {
2019 if (evsel->
attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
2031 fprintf(trace->
output,
"%sfault [",
2032 evsel->
attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ?
2037 fprintf(trace->
output,
"] => ");
2052 fprintf(trace->
output,
" (%c%c)\n", map_type, al.
level);
2054 if (callchain_ret > 0)
2056 else if (callchain_ret < 0)
2078 (evsel->
attr.sample_type & PERF_SAMPLE_TIME))
2088 struct trace *trace = container_of(tool,
struct trace, tool);
2102 handler(trace, evsel, event, sample);
2111 unsigned int rec_argc, i, j;
2112 const char **rec_argv;
2113 const char *
const record_args[] = {
2120 const char *
const sc_args[] = {
"-e", };
2121 unsigned int sc_args_nr = ARRAY_SIZE(sc_args);
2122 const char *
const majpf_args[] = {
"-e",
"major-faults" };
2123 unsigned int majpf_args_nr = ARRAY_SIZE(majpf_args);
2124 const char *
const minpf_args[] = {
"-e",
"minor-faults" };
2125 unsigned int minpf_args_nr = ARRAY_SIZE(minpf_args);
2128 rec_argc = ARRAY_SIZE(record_args) + sc_args_nr + 1 +
2129 majpf_args_nr + minpf_args_nr +
argc;
2130 rec_argv = calloc(rec_argc + 1,
sizeof(
char *));
2132 if (rec_argv == NULL)
2136 for (i = 0; i < ARRAY_SIZE(record_args); i++)
2137 rec_argv[j++] = record_args[i];
2140 for (i = 0; i < sc_args_nr; i++)
2141 rec_argv[j++] = sc_args[i];
2145 rec_argv[j++] =
"raw_syscalls:sys_enter,raw_syscalls:sys_exit";
2147 rec_argv[j++] =
"syscalls:sys_enter,syscalls:sys_exit";
2149 pr_err(
"Neither raw_syscalls nor syscalls events exist.\n");
2156 for (i = 0; i < majpf_args_nr; i++)
2157 rec_argv[j++] = majpf_args[i];
2160 for (i = 0; i < minpf_args_nr; i++)
2161 rec_argv[j++] = minpf_args[i];
2163 for (i = 0; i < (
unsigned int)argc; i++)
2164 rec_argv[j++] = argv[i];
2191 struct perf_event_attr attr = {
2192 .type = PERF_TYPE_SOFTWARE,
2197 attr.sample_period = 1;
2210 const u32 type =
event->header.type;
2213 if (type != PERF_RECORD_SAMPLE) {
2219 if (evsel == NULL) {
2220 fprintf(trace->
output,
"Unknown tp ID %" PRIu64
", skipping...\n", sample->
id);
2226 if (evsel->
attr.type == PERF_TYPE_TRACEPOINT &&
2228 fprintf(trace->
output,
"%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
2233 handler(trace, evsel, event, sample);
2244 if (sys_enter == NULL)
2248 goto out_delete_sys_enter;
2251 if (sys_exit == NULL)
2252 goto out_delete_sys_enter;
2255 goto out_delete_sys_exit;
2269 sys_exit->
attr.exclude_callchain_kernel = 1;
2279 out_delete_sys_exit:
2281 out_delete_sys_enter:
2313 unsigned int nr = 1;
2319 while (thread && nr < ARRAY_SIZE(pids)) {
2326 pids[nr++] = parent->
tid;
2338 struct perf_evsel *evsel, *pgfault_maj = NULL, *pgfault_min = NULL;
2340 unsigned long before;
2341 const bool forks = argc > 0;
2342 bool draining =
false;
2347 goto out_error_raw_syscalls;
2354 if (pgfault_maj == NULL)
2362 if (pgfault_min == NULL)
2371 goto out_error_sched_stat_runtime;
2403 fprintf(trace->
output,
"Problems parsing the target to trace, check your options!\n");
2404 goto out_delete_evlist;
2409 fprintf(trace->
output,
"Problems initializing symbol libraries!\n");
2410 goto out_delete_evlist;
2422 fprintf(trace->
output,
"Couldn't run the workload!\n");
2423 goto out_delete_evlist;
2429 goto out_error_open;
2433 char errbuf[BUFSIZ];
2436 pr_err(
"ERROR: Apply config to BPF failed: %s\n",
2438 goto out_error_open;
2460 pr_debug(
"event qualifier tracepoint filter: %s\n",
2466 goto out_error_apply_filters;
2470 goto out_error_mmap;
2495 evsel->
attr.sample_max_stack == 0)
2501 for (i = 0; i < evlist->
nr_mmaps; i++) {
2505 md = &evlist->
mmap[i];
2516 fprintf(trace->
output,
"Can't parse sample, err = %d, skipping...\n", err);
2527 if (done && !draining) {
2536 int timeout = done ? 100 : -1;
2558 fprintf(trace->
output,
"Stats:\n " 2559 " vfs_getname : %" PRIu64
"\n" 2560 " proc_getname: %" PRIu64
"\n",
2572 trace->
live =
false;
2575 char errbuf[BUFSIZ];
2577 out_error_sched_stat_runtime:
2578 tracing_path__strerror_open_tp(errno, errbuf,
sizeof(errbuf),
"sched",
"sched_stat_runtime");
2581 out_error_raw_syscalls:
2582 tracing_path__strerror_open_tp(errno, errbuf,
sizeof(errbuf),
"raw_syscalls",
"sys_(enter|exit)");
2593 fprintf(trace->
output,
"%s\n", errbuf);
2594 goto out_delete_evlist;
2596 out_error_apply_filters:
2598 "Failed to set filter \"%s\" on event %s with %d (%s)\n",
2600 str_error_r(errno, errbuf,
sizeof(errbuf)));
2601 goto out_delete_evlist;
2604 fprintf(trace->
output,
"Not enough memory to run!\n");
2605 goto out_delete_evlist;
2609 goto out_delete_evlist;
2622 .force = trace->
force,
2646 if (session == NULL)
2665 "raw_syscalls:sys_enter");
2669 "syscalls:sys_enter");
2674 pr_err(
"Error during initialize raw_syscalls:sys_enter event\n");
2679 "raw_syscalls:sys_exit");
2682 "syscalls:sys_exit");
2686 pr_err(
"Error during initialize raw_syscalls:sys_exit event\n");
2691 if (evsel->
attr.type == PERF_TYPE_SOFTWARE &&
2692 (evsel->
attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ||
2693 evsel->
attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
2694 evsel->
attr.config == PERF_COUNT_SW_PAGE_FAULTS))
2702 pr_err(
"Failed to process events, error %d", err);
2717 printed = fprintf(fp,
"\n Summary of events:\n\n");
2731 entry->syscall = source->
i;
2733 entry->msecs = stats ? (u64)stats->
n * (
avg_stats(stats) / NSEC_PER_MSEC) : 0;
2737 struct trace *trace, FILE *fp)
2744 if (syscall_stats == NULL)
2747 printed += fprintf(fp,
"\n");
2749 printed += fprintf(fp,
" syscall calls total min avg max stddev\n");
2750 printed += fprintf(fp,
" (msec) (msec) (msec) (msec) (%%)\n");
2751 printed += fprintf(fp,
" --------------- -------- --------- --------- --------- --------- ------\n");
2754 struct stats *
stats = syscall_stats_entry->stats;
2756 double min = (double)(stats->
min) / NSEC_PER_MSEC;
2757 double max = (double)(stats->
max) / NSEC_PER_MSEC;
2760 u64
n = (u64) stats->
n;
2763 avg /= NSEC_PER_MSEC;
2766 printed += fprintf(fp,
" %-15s", sc->
name);
2767 printed += fprintf(fp,
" %8" PRIu64
" %9.3f %9.3f %9.3f",
2768 n, syscall_stats_entry->msecs, min, avg);
2769 printed += fprintf(fp,
" %9.3f %9.2f%%\n", max, pct);
2774 printed += fprintf(fp,
"\n\n");
2791 printed += fprintf(fp,
"%lu events, ", ttrace->
nr_events);
2792 printed += fprintf(fp,
"%.1f%%", ratio);
2794 printed += fprintf(fp,
", %lu majfaults", ttrace->
pfmaj);
2796 printed += fprintf(fp,
", %lu minfaults", ttrace->
pfmin);
2798 printed += fprintf(fp,
", %.3f msec\n", ttrace->
runtime_ms);
2799 else if (fputc(
'\n', fp) != EOF)
2816 entry->thread = rb_entry(nd,
struct thread, rb_node);
2829 fprintf(fp,
"%s",
"Error sorting output by nr_events!\n");
2842 int unset __maybe_unused)
2844 struct trace *trace = opt->value;
2851 int unset __maybe_unused)
2855 struct trace *trace = opt->value;
2886 if (!stat(filename, &st) && st.st_size) {
2889 scnprintf(oldname,
sizeof(oldname),
"%s.old", filename);
2891 rename(filename, oldname);
2894 trace->
output = fopen(filename,
"w");
2896 return trace->
output == NULL ? -errno : 0;
2900 int unset __maybe_unused)
2904 if (strcmp(str,
"all") == 0)
2906 else if (strcmp(str,
"maj") == 0)
2908 else if (strcmp(str,
"min") == 0)
2933 int unset __maybe_unused)
2935 struct trace *trace = (
struct trace *)opt->value;
2936 const char *s = str;
2937 char *sep = NULL, *lists[2] = { NULL, NULL, };
2938 int len = strlen(
str) + 1,
err = -1, list, idx;
2939 char *strace_groups_dir = system_path(STRACE_GROUPS_DIR);
2942 if (strace_groups_dir == NULL)
2951 if ((sep = strchr(s,
',')) != NULL)
2959 path__join(group_name,
sizeof(group_name), strace_groups_dir, s);
2960 if (access(group_name, R_OK) == 0)
2965 sprintf(lists[list] + strlen(lists[list]),
",%s", s);
2967 lists[list] =
malloc(len);
2968 if (lists[list] == NULL)
2970 strcpy(lists[list], s);
2980 if (lists[1] != NULL) {
2987 fputs(
"Not enough memory to parse event qualifier", trace->
output);
2998 struct option o = OPT_CALLBACK(
'e',
"event", &trace->
evlist,
"event",
2999 "event selector. use 'perf list' to list available events",
3012 struct trace *trace = opt->value;
3024 const char *trace_usage[] = {
3025 "perf trace [<options>] [<command>]",
3026 "perf trace [<options>] -- <command> [<options>]",
3027 "perf trace record [<options>] [<command>]",
3028 "perf trace record [<options>] -- <command> [<options>]",
3031 struct trace trace = {
3040 .user_freq = UINT_MAX,
3041 .user_interval = ULLONG_MAX,
3042 .no_buffering =
true,
3043 .mmap_pages = UINT_MAX,
3044 .proc_map_timeout = 500,
3048 .trace_syscalls =
true,
3049 .kernel_syscallchains =
false,
3050 .max_stack = UINT_MAX,
3053 const struct option trace_options[] = {
3054 OPT_CALLBACK(
'e',
"event", &trace,
"event",
3055 "event/syscall selector. use 'perf list' to list available events",
3057 OPT_BOOLEAN(0,
"comm", &trace.
show_comm,
3058 "show the thread COMM next to its id"),
3059 OPT_BOOLEAN(0,
"tool_stats", &trace.
show_tool_stats,
"show tool stats"),
3060 OPT_CALLBACK(0,
"expr", &trace,
"expr",
"list of syscalls/events to trace",
3062 OPT_STRING(
'o',
"output", &output_name,
"file",
"output file name"),
3063 OPT_STRING(
'i',
"input", &
input_name,
"file",
"Analyze events in file"),
3065 "trace events on existing process id"),
3067 "trace events on existing thread id"),
3068 OPT_CALLBACK(0,
"filter-pids", &trace,
"CSV list of pids",
3071 "system-wide collection from all CPUs"),
3073 "list of cpus to monitor"),
3075 "child tasks do not inherit counters"),
3077 "number of mmap data pages",
3081 OPT_CALLBACK(0,
"duration", &trace,
"float",
3082 "show only events with duration > N.M ms",
3084 OPT_BOOLEAN(0,
"sched", &trace.
sched,
"show blocking scheduler events"),
3085 OPT_INCR(
'v',
"verbose", &
verbose,
"be more verbose"),
3086 OPT_BOOLEAN(
'T',
"time", &trace.
full_time,
3087 "Show full timestamp, not time relative to first start"),
3089 "Show only syscalls that failed"),
3091 "Show only syscall summary with statistics"),
3092 OPT_BOOLEAN(
'S',
"with-summary", &trace.
summary,
3093 "Show all syscalls and summary with statistics"),
3094 OPT_CALLBACK_DEFAULT(
'F',
"pf", &trace.
trace_pgfaults,
"all|maj|min",
3096 OPT_BOOLEAN(0,
"syscalls", &trace.
trace_syscalls,
"Trace syscalls"),
3097 OPT_BOOLEAN(
'f',
"force", &trace.
force,
"don't complain, do it"),
3098 OPT_CALLBACK(0,
"call-graph", &trace.
opts,
3102 "Show the kernel callchains on the syscall exit path"),
3103 OPT_UINTEGER(0,
"min-stack", &trace.
min_stack,
3104 "Set the minimum stack depth when parsing the callchain, " 3105 "anything below the specified depth will be ignored."),
3106 OPT_UINTEGER(0,
"max-stack", &trace.
max_stack,
3107 "Set the maximum stack depth when parsing the callchain, " 3108 "anything beyond the specified depth will be ignored. " 3109 "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)),
3111 "print the PERF_RECORD_SAMPLE PERF_SAMPLE_ info, for debugging"),
3113 "per thread proc mmap processing timeout in ms"),
3114 OPT_CALLBACK(
'G',
"cgroup", &trace,
"name",
"monitor event in cgroup name only",
3117 "ms to wait before starting measurement after program " 3121 bool __maybe_unused max_stack_user_set =
true;
3122 bool mmap_pages_user_set =
true;
3123 const char *
const trace_subcommands[] = {
"record", NULL };
3133 if (trace.
evlist == NULL || trace.
sctbl == NULL) {
3134 pr_err(
"Not enough memory to run!\n");
3139 argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
3140 trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
3143 usage_with_options_msg(trace_usage, trace_options,
3144 "cgroup monitoring only available in system-wide mode");
3150 pr_err(
"ERROR: Setup BPF stdout failed: %s\n", bf);
3162 mmap_pages_user_set =
false;
3166 max_stack_user_set =
false;
3169 #ifdef HAVE_DWARF_UNWIND_SUPPORT 3176 if (!mmap_pages_user_set && geteuid() == 0)
3185 if ((argc >= 1) && (strcmp(argv[0],
"record") == 0))
3194 pr_err(
"Please specify something to trace.\n");
3199 pr_err(
"The -e option can't be used with --no-syscalls.\n");
3203 if (output_name != NULL) {
3206 perror(
"failed to create output file");
3216 fprintf(trace.
output,
"%s", bf);
3223 fprintf(trace.
output,
"%s", bf);
3236 if (output_name != NULL)
static void * tp_field__ptr(struct tp_field *field, struct perf_sample *sample)
#define perf_evsel__sc_tp_uint(evsel, name, sample)
enum target_errno target__parse_uid(struct target *target)
static bool thread__is_filtered(struct thread *thread)
int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter)
void event_attr_init(struct perf_event_attr *attr)
static int trace__fprintf_sample(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample, struct thread *thread)
#define F_LINUX_SPECIFIC_BASE
#define STRARRAY(name, array)
static char * trace__machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
int(* tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel, union perf_event *event, struct perf_sample *sample)
int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, const char *argv[], bool pipe_output, void(*exec_error)(int signo, siginfo_t *info, void *ucontext))
int color_fprintf(FILE *fp, const char *color, const char *fmt,...)
void perf_mmap__consume(struct perf_mmap *map)
static int trace__set_filter_pids(const struct option *opt, const char *str, int unset __maybe_unused)
static const char * clockid[]
static int thread__read_fd_path(struct thread *thread, int fd)
struct event_format * trace_event__tp_format(const char *sys, const char *name)
static int trace__pgfault(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
double avg_stats(struct stats *stats)
struct perf_evlist * evlist
struct trace::@14 filter_pids
static int trace__process_event(struct trace *trace, struct machine *machine, union perf_event *event, struct perf_sample *sample)
static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
void event_format__fprintf(struct event_format *event, int cpu, void *data, int size, FILE *fp)
int bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused, int err, char *buf, size_t size)
struct trace::@12::@16 events
int machine__resolve(struct machine *machine, struct addr_location *al, struct perf_sample *sample)
static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
static int tp_field__init_uint(struct tp_field *field, struct format_field *format_field, bool needs_swap)
static const size_t trace__entry_str_size
size_t(* scnprintf)(char *bf, size_t size, struct syscall_arg *arg)
static int parse_pagefaults(const struct option *opt, const char *str, int unset __maybe_unused)
static int trace__add_syscall_newtp(struct trace *trace)
static const char * whences[]
#define resort_rb__delete(__name)
int trace_event__register_resolver(struct machine *machine, pevent_func_resolver_t *func)
int cmd_record(int argc, const char **argv)
size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg)
enum target_errno target__validate(struct target *target)
static unsigned long thread__nr_events(struct thread_trace *ttrace)
#define thread__zput(thread)
#define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine, hash_bucket)
static const char * epoll_ctl_ops[]
static int trace__validate_ev_qualifier(struct trace *trace)
int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg)
void intlist__delete(struct intlist *ilist)
void perf_evlist__enable(struct perf_evlist *evlist)
static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample, struct callchain_cursor *cursor)
static struct syscall_fmt * syscall_fmt__find(const char *name)
static bool perf_evsel__is_bpf_output(struct perf_evsel *evsel)
#define EVSEL__PRINT_UNKNOWN_AS_ADDR
size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg)
int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, struct target *target, struct thread_map *threads, perf_event__handler_t process, bool data_mmap, unsigned int proc_map_timeout, unsigned int nr_threads_synthesize)
static bool trace__filter_duration(struct trace *trace, double t)
struct ip_callchain * callchain
static size_t trace__fprintf_threads_header(FILE *fp)
size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg)
size_t(* ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)
static void trace__symbols__exit(struct trace *trace)
void machine__exit(struct machine *machine)
static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size, const char *intfmt, struct syscall_arg *arg)
static DEFINE_STRARRAY(bpf_cmd)
unsigned int proc_map_timeout
static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sample)
static struct strarray * fcntl_cmds_arrays[]
struct perf_data_file file
static struct perf_evsel * perf_evsel__new_pgfault(u64 config)
const char * tid_list_str
static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
#define perf_evsel__sc_tp_ptr(evsel, name, sample)
void perf_evsel__delete(struct perf_evsel *evsel)
void perf_evlist__delete(struct perf_evlist *evlist)
int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx)
static int trace__tool_process(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int record_opts__parse_callchain(struct record_opts *record, struct callchain_param *callchain, const char *arg, bool unset)
int perf_event__process_comm(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int perf_event__process_exit(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int perf_evlist__start_workload(struct perf_evlist *evlist)
struct thread_map * threads
static struct thread_trace * thread_trace__new(void)
double stddev_stats(struct stats *stats)
static bool target__none(struct target *target)
int machine__process_event(struct machine *machine, union perf_event *event, struct perf_sample *sample)
static size_t thread__dump_stats(struct thread_trace *ttrace, struct trace *trace, FILE *fp)
static unsigned int strlist__nr_entries(const struct strlist *slist)
static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
int perf_evlist__add_newtp(struct perf_evlist *evlist, const char *sys, const char *name, void *handler)
struct perf_evsel * sys_exit
static const char * output_name
size_t pid__scnprintf_fd(struct trace *trace, pid_t pid, int fd, char *bf, size_t size)
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
void perf_session__delete(struct perf_session *session)
int bpf__strerror_apply_obj_config(int err, char *buf, size_t size)
int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, int unset __maybe_unused)
static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
static void init_stats(struct stats *stats)
#define PERF_COLOR_NORMAL
int parse_cgroups(const struct option *opt, const char *str, int unset __maybe_unused)
static size_t syscall__scnprintf_val(struct syscall *sc, char *bf, size_t size, struct syscall_arg *arg, unsigned long val)
struct event_format * tp_format
static int trace__run(struct trace *trace, int argc, const char **argv)
static void bpf_output__fprintf(struct trace *trace, struct perf_sample *sample)
int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, unsigned int print_opts, struct callchain_cursor *cursor, FILE *fp)
int target__strerror(struct target *target, int errnum, char *buf, size_t buflen)
int path__join(char *bf, size_t size, const char *path1, const char *path2)
struct thread * machine__find_thread(struct machine *machine, pid_t pid, pid_t tid)
int perf_mmap__read_init(struct perf_mmap *map)
static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trace *trace)
const char * thread__comm_str(const struct thread *thread)
int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
#define pr_debug(fmt,...)
static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread, u64 duration, bool duration_calculated, u64 tstamp, FILE *fp)
void update_stats(struct stats *stats, u64 val)
static struct perf_session * session
static int trace__process_sample(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine __maybe_unused)
static int trace__set_filter_loop_pids(struct trace *trace)
static void sig_handler(int sig)
int perf_evlist__open(struct perf_evlist *evlist)
static void print_location(FILE *f, struct perf_sample *sample, struct addr_location *al, bool print_dso, bool print_sym)
#define evlist__for_each_entry(evlist, evsel)
int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel)
size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg)
int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, struct perf_sample *sample)
static const char * fcntl_linux_specific_cmds[]
static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1)
int is_valid_tracepoint(const char *event_string)
static int entry(u64 ip, struct unwind_info *ui)
static int trace__parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused)
static const char * socket_families[]
static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, struct syscall_arg *arg)
static char * perf_evsel__strval(struct perf_evsel *evsel, struct perf_sample *sample, const char *name)
int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
static const char * bpf_cmd[]
static struct thread_trace * thread__trace(struct thread *thread, FILE *fp)
#define perf_evsel__init_sc_tp_uint_field(evsel, name)
static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size, struct syscall_arg *arg)
#define DEFINE_STRARRAYS(array)
static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val)
struct int_node * intlist__findnew(struct intlist *ilist, int i)
struct syscalltbl * sctbl
struct event_format * tp_format
int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused, const char *syscall_glob __maybe_unused, int *idx __maybe_unused)
bool kptr_restrict_warned
static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
static int str(yyscan_t scanner, int token)
static const char * errno_to_name(struct perf_evsel *evsel, int err)
struct perf_evsel * sys_enter
const char * syscalltbl__name(const struct syscalltbl *tbl, int id)
#define strlist__for_each_entry(pos, slist)
static const char * thread__fd_path(struct thread *thread, int fd, struct trace *trace)
const char record_callchain_help[]
static const char * sighow[]
#define SCA_PKEY_ALLOC_ACCESS_RIGHTS
static struct perf_evsel * perf_evsel__syscall_newtp(const char *direction, void *handler)
struct cgroup * evlist__findnew_cgroup(struct perf_evlist *evlist, const char *name)
static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, struct syscall_arg *arg)
struct perf_evsel * perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
struct intlist * syscall_stats
int bpf__apply_obj_config(void)
int perf_evlist__set_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids)
static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel, struct tp_field *field, const char *name)
struct int_node * intlist__entry(const struct intlist *ilist, unsigned int idx)
void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
const char * pid_list_str
static void thread__update_stats(struct thread_trace *ttrace, int id, struct perf_sample *sample)
static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args)
u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample, const char *name)
struct strlist * ev_qualifier
void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts, struct callchain_param *callchain)
int cmd_trace(int argc, const char **argv)
static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
struct strarray ** entries
static int bpf_output__printer(enum binary_printer_ops op, unsigned int val, void *extra __maybe_unused, FILE *fp)
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
struct syscall_arg_fmt arg[6]
int syscalltbl__id(struct syscalltbl *tbl, const char *name)
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
const char * perf_env__arch(struct perf_env *env)
struct perf_env * perf_evsel__env(struct perf_evsel *evsel)
static void perf_evsel__delete_priv(struct perf_evsel *evsel)
#define perf_evsel__init_sc_tp_ptr_field(evsel, name)
static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
#define resort_rb__for_each_entry(__nd, __name)
static int trace__read_syscall_info(struct trace *trace, int id)
const char * perf_evsel__name(struct perf_evsel *evsel)
struct syscall_arg_fmt * arg_fmt
static struct perf_evsel * perf_evsel__new(struct perf_event_attr *attr)
struct thread_trace::@22 paths
static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, struct syscall_arg *arg)
int binary__fprintf(unsigned char *data, size_t len, size_t bytes_per_line, binary__fprintf_t printer, void *extra, FILE *fp)
static int syscall_fmt__cmp(const void *name, const void *fmtp)
void perf_mmap__read_done(struct perf_mmap *map)
struct perf_event_header header
int bpf__setup_stdout(struct perf_evlist *evlist)
struct intlist * intlist__new(const char *slist)
bool kernel_syscallchains
struct strfilter * filter
#define SCA_SECCOMP_FLAGS
static int trace__printf_interrupted_entry(struct trace *trace)
struct perf_session * perf_session__new(struct perf_data *data, bool repipe, struct perf_tool *tool)
static const char * fcntl_cmds[]
static struct perf_evsel * perf_evlist__first(struct perf_evlist *evlist)
int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused)
union perf_event * perf_mmap__read_event(struct perf_mmap *map)
void thread__put(struct thread *thread)
void cgroup__put(struct cgroup *cgrp)
void perf_evlist__disable(struct perf_evlist *evlist)
void * perf_evsel__rawptr(struct perf_evsel *evsel, struct perf_sample *sample, const char *name)
u64(* integer)(struct tp_field *field, struct perf_sample *sample)
static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel, union perf_event *event __maybe_unused, struct perf_sample *sample)
const char * arch_syscalls__strerrno(const char *arch, int err)
#define SCA_GETRANDOM_FLAGS
int perf_session__process_events(struct perf_session *session)
static struct syscall_fmt syscall_fmts[]
static size_t fprintf_duration(unsigned long t, bool calculated, FILE *fp)
void *(* pointer)(struct tp_field *field, struct perf_sample *sample)
void perf_evsel__config_callchain(struct perf_evsel *evsel, struct record_opts *opts, struct callchain_param *param)
static int trace__set_ev_qualifier_filter(struct trace *trace)
struct syscalltbl * syscalltbl__new(void)
static unsigned int intlist__nr_entries(const struct intlist *ilist)
static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size, struct syscall_arg *arg)
static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
void evlist__set_default_cgroup(struct perf_evlist *evlist, struct cgroup *cgroup)
static int trace__parse_cgroups(const struct option *opt, const char *str, int unset)
static int syscall__set_arg_fmts(struct syscall *sc)
int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
static void thread__set_filename_pos(struct thread *thread, const char *bf, unsigned long ptr)
static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, struct syscall_arg *arg)
void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, size_t(*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg))
#define TP_UINT_FIELD__SWAPPED(bits)
#define TP_UINT_FIELD(bits)
struct perf_evsel * perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, const char *name)
struct machine * machine__new_host(void)
static const char * rlimit_resources[]
struct symbol * thread__find_symbol(struct thread *thread, u8 cpumode, u64 addr, struct addr_location *al)
struct perf_header header
static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
int symbol__init(struct perf_env *env)
unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx)
static pid_t thread_map__pid(struct thread_map *map, int thread)
#define THREADS__TABLE_SIZE
struct trace::@13 ev_qualifier_ids
static size_t syscall__scnprintf_name(struct syscall *sc, char *bf, size_t size, struct syscall_arg *arg)
int machine__process_lost_event(struct machine *machine __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused)
unsigned long perf_event_mlock_kb_in_pages(void)
struct format_field * args
struct trace::@12 syscalls
static int trace__replay(struct trace *trace)
static void thread__set_priv(struct thread *thread, void *p)
struct perf_evlist * evlist
static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
int thread__resolve_callchain(struct thread *thread, struct callchain_cursor *cursor, struct perf_evsel *evsel, struct perf_sample *sample, struct symbol **parent, struct addr_location *root_al, int max_stack)
#define PERF_COLOR_YELLOW
static void trace__set_base_time(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample)
static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel, struct tp_field *field, const char *name)
static struct perf_evsel * perf_evsel__newtp(const char *sys, const char *name)
char * machine__resolve_kernel_addr(void *vmachine, unsigned long long *addrp, char **modp)
char * asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints)
static const char * itimers[]
struct thread * thread__get(struct thread *thread)
#define pr_warning(fmt,...)
static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, unsigned char *args, struct trace *trace, struct thread *thread)
int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size)
DEFINE_RESORT_RB(syscall_stats, a->msecs > b->msecs, struct stats *stats;double msecs;int syscall;)
#define perf_session__set_tracepoints_handlers(session, array)
#define SCA_WAITID_OPTIONS
static bool evsel__has_callchain(const struct perf_evsel *evsel)
static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, struct syscall_arg *arg)
struct format_field * perf_evsel__field(struct perf_evsel *evsel, const char *name)
int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct machine *machine)
static int trace__record(struct trace *trace, int argc, const char **argv)
void sighandler_dump_stack(int sig)
struct strlist * strlist__new(const char *list, const struct strlist_config *config)
#define DECLARE_RESORT_RB_INTLIST(__name, __ilist)
struct thread * machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid)
int sysctl__max_stack(void)
struct perf_evlist * perf_evlist__new(void)
struct perf_event_attr attr
struct thread_trace::@21 filename
static int trace__set_duration(const struct option *opt, const char *str, int unset __maybe_unused)
int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset)
struct timeval start end runtime
static struct syscall * trace__syscall_info(struct trace *trace, struct perf_evsel *evsel, int id)
static const char * keyctl_options[]
static void * thread__priv(struct thread *thread)
static size_t __trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
static int trace__open_output(struct trace *trace, const char *filename)
void static void * zalloc(size_t size)