1 #include <traceevent/event-parse.h>
3 #include "util/color.h"
4 #include "util/debug.h"
5 #include "util/evlist.h"
6 #include "util/exec_cmd.h"
7 #include "util/machine.h"
8 #include "util/session.h"
9 #include "util/thread.h"
10 #include "util/parse-options.h"
11 #include "util/strlist.h"
12 #include "util/intlist.h"
13 #include "util/thread_map.h"
14 #include "util/stat.h"
15 #include "trace-event.h"
16 #include "util/parse-events.h"
21 #include <linux/futex.h>
23 /* For older distros: */
25 # define MAP_STACK 0x20000
29 # define MADV_HWPOISON 100
32 #ifndef MADV_MERGEABLE
33 # define MADV_MERGEABLE 12
36 #ifndef MADV_UNMERGEABLE
37 # define MADV_UNMERGEABLE 13
41 # define EFD_SEMAPHORE 1
45 # define EFD_NONBLOCK 00004000
49 # define EFD_CLOEXEC 02000000
53 # define O_CLOEXEC 02000000
61 # define SOCK_CLOEXEC 02000000
65 # define SOCK_NONBLOCK 00004000
68 #ifndef MSG_CMSG_CLOEXEC
69 # define MSG_CMSG_CLOEXEC 0x40000000
72 #ifndef PERF_FLAG_FD_NO_GROUP
73 # define PERF_FLAG_FD_NO_GROUP (1UL << 0)
76 #ifndef PERF_FLAG_FD_OUTPUT
77 # define PERF_FLAG_FD_OUTPUT (1UL << 1)
80 #ifndef PERF_FLAG_PID_CGROUP
81 # define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */
84 #ifndef PERF_FLAG_FD_CLOEXEC
85 # define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */
92 u64 (*integer)(struct tp_field *field, struct perf_sample *sample);
93 void *(*pointer)(struct tp_field *field, struct perf_sample *sample);
97 #define TP_UINT_FIELD(bits) \
98 static u64 tp_field__u##bits(struct tp_field *field, struct perf_sample *sample) \
101 memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \
110 #define TP_UINT_FIELD__SWAPPED(bits) \
111 static u64 tp_field__swapped_u##bits(struct tp_field *field, struct perf_sample *sample) \
114 memcpy(&value, sample->raw_data + field->offset, sizeof(value)); \
115 return bswap_##bits(value);\
118 TP_UINT_FIELD__SWAPPED(16);
119 TP_UINT_FIELD__SWAPPED(32);
120 TP_UINT_FIELD__SWAPPED(64);
122 static int tp_field__init_uint(struct tp_field *field,
123 struct format_field *format_field,
126 field->offset = format_field->offset;
128 switch (format_field->size) {
130 field->integer = tp_field__u8;
133 field->integer = needs_swap ? tp_field__swapped_u16 : tp_field__u16;
136 field->integer = needs_swap ? tp_field__swapped_u32 : tp_field__u32;
139 field->integer = needs_swap ? tp_field__swapped_u64 : tp_field__u64;
148 static void *tp_field__ptr(struct tp_field *field, struct perf_sample *sample)
150 return sample->raw_data + field->offset;
153 static int tp_field__init_ptr(struct tp_field *field, struct format_field *format_field)
155 field->offset = format_field->offset;
156 field->pointer = tp_field__ptr;
163 struct tp_field args, ret;
167 static int perf_evsel__init_tp_uint_field(struct perf_evsel *evsel,
168 struct tp_field *field,
171 struct format_field *format_field = perf_evsel__field(evsel, name);
173 if (format_field == NULL)
176 return tp_field__init_uint(field, format_field, evsel->needs_swap);
179 #define perf_evsel__init_sc_tp_uint_field(evsel, name) \
180 ({ struct syscall_tp *sc = evsel->priv;\
181 perf_evsel__init_tp_uint_field(evsel, &sc->name, #name); })
183 static int perf_evsel__init_tp_ptr_field(struct perf_evsel *evsel,
184 struct tp_field *field,
187 struct format_field *format_field = perf_evsel__field(evsel, name);
189 if (format_field == NULL)
192 return tp_field__init_ptr(field, format_field);
195 #define perf_evsel__init_sc_tp_ptr_field(evsel, name) \
196 ({ struct syscall_tp *sc = evsel->priv;\
197 perf_evsel__init_tp_ptr_field(evsel, &sc->name, #name); })
199 static void perf_evsel__delete_priv(struct perf_evsel *evsel)
202 perf_evsel__delete(evsel);
205 static int perf_evsel__init_syscall_tp(struct perf_evsel *evsel, void *handler)
207 evsel->priv = malloc(sizeof(struct syscall_tp));
208 if (evsel->priv != NULL) {
209 if (perf_evsel__init_sc_tp_uint_field(evsel, id))
212 evsel->handler = handler;
223 static struct perf_evsel *perf_evsel__syscall_newtp(const char *direction, void *handler)
225 struct perf_evsel *evsel = perf_evsel__newtp("raw_syscalls", direction);
227 /* older kernel (e.g., RHEL6) use syscalls:{enter,exit} */
229 evsel = perf_evsel__newtp("syscalls", direction);
232 if (perf_evsel__init_syscall_tp(evsel, handler))
239 perf_evsel__delete_priv(evsel);
243 #define perf_evsel__sc_tp_uint(evsel, name, sample) \
244 ({ struct syscall_tp *fields = evsel->priv; \
245 fields->name.integer(&fields->name, sample); })
247 #define perf_evsel__sc_tp_ptr(evsel, name, sample) \
248 ({ struct syscall_tp *fields = evsel->priv; \
249 fields->name.pointer(&fields->name, sample); })
253 struct thread *thread;
263 const char **entries;
266 #define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \
267 .nr_entries = ARRAY_SIZE(array), \
271 #define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \
273 .nr_entries = ARRAY_SIZE(array), \
277 static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size,
279 struct syscall_arg *arg)
281 struct strarray *sa = arg->parm;
282 int idx = arg->val - sa->offset;
284 if (idx < 0 || idx >= sa->nr_entries)
285 return scnprintf(bf, size, intfmt, arg->val);
287 return scnprintf(bf, size, "%s", sa->entries[idx]);
290 static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size,
291 struct syscall_arg *arg)
293 return __syscall_arg__scnprintf_strarray(bf, size, "%d", arg);
296 #define SCA_STRARRAY syscall_arg__scnprintf_strarray
298 #if defined(__i386__) || defined(__x86_64__)
300 * FIXME: Make this available to all arches as soon as the ioctl beautifier
301 * gets rewritten to support all arches.
303 static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size,
304 struct syscall_arg *arg)
306 return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg);
309 #define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray
310 #endif /* defined(__i386__) || defined(__x86_64__) */
312 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
313 struct syscall_arg *arg);
315 #define SCA_FD syscall_arg__scnprintf_fd
317 static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size,
318 struct syscall_arg *arg)
323 return scnprintf(bf, size, "CWD");
325 return syscall_arg__scnprintf_fd(bf, size, arg);
328 #define SCA_FDAT syscall_arg__scnprintf_fd_at
330 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
331 struct syscall_arg *arg);
333 #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd
335 static size_t syscall_arg__scnprintf_hex(char *bf, size_t size,
336 struct syscall_arg *arg)
338 return scnprintf(bf, size, "%#lx", arg->val);
341 #define SCA_HEX syscall_arg__scnprintf_hex
343 static size_t syscall_arg__scnprintf_int(char *bf, size_t size,
344 struct syscall_arg *arg)
346 return scnprintf(bf, size, "%d", arg->val);
349 #define SCA_INT syscall_arg__scnprintf_int
351 static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
352 struct syscall_arg *arg)
354 int printed = 0, prot = arg->val;
356 if (prot == PROT_NONE)
357 return scnprintf(bf, size, "NONE");
358 #define P_MMAP_PROT(n) \
359 if (prot & PROT_##n) { \
360 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
370 P_MMAP_PROT(GROWSDOWN);
371 P_MMAP_PROT(GROWSUP);
375 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", prot);
380 #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot
382 static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
383 struct syscall_arg *arg)
385 int printed = 0, flags = arg->val;
387 #define P_MMAP_FLAG(n) \
388 if (flags & MAP_##n) { \
389 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
394 P_MMAP_FLAG(PRIVATE);
398 P_MMAP_FLAG(ANONYMOUS);
399 P_MMAP_FLAG(DENYWRITE);
400 P_MMAP_FLAG(EXECUTABLE);
403 P_MMAP_FLAG(GROWSDOWN);
405 P_MMAP_FLAG(HUGETLB);
408 P_MMAP_FLAG(NONBLOCK);
409 P_MMAP_FLAG(NORESERVE);
410 P_MMAP_FLAG(POPULATE);
412 #ifdef MAP_UNINITIALIZED
413 P_MMAP_FLAG(UNINITIALIZED);
418 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
423 #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags
425 static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
426 struct syscall_arg *arg)
428 int printed = 0, flags = arg->val;
430 #define P_MREMAP_FLAG(n) \
431 if (flags & MREMAP_##n) { \
432 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
433 flags &= ~MREMAP_##n; \
436 P_MREMAP_FLAG(MAYMOVE);
438 P_MREMAP_FLAG(FIXED);
443 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
448 #define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags
450 static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
451 struct syscall_arg *arg)
453 int behavior = arg->val;
456 #define P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n)
459 P_MADV_BHV(SEQUENTIAL);
460 P_MADV_BHV(WILLNEED);
461 P_MADV_BHV(DONTNEED);
463 P_MADV_BHV(DONTFORK);
465 P_MADV_BHV(HWPOISON);
466 #ifdef MADV_SOFT_OFFLINE
467 P_MADV_BHV(SOFT_OFFLINE);
469 P_MADV_BHV(MERGEABLE);
470 P_MADV_BHV(UNMERGEABLE);
472 P_MADV_BHV(HUGEPAGE);
474 #ifdef MADV_NOHUGEPAGE
475 P_MADV_BHV(NOHUGEPAGE);
478 P_MADV_BHV(DONTDUMP);
487 return scnprintf(bf, size, "%#x", behavior);
490 #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior
492 static size_t syscall_arg__scnprintf_flock(char *bf, size_t size,
493 struct syscall_arg *arg)
495 int printed = 0, op = arg->val;
498 return scnprintf(bf, size, "NONE");
500 if ((op & LOCK_##cmd) == LOCK_##cmd) { \
501 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \
516 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op);
521 #define SCA_FLOCK syscall_arg__scnprintf_flock
523 static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg)
525 enum syscall_futex_args {
526 SCF_UADDR = (1 << 0),
529 SCF_TIMEOUT = (1 << 3),
530 SCF_UADDR2 = (1 << 4),
534 int cmd = op & FUTEX_CMD_MASK;
538 #define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n);
539 P_FUTEX_OP(WAIT); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
540 P_FUTEX_OP(WAKE); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
541 P_FUTEX_OP(FD); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
542 P_FUTEX_OP(REQUEUE); arg->mask |= SCF_VAL3|SCF_TIMEOUT; break;
543 P_FUTEX_OP(CMP_REQUEUE); arg->mask |= SCF_TIMEOUT; break;
544 P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT; break;
545 P_FUTEX_OP(WAKE_OP); break;
546 P_FUTEX_OP(LOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
547 P_FUTEX_OP(UNLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break;
548 P_FUTEX_OP(TRYLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2; break;
549 P_FUTEX_OP(WAIT_BITSET); arg->mask |= SCF_UADDR2; break;
550 P_FUTEX_OP(WAKE_BITSET); arg->mask |= SCF_UADDR2; break;
551 P_FUTEX_OP(WAIT_REQUEUE_PI); break;
552 default: printed = scnprintf(bf, size, "%#x", cmd); break;
555 if (op & FUTEX_PRIVATE_FLAG)
556 printed += scnprintf(bf + printed, size - printed, "|PRIV");
558 if (op & FUTEX_CLOCK_REALTIME)
559 printed += scnprintf(bf + printed, size - printed, "|CLKRT");
564 #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op
566 static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", };
567 static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1);
569 static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", };
570 static DEFINE_STRARRAY(itimers);
572 static const char *keyctl_options[] = {
573 "GET_KEYRING_ID", "JOIN_SESSION_KEYRING", "UPDATE", "REVOKE", "CHOWN",
574 "SETPERM", "DESCRIBE", "CLEAR", "LINK", "UNLINK", "SEARCH", "READ",
575 "INSTANTIATE", "NEGATE", "SET_REQKEY_KEYRING", "SET_TIMEOUT",
576 "ASSUME_AUTHORITY", "GET_SECURITY", "SESSION_TO_PARENT", "REJECT",
577 "INSTANTIATE_IOV", "INVALIDATE", "GET_PERSISTENT",
579 static DEFINE_STRARRAY(keyctl_options);
581 static const char *whences[] = { "SET", "CUR", "END",
589 static DEFINE_STRARRAY(whences);
591 static const char *fcntl_cmds[] = {
592 "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK",
593 "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64",
594 "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX",
597 static DEFINE_STRARRAY(fcntl_cmds);
599 static const char *rlimit_resources[] = {
600 "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE",
601 "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO",
604 static DEFINE_STRARRAY(rlimit_resources);
606 static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", };
607 static DEFINE_STRARRAY(sighow);
609 static const char *clockid[] = {
610 "REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID",
611 "MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE", "BOOTTIME",
612 "REALTIME_ALARM", "BOOTTIME_ALARM", "SGI_CYCLE", "TAI"
614 static DEFINE_STRARRAY(clockid);
616 static const char *socket_families[] = {
617 "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
618 "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
619 "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
620 "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
621 "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
622 "ALG", "NFC", "VSOCK",
624 static DEFINE_STRARRAY(socket_families);
626 #ifndef SOCK_TYPE_MASK
627 #define SOCK_TYPE_MASK 0xf
630 static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
631 struct syscall_arg *arg)
635 flags = type & ~SOCK_TYPE_MASK;
637 type &= SOCK_TYPE_MASK;
639 * Can't use a strarray, MIPS may override for ABI reasons.
642 #define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
647 P_SK_TYPE(SEQPACKET);
652 printed = scnprintf(bf, size, "%#x", type);
655 #define P_SK_FLAG(n) \
656 if (flags & SOCK_##n) { \
657 printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
658 flags &= ~SOCK_##n; \
666 printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
671 #define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
674 #define MSG_PROBE 0x10
676 #ifndef MSG_WAITFORONE
677 #define MSG_WAITFORONE 0x10000
679 #ifndef MSG_SENDPAGE_NOTLAST
680 #define MSG_SENDPAGE_NOTLAST 0x20000
683 #define MSG_FASTOPEN 0x20000000
686 static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size,
687 struct syscall_arg *arg)
689 int printed = 0, flags = arg->val;
692 return scnprintf(bf, size, "NONE");
693 #define P_MSG_FLAG(n) \
694 if (flags & MSG_##n) { \
695 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
701 P_MSG_FLAG(DONTROUTE);
706 P_MSG_FLAG(DONTWAIT);
713 P_MSG_FLAG(ERRQUEUE);
714 P_MSG_FLAG(NOSIGNAL);
716 P_MSG_FLAG(WAITFORONE);
717 P_MSG_FLAG(SENDPAGE_NOTLAST);
718 P_MSG_FLAG(FASTOPEN);
719 P_MSG_FLAG(CMSG_CLOEXEC);
723 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
728 #define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags
730 static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size,
731 struct syscall_arg *arg)
736 if (mode == F_OK) /* 0 */
737 return scnprintf(bf, size, "F");
739 if (mode & n##_OK) { \
740 printed += scnprintf(bf + printed, size - printed, "%s", #n); \
750 printed += scnprintf(bf + printed, size - printed, "|%#x", mode);
755 #define SCA_ACCMODE syscall_arg__scnprintf_access_mode
757 static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
758 struct syscall_arg *arg);
760 #define SCA_FILENAME syscall_arg__scnprintf_filename
762 static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size,
763 struct syscall_arg *arg)
765 int printed = 0, flags = arg->val;
767 if (!(flags & O_CREAT))
768 arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */
771 return scnprintf(bf, size, "RDONLY");
773 if (flags & O_##n) { \
774 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
798 if ((flags & O_SYNC) == O_SYNC)
799 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC");
811 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
816 #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags
818 static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size,
819 struct syscall_arg *arg)
821 int printed = 0, flags = arg->val;
827 if (flags & PERF_FLAG_##n) { \
828 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
829 flags &= ~PERF_FLAG_##n; \
839 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
844 #define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags
846 static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size,
847 struct syscall_arg *arg)
849 int printed = 0, flags = arg->val;
852 return scnprintf(bf, size, "NONE");
854 if (flags & EFD_##n) { \
855 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
865 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
870 #define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags
872 static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
873 struct syscall_arg *arg)
875 int printed = 0, flags = arg->val;
878 if (flags & O_##n) { \
879 printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \
888 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);
893 #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags
895 static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg)
900 #define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n)
943 return scnprintf(bf, size, "%#x", sig);
946 #define SCA_SIGNUM syscall_arg__scnprintf_signum
948 #if defined(__i386__) || defined(__x86_64__)
950 * FIXME: Make this available to all arches.
952 #define TCGETS 0x5401
954 static const char *tioctls[] = {
955 "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW",
956 "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL",
957 "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI",
958 "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC",
959 "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX",
960 "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO",
961 "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK",
962 "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2",
963 "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK",
964 "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG",
965 "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL",
966 [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG",
967 "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS",
968 "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI",
969 "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE",
972 static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401);
973 #endif /* defined(__i386__) || defined(__x86_64__) */
975 #define STRARRAY(arg, name, array) \
976 .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \
977 .arg_parm = { [arg] = &strarray__##array, }
979 static struct syscall_fmt {
982 size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg);
988 { .name = "access", .errmsg = true,
989 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */
990 [1] = SCA_ACCMODE, /* mode */ }, },
991 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
992 { .name = "brk", .hexret = true,
993 .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, },
994 { .name = "chdir", .errmsg = true,
995 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
996 { .name = "chmod", .errmsg = true,
997 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
998 { .name = "chroot", .errmsg = true,
999 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1000 { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), },
1001 { .name = "close", .errmsg = true,
1002 .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, },
1003 { .name = "connect", .errmsg = true, },
1004 { .name = "creat", .errmsg = true,
1005 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1006 { .name = "dup", .errmsg = true,
1007 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1008 { .name = "dup2", .errmsg = true,
1009 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1010 { .name = "dup3", .errmsg = true,
1011 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1012 { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), },
1013 { .name = "eventfd2", .errmsg = true,
1014 .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, },
1015 { .name = "faccessat", .errmsg = true,
1016 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1017 [1] = SCA_FILENAME, /* filename */ }, },
1018 { .name = "fadvise64", .errmsg = true,
1019 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1020 { .name = "fallocate", .errmsg = true,
1021 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1022 { .name = "fchdir", .errmsg = true,
1023 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1024 { .name = "fchmod", .errmsg = true,
1025 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1026 { .name = "fchmodat", .errmsg = true,
1027 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1028 [1] = SCA_FILENAME, /* filename */ }, },
1029 { .name = "fchown", .errmsg = true,
1030 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1031 { .name = "fchownat", .errmsg = true,
1032 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1033 [1] = SCA_FILENAME, /* filename */ }, },
1034 { .name = "fcntl", .errmsg = true,
1035 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1036 [1] = SCA_STRARRAY, /* cmd */ },
1037 .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, },
1038 { .name = "fdatasync", .errmsg = true,
1039 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1040 { .name = "flock", .errmsg = true,
1041 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1042 [1] = SCA_FLOCK, /* cmd */ }, },
1043 { .name = "fsetxattr", .errmsg = true,
1044 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1045 { .name = "fstat", .errmsg = true, .alias = "newfstat",
1046 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1047 { .name = "fstatat", .errmsg = true, .alias = "newfstatat",
1048 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1049 [1] = SCA_FILENAME, /* filename */ }, },
1050 { .name = "fstatfs", .errmsg = true,
1051 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1052 { .name = "fsync", .errmsg = true,
1053 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1054 { .name = "ftruncate", .errmsg = true,
1055 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1056 { .name = "futex", .errmsg = true,
1057 .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, },
1058 { .name = "futimesat", .errmsg = true,
1059 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1060 [1] = SCA_FILENAME, /* filename */ }, },
1061 { .name = "getdents", .errmsg = true,
1062 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1063 { .name = "getdents64", .errmsg = true,
1064 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1065 { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), },
1066 { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1067 { .name = "getxattr", .errmsg = true,
1068 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1069 { .name = "inotify_add_watch", .errmsg = true,
1070 .arg_scnprintf = { [1] = SCA_FILENAME, /* pathname */ }, },
1071 { .name = "ioctl", .errmsg = true,
1072 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1073 #if defined(__i386__) || defined(__x86_64__)
1075 * FIXME: Make this available to all arches.
1077 [1] = SCA_STRHEXARRAY, /* cmd */
1078 [2] = SCA_HEX, /* arg */ },
1079 .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, },
1081 [2] = SCA_HEX, /* arg */ }, },
1083 { .name = "keyctl", .errmsg = true, STRARRAY(0, option, keyctl_options), },
1084 { .name = "kill", .errmsg = true,
1085 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1086 { .name = "lchown", .errmsg = true,
1087 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1088 { .name = "lgetxattr", .errmsg = true,
1089 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1090 { .name = "linkat", .errmsg = true,
1091 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, },
1092 { .name = "listxattr", .errmsg = true,
1093 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1094 { .name = "llistxattr", .errmsg = true,
1095 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1096 { .name = "lremovexattr", .errmsg = true,
1097 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1098 { .name = "lseek", .errmsg = true,
1099 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1100 [2] = SCA_STRARRAY, /* whence */ },
1101 .arg_parm = { [2] = &strarray__whences, /* whence */ }, },
1102 { .name = "lsetxattr", .errmsg = true,
1103 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1104 { .name = "lstat", .errmsg = true, .alias = "newlstat",
1105 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1106 { .name = "lsxattr", .errmsg = true,
1107 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1108 { .name = "madvise", .errmsg = true,
1109 .arg_scnprintf = { [0] = SCA_HEX, /* start */
1110 [2] = SCA_MADV_BHV, /* behavior */ }, },
1111 { .name = "mkdir", .errmsg = true,
1112 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1113 { .name = "mkdirat", .errmsg = true,
1114 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1115 [1] = SCA_FILENAME, /* pathname */ }, },
1116 { .name = "mknod", .errmsg = true,
1117 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1118 { .name = "mknodat", .errmsg = true,
1119 .arg_scnprintf = { [0] = SCA_FDAT, /* fd */
1120 [1] = SCA_FILENAME, /* filename */ }, },
1121 { .name = "mlock", .errmsg = true,
1122 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1123 { .name = "mlockall", .errmsg = true,
1124 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1125 { .name = "mmap", .hexret = true,
1126 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
1127 [2] = SCA_MMAP_PROT, /* prot */
1128 [3] = SCA_MMAP_FLAGS, /* flags */
1129 [4] = SCA_FD, /* fd */ }, },
1130 { .name = "mprotect", .errmsg = true,
1131 .arg_scnprintf = { [0] = SCA_HEX, /* start */
1132 [2] = SCA_MMAP_PROT, /* prot */ }, },
1133 { .name = "mq_unlink", .errmsg = true,
1134 .arg_scnprintf = { [0] = SCA_FILENAME, /* u_name */ }, },
1135 { .name = "mremap", .hexret = true,
1136 .arg_scnprintf = { [0] = SCA_HEX, /* addr */
1137 [3] = SCA_MREMAP_FLAGS, /* flags */
1138 [4] = SCA_HEX, /* new_addr */ }, },
1139 { .name = "munlock", .errmsg = true,
1140 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1141 { .name = "munmap", .errmsg = true,
1142 .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, },
1143 { .name = "name_to_handle_at", .errmsg = true,
1144 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1145 { .name = "newfstatat", .errmsg = true,
1146 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1147 [1] = SCA_FILENAME, /* filename */ }, },
1148 { .name = "open", .errmsg = true,
1149 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */
1150 [1] = SCA_OPEN_FLAGS, /* flags */ }, },
1151 { .name = "open_by_handle_at", .errmsg = true,
1152 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1153 [2] = SCA_OPEN_FLAGS, /* flags */ }, },
1154 { .name = "openat", .errmsg = true,
1155 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1156 [1] = SCA_FILENAME, /* filename */
1157 [2] = SCA_OPEN_FLAGS, /* flags */ }, },
1158 { .name = "perf_event_open", .errmsg = true,
1159 .arg_scnprintf = { [1] = SCA_INT, /* pid */
1160 [2] = SCA_INT, /* cpu */
1161 [3] = SCA_FD, /* group_fd */
1162 [4] = SCA_PERF_FLAGS, /* flags */ }, },
1163 { .name = "pipe2", .errmsg = true,
1164 .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, },
1165 { .name = "poll", .errmsg = true, .timeout = true, },
1166 { .name = "ppoll", .errmsg = true, .timeout = true, },
1167 { .name = "pread", .errmsg = true, .alias = "pread64",
1168 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1169 { .name = "preadv", .errmsg = true, .alias = "pread",
1170 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1171 { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), },
1172 { .name = "pwrite", .errmsg = true, .alias = "pwrite64",
1173 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1174 { .name = "pwritev", .errmsg = true,
1175 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1176 { .name = "read", .errmsg = true,
1177 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1178 { .name = "readlink", .errmsg = true,
1179 .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
1180 { .name = "readlinkat", .errmsg = true,
1181 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1182 [1] = SCA_FILENAME, /* pathname */ }, },
1183 { .name = "readv", .errmsg = true,
1184 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1185 { .name = "recvfrom", .errmsg = true,
1186 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1187 [3] = SCA_MSG_FLAGS, /* flags */ }, },
1188 { .name = "recvmmsg", .errmsg = true,
1189 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1190 [3] = SCA_MSG_FLAGS, /* flags */ }, },
1191 { .name = "recvmsg", .errmsg = true,
1192 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1193 [2] = SCA_MSG_FLAGS, /* flags */ }, },
1194 { .name = "removexattr", .errmsg = true,
1195 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1196 { .name = "renameat", .errmsg = true,
1197 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1198 { .name = "rmdir", .errmsg = true,
1199 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1200 { .name = "rt_sigaction", .errmsg = true,
1201 .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, },
1202 { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), },
1203 { .name = "rt_sigqueueinfo", .errmsg = true,
1204 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1205 { .name = "rt_tgsigqueueinfo", .errmsg = true,
1206 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
1207 { .name = "select", .errmsg = true, .timeout = true, },
1208 { .name = "sendmmsg", .errmsg = true,
1209 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1210 [3] = SCA_MSG_FLAGS, /* flags */ }, },
1211 { .name = "sendmsg", .errmsg = true,
1212 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1213 [2] = SCA_MSG_FLAGS, /* flags */ }, },
1214 { .name = "sendto", .errmsg = true,
1215 .arg_scnprintf = { [0] = SCA_FD, /* fd */
1216 [3] = SCA_MSG_FLAGS, /* flags */ }, },
1217 { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), },
1218 { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), },
1219 { .name = "setxattr", .errmsg = true,
1220 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1221 { .name = "shutdown", .errmsg = true,
1222 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1223 { .name = "socket", .errmsg = true,
1224 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
1225 [1] = SCA_SK_TYPE, /* type */ },
1226 .arg_parm = { [0] = &strarray__socket_families, /* family */ }, },
1227 { .name = "socketpair", .errmsg = true,
1228 .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */
1229 [1] = SCA_SK_TYPE, /* type */ },
1230 .arg_parm = { [0] = &strarray__socket_families, /* family */ }, },
1231 { .name = "stat", .errmsg = true, .alias = "newstat",
1232 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1233 { .name = "statfs", .errmsg = true,
1234 .arg_scnprintf = { [0] = SCA_FILENAME, /* pathname */ }, },
1235 { .name = "swapoff", .errmsg = true,
1236 .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, },
1237 { .name = "swapon", .errmsg = true,
1238 .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, },
1239 { .name = "symlinkat", .errmsg = true,
1240 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, },
1241 { .name = "tgkill", .errmsg = true,
1242 .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, },
1243 { .name = "tkill", .errmsg = true,
1244 .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, },
1245 { .name = "truncate", .errmsg = true,
1246 .arg_scnprintf = { [0] = SCA_FILENAME, /* path */ }, },
1247 { .name = "uname", .errmsg = true, .alias = "newuname", },
1248 { .name = "unlinkat", .errmsg = true,
1249 .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */
1250 [1] = SCA_FILENAME, /* pathname */ }, },
1251 { .name = "utime", .errmsg = true,
1252 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1253 { .name = "utimensat", .errmsg = true,
1254 .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */
1255 [1] = SCA_FILENAME, /* filename */ }, },
1256 { .name = "utimes", .errmsg = true,
1257 .arg_scnprintf = { [0] = SCA_FILENAME, /* filename */ }, },
1258 { .name = "vmsplice", .errmsg = true,
1259 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1260 { .name = "write", .errmsg = true,
1261 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1262 { .name = "writev", .errmsg = true,
1263 .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, },
1266 static int syscall_fmt__cmp(const void *name, const void *fmtp)
1268 const struct syscall_fmt *fmt = fmtp;
1269 return strcmp(name, fmt->name);
1272 static struct syscall_fmt *syscall_fmt__find(const char *name)
1274 const int nmemb = ARRAY_SIZE(syscall_fmts);
1275 return bsearch(name, syscall_fmts, nmemb, sizeof(struct syscall_fmt), syscall_fmt__cmp);
1279 struct event_format *tp_format;
1281 struct format_field *args;
1284 struct syscall_fmt *fmt;
1285 size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg);
1289 static size_t fprintf_duration(unsigned long t, FILE *fp)
1291 double duration = (double)t / NSEC_PER_MSEC;
1292 size_t printed = fprintf(fp, "(");
1294 if (duration >= 1.0)
1295 printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
1296 else if (duration >= 0.01)
1297 printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
1299 printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
1300 return printed + fprintf(fp, "): ");
1304 * filename.ptr: The filename char pointer that will be vfs_getname'd
1305 * filename.entry_str_pos: Where to insert the string translated from
1306 * filename.ptr by the vfs_getname tracepoint/kprobe.
1308 struct thread_trace {
1312 unsigned long nr_events;
1313 unsigned long pfmaj, pfmin;
1325 struct intlist *syscall_stats;
1328 static struct thread_trace *thread_trace__new(void)
1330 struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace));
1333 ttrace->paths.max = -1;
1335 ttrace->syscall_stats = intlist__new(NULL);
1340 static struct thread_trace *thread__trace(struct thread *thread, FILE *fp)
1342 struct thread_trace *ttrace;
1347 if (thread__priv(thread) == NULL)
1348 thread__set_priv(thread, thread_trace__new());
1350 if (thread__priv(thread) == NULL)
1353 ttrace = thread__priv(thread);
1354 ++ttrace->nr_events;
1358 color_fprintf(fp, PERF_COLOR_RED,
1359 "WARNING: not enough memory, dropping samples!\n");
1363 #define TRACE_PFMAJ (1 << 0)
1364 #define TRACE_PFMIN (1 << 1)
1366 static const size_t trace__entry_str_size = 2048;
1369 struct perf_tool tool;
1376 struct syscall *table;
1378 struct perf_evsel *sys_enter,
1382 struct record_opts opts;
1383 struct perf_evlist *evlist;
1384 struct machine *host;
1385 struct thread *current;
1388 unsigned long nr_events;
1389 struct strlist *ev_qualifier;
1394 const char *last_vfs_getname;
1395 struct intlist *tid_list;
1396 struct intlist *pid_list;
1401 double duration_filter;
1407 bool not_ev_qualifier;
1411 bool multiple_threads;
1415 bool show_tool_stats;
1416 bool trace_syscalls;
1422 static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname)
1424 struct thread_trace *ttrace = thread__priv(thread);
1426 if (fd > ttrace->paths.max) {
1427 char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *));
1432 if (ttrace->paths.max != -1) {
1433 memset(npath + ttrace->paths.max + 1, 0,
1434 (fd - ttrace->paths.max) * sizeof(char *));
1436 memset(npath, 0, (fd + 1) * sizeof(char *));
1439 ttrace->paths.table = npath;
1440 ttrace->paths.max = fd;
1443 ttrace->paths.table[fd] = strdup(pathname);
1445 return ttrace->paths.table[fd] != NULL ? 0 : -1;
1448 static int thread__read_fd_path(struct thread *thread, int fd)
1450 char linkname[PATH_MAX], pathname[PATH_MAX];
1454 if (thread->pid_ == thread->tid) {
1455 scnprintf(linkname, sizeof(linkname),
1456 "/proc/%d/fd/%d", thread->pid_, fd);
1458 scnprintf(linkname, sizeof(linkname),
1459 "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd);
1462 if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname))
1465 ret = readlink(linkname, pathname, sizeof(pathname));
1467 if (ret < 0 || ret > st.st_size)
1470 pathname[ret] = '\0';
1471 return trace__set_fd_pathname(thread, fd, pathname);
1474 static const char *thread__fd_path(struct thread *thread, int fd,
1475 struct trace *trace)
1477 struct thread_trace *ttrace = thread__priv(thread);
1485 if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) {
1488 ++trace->stats.proc_getname;
1489 if (thread__read_fd_path(thread, fd))
1493 return ttrace->paths.table[fd];
1496 static size_t syscall_arg__scnprintf_fd(char *bf, size_t size,
1497 struct syscall_arg *arg)
1500 size_t printed = scnprintf(bf, size, "%d", fd);
1501 const char *path = thread__fd_path(arg->thread, fd, arg->trace);
1504 printed += scnprintf(bf + printed, size - printed, "<%s>", path);
1509 static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size,
1510 struct syscall_arg *arg)
1513 size_t printed = syscall_arg__scnprintf_fd(bf, size, arg);
1514 struct thread_trace *ttrace = thread__priv(arg->thread);
1516 if (ttrace && fd >= 0 && fd <= ttrace->paths.max)
1517 zfree(&ttrace->paths.table[fd]);
1522 static void thread__set_filename_pos(struct thread *thread, const char *bf,
1525 struct thread_trace *ttrace = thread__priv(thread);
1527 ttrace->filename.ptr = ptr;
1528 ttrace->filename.entry_str_pos = bf - ttrace->entry_str;
1531 static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
1532 struct syscall_arg *arg)
1534 unsigned long ptr = arg->val;
1536 if (!arg->trace->vfs_getname)
1537 return scnprintf(bf, size, "%#x", ptr);
1539 thread__set_filename_pos(arg->thread, bf, ptr);
1543 static bool trace__filter_duration(struct trace *trace, double t)
1545 return t < (trace->duration_filter * NSEC_PER_MSEC);
1548 static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
1550 double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
1552 return fprintf(fp, "%10.3f ", ts);
1555 static bool done = false;
1556 static bool interrupted = false;
1558 static void sig_handler(int sig)
1561 interrupted = sig == SIGINT;
1564 static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
1565 u64 duration, u64 tstamp, FILE *fp)
1567 size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
1568 printed += fprintf_duration(duration, fp);
1570 if (trace->multiple_threads) {
1571 if (trace->show_comm)
1572 printed += fprintf(fp, "%.14s/", thread__comm_str(thread));
1573 printed += fprintf(fp, "%d ", thread->tid);
1579 static int trace__process_event(struct trace *trace, struct machine *machine,
1580 union perf_event *event, struct perf_sample *sample)
1584 switch (event->header.type) {
1585 case PERF_RECORD_LOST:
1586 color_fprintf(trace->output, PERF_COLOR_RED,
1587 "LOST %" PRIu64 " events!\n", event->lost.lost);
1588 ret = machine__process_lost_event(machine, event, sample);
1590 ret = machine__process_event(machine, event, sample);
1597 static int trace__tool_process(struct perf_tool *tool,
1598 union perf_event *event,
1599 struct perf_sample *sample,
1600 struct machine *machine)
1602 struct trace *trace = container_of(tool, struct trace, tool);
1603 return trace__process_event(trace, machine, event, sample);
1606 static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
1608 int err = symbol__init(NULL);
1613 trace->host = machine__new_host();
1614 if (trace->host == NULL)
1617 if (trace_event__register_resolver(trace->host, machine__resolve_kernel_addr) < 0)
1620 err = __machine__synthesize_threads(trace->host, &trace->tool, &trace->opts.target,
1621 evlist->threads, trace__tool_process, false,
1622 trace->opts.proc_map_timeout);
1629 static int syscall__set_arg_fmts(struct syscall *sc)
1631 struct format_field *field;
1634 sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
1635 if (sc->arg_scnprintf == NULL)
1639 sc->arg_parm = sc->fmt->arg_parm;
1641 for (field = sc->args; field; field = field->next) {
1642 if (sc->fmt && sc->fmt->arg_scnprintf[idx])
1643 sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
1644 else if (field->flags & FIELD_IS_POINTER)
1645 sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex;
1652 static int trace__read_syscall_info(struct trace *trace, int id)
1656 const char *name = audit_syscall_to_name(id, trace->audit.machine);
1661 if (id > trace->syscalls.max) {
1662 struct syscall *nsyscalls = realloc(trace->syscalls.table, (id + 1) * sizeof(*sc));
1664 if (nsyscalls == NULL)
1667 if (trace->syscalls.max != -1) {
1668 memset(nsyscalls + trace->syscalls.max + 1, 0,
1669 (id - trace->syscalls.max) * sizeof(*sc));
1671 memset(nsyscalls, 0, (id + 1) * sizeof(*sc));
1674 trace->syscalls.table = nsyscalls;
1675 trace->syscalls.max = id;
1678 sc = trace->syscalls.table + id;
1681 sc->fmt = syscall_fmt__find(sc->name);
1683 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->name);
1684 sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1686 if (sc->tp_format == NULL && sc->fmt && sc->fmt->alias) {
1687 snprintf(tp_name, sizeof(tp_name), "sys_enter_%s", sc->fmt->alias);
1688 sc->tp_format = trace_event__tp_format("syscalls", tp_name);
1691 if (sc->tp_format == NULL)
1694 sc->args = sc->tp_format->format.fields;
1695 sc->nr_args = sc->tp_format->format.nr_fields;
1696 /* drop nr field - not relevant here; does not exist on older kernels */
1697 if (sc->args && strcmp(sc->args->name, "nr") == 0) {
1698 sc->args = sc->args->next;
1702 sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
1704 return syscall__set_arg_fmts(sc);
1707 static int trace__validate_ev_qualifier(struct trace *trace)
1710 struct str_node *pos;
1712 trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier);
1713 trace->ev_qualifier_ids.entries = malloc(trace->ev_qualifier_ids.nr *
1714 sizeof(trace->ev_qualifier_ids.entries[0]));
1716 if (trace->ev_qualifier_ids.entries == NULL) {
1717 fputs("Error:\tNot enough memory for allocating events qualifier ids\n",
1725 strlist__for_each(pos, trace->ev_qualifier) {
1726 const char *sc = pos->s;
1727 int id = audit_name_to_syscall(sc, trace->audit.machine);
1731 fputs("Error:\tInvalid syscall ", trace->output);
1734 fputs(", ", trace->output);
1737 fputs(sc, trace->output);
1740 trace->ev_qualifier_ids.entries[i++] = id;
1744 fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'"
1745 "\nHint:\tand: 'man syscalls'\n", trace->output);
1746 zfree(&trace->ev_qualifier_ids.entries);
1747 trace->ev_qualifier_ids.nr = 0;
1754 * args is to be interpreted as a series of longs but we need to handle
1755 * 8-byte unaligned accesses. args points to raw_data within the event
1756 * and raw_data is guaranteed to be 8-byte unaligned because it is
1757 * preceded by raw_size which is a u32. So we need to copy args to a temp
1758 * variable to read it. Most notably this avoids extended load instructions
1759 * on unaligned addresses
1762 static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
1763 unsigned char *args, struct trace *trace,
1764 struct thread *thread)
1770 if (sc->args != NULL) {
1771 struct format_field *field;
1773 struct syscall_arg arg = {
1780 for (field = sc->args; field;
1781 field = field->next, ++arg.idx, bit <<= 1) {
1785 /* special care for unaligned accesses */
1786 p = args + sizeof(unsigned long) * arg.idx;
1787 memcpy(&val, p, sizeof(val));
1790 * Suppress this argument if its value is zero and
1791 * and we don't have a string associated in an
1795 !(sc->arg_scnprintf &&
1796 sc->arg_scnprintf[arg.idx] == SCA_STRARRAY &&
1797 sc->arg_parm[arg.idx]))
1800 printed += scnprintf(bf + printed, size - printed,
1801 "%s%s: ", printed ? ", " : "", field->name);
1802 if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) {
1805 arg.parm = sc->arg_parm[arg.idx];
1806 printed += sc->arg_scnprintf[arg.idx](bf + printed,
1807 size - printed, &arg);
1809 printed += scnprintf(bf + printed, size - printed,
1817 /* special care for unaligned accesses */
1818 p = args + sizeof(unsigned long) * i;
1819 memcpy(&val, p, sizeof(val));
1820 printed += scnprintf(bf + printed, size - printed,
1822 printed ? ", " : "", i, val);
1830 typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
1831 union perf_event *event,
1832 struct perf_sample *sample);
1834 static struct syscall *trace__syscall_info(struct trace *trace,
1835 struct perf_evsel *evsel, int id)
1841 * XXX: Noticed on x86_64, reproduced as far back as 3.0.36, haven't tried
1842 * before that, leaving at a higher verbosity level till that is
1843 * explained. Reproduced with plain ftrace with:
1845 * echo 1 > /t/events/raw_syscalls/sys_exit/enable
1846 * grep "NR -1 " /t/trace_pipe
1848 * After generating some load on the machine.
1852 fprintf(trace->output, "Invalid syscall %d id, skipping (%s, %" PRIu64 ") ...\n",
1853 id, perf_evsel__name(evsel), ++n);
1858 if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
1859 trace__read_syscall_info(trace, id))
1862 if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
1865 return &trace->syscalls.table[id];
1869 fprintf(trace->output, "Problems reading syscall %d", id);
1870 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
1871 fprintf(trace->output, "(%s)", trace->syscalls.table[id].name);
1872 fputs(" information\n", trace->output);
1877 static void thread__update_stats(struct thread_trace *ttrace,
1878 int id, struct perf_sample *sample)
1880 struct int_node *inode;
1881 struct stats *stats;
1884 inode = intlist__findnew(ttrace->syscall_stats, id);
1888 stats = inode->priv;
1889 if (stats == NULL) {
1890 stats = malloc(sizeof(struct stats));
1894 inode->priv = stats;
1897 if (ttrace->entry_time && sample->time > ttrace->entry_time)
1898 duration = sample->time - ttrace->entry_time;
1900 update_stats(stats, duration);
1903 static int trace__printf_interrupted_entry(struct trace *trace, struct perf_sample *sample)
1905 struct thread_trace *ttrace;
1909 if (trace->current == NULL)
1912 ttrace = thread__priv(trace->current);
1914 if (!ttrace->entry_pending)
1917 duration = sample->time - ttrace->entry_time;
1919 printed = trace__fprintf_entry_head(trace, trace->current, duration, sample->time, trace->output);
1920 printed += fprintf(trace->output, "%-70s) ...\n", ttrace->entry_str);
1921 ttrace->entry_pending = false;
1926 static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
1927 union perf_event *event __maybe_unused,
1928 struct perf_sample *sample)
1933 struct thread *thread;
1934 int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
1935 struct syscall *sc = trace__syscall_info(trace, evsel, id);
1936 struct thread_trace *ttrace;
1941 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1942 ttrace = thread__trace(thread, trace->output);
1946 args = perf_evsel__sc_tp_ptr(evsel, args, sample);
1948 if (ttrace->entry_str == NULL) {
1949 ttrace->entry_str = malloc(trace__entry_str_size);
1950 if (!ttrace->entry_str)
1954 if (!trace->summary_only)
1955 trace__printf_interrupted_entry(trace, sample);
1957 ttrace->entry_time = sample->time;
1958 msg = ttrace->entry_str;
1959 printed += scnprintf(msg + printed, trace__entry_str_size - printed, "%s(", sc->name);
1961 printed += syscall__scnprintf_args(sc, msg + printed, trace__entry_str_size - printed,
1962 args, trace, thread);
1965 if (!trace->duration_filter && !trace->summary_only) {
1966 trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
1967 fprintf(trace->output, "%-70s\n", ttrace->entry_str);
1970 ttrace->entry_pending = true;
1972 if (trace->current != thread) {
1973 thread__put(trace->current);
1974 trace->current = thread__get(thread);
1978 thread__put(thread);
1982 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
1983 union perf_event *event __maybe_unused,
1984 struct perf_sample *sample)
1988 struct thread *thread;
1989 int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
1990 struct syscall *sc = trace__syscall_info(trace, evsel, id);
1991 struct thread_trace *ttrace;
1996 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
1997 ttrace = thread__trace(thread, trace->output);
2002 thread__update_stats(ttrace, id, sample);
2004 ret = perf_evsel__sc_tp_uint(evsel, ret, sample);
2006 if (id == trace->audit.open_id && ret >= 0 && trace->last_vfs_getname) {
2007 trace__set_fd_pathname(thread, ret, trace->last_vfs_getname);
2008 trace->last_vfs_getname = NULL;
2009 ++trace->stats.vfs_getname;
2012 ttrace->exit_time = sample->time;
2014 if (ttrace->entry_time) {
2015 duration = sample->time - ttrace->entry_time;
2016 if (trace__filter_duration(trace, duration))
2018 } else if (trace->duration_filter)
2021 if (trace->summary_only)
2024 trace__fprintf_entry_head(trace, thread, duration, sample->time, trace->output);
2026 if (ttrace->entry_pending) {
2027 fprintf(trace->output, "%-70s", ttrace->entry_str);
2029 fprintf(trace->output, " ... [");
2030 color_fprintf(trace->output, PERF_COLOR_YELLOW, "continued");
2031 fprintf(trace->output, "]: %s()", sc->name);
2034 if (sc->fmt == NULL) {
2036 fprintf(trace->output, ") = %ld", ret);
2037 } else if (ret < 0 && sc->fmt->errmsg) {
2038 char bf[STRERR_BUFSIZE];
2039 const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
2040 *e = audit_errno_to_name(-ret);
2042 fprintf(trace->output, ") = -1 %s %s", e, emsg);
2043 } else if (ret == 0 && sc->fmt->timeout)
2044 fprintf(trace->output, ") = 0 Timeout");
2045 else if (sc->fmt->hexret)
2046 fprintf(trace->output, ") = %#lx", ret);
2050 fputc('\n', trace->output);
2052 ttrace->entry_pending = false;
2055 thread__put(thread);
2059 static int trace__vfs_getname(struct trace *trace, struct perf_evsel *evsel,
2060 union perf_event *event __maybe_unused,
2061 struct perf_sample *sample)
2063 struct thread *thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
2064 struct thread_trace *ttrace;
2065 size_t filename_len, entry_str_len, to_move;
2066 ssize_t remaining_space;
2068 const char *filename;
2070 trace->last_vfs_getname = perf_evsel__rawptr(evsel, sample, "pathname");
2075 ttrace = thread__priv(thread);
2079 if (!ttrace->filename.ptr)
2082 entry_str_len = strlen(ttrace->entry_str);
2083 remaining_space = trace__entry_str_size - entry_str_len - 1; /* \0 */
2084 if (remaining_space <= 0)
2087 filename = trace->last_vfs_getname;
2088 filename_len = strlen(filename);
2089 if (filename_len > (size_t)remaining_space) {
2090 filename += filename_len - remaining_space;
2091 filename_len = remaining_space;
2094 to_move = entry_str_len - ttrace->filename.entry_str_pos + 1; /* \0 */
2095 pos = ttrace->entry_str + ttrace->filename.entry_str_pos;
2096 memmove(pos + filename_len, pos, to_move);
2097 memcpy(pos, filename, filename_len);
2099 ttrace->filename.ptr = 0;
2100 ttrace->filename.entry_str_pos = 0;
2105 static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel,
2106 union perf_event *event __maybe_unused,
2107 struct perf_sample *sample)
2109 u64 runtime = perf_evsel__intval(evsel, sample, "runtime");
2110 double runtime_ms = (double)runtime / NSEC_PER_MSEC;
2111 struct thread *thread = machine__findnew_thread(trace->host,
2114 struct thread_trace *ttrace = thread__trace(thread, trace->output);
2119 ttrace->runtime_ms += runtime_ms;
2120 trace->runtime_ms += runtime_ms;
2121 thread__put(thread);
2125 fprintf(trace->output, "%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n",
2127 perf_evsel__strval(evsel, sample, "comm"),
2128 (pid_t)perf_evsel__intval(evsel, sample, "pid"),
2130 perf_evsel__intval(evsel, sample, "vruntime"));
2131 thread__put(thread);
2135 static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
2136 union perf_event *event __maybe_unused,
2137 struct perf_sample *sample)
2139 trace__printf_interrupted_entry(trace, sample);
2140 trace__fprintf_tstamp(trace, sample->time, trace->output);
2142 if (trace->trace_syscalls)
2143 fprintf(trace->output, "( ): ");
2145 fprintf(trace->output, "%s:", evsel->name);
2147 if (evsel->tp_format) {
2148 event_format__fprintf(evsel->tp_format, sample->cpu,
2149 sample->raw_data, sample->raw_size,
2153 fprintf(trace->output, ")\n");
2157 static void print_location(FILE *f, struct perf_sample *sample,
2158 struct addr_location *al,
2159 bool print_dso, bool print_sym)
2162 if ((verbose || print_dso) && al->map)
2163 fprintf(f, "%s@", al->map->dso->long_name);
2165 if ((verbose || print_sym) && al->sym)
2166 fprintf(f, "%s+0x%" PRIx64, al->sym->name,
2167 al->addr - al->sym->start);
2169 fprintf(f, "0x%" PRIx64, al->addr);
2171 fprintf(f, "0x%" PRIx64, sample->addr);
2174 static int trace__pgfault(struct trace *trace,
2175 struct perf_evsel *evsel,
2176 union perf_event *event,
2177 struct perf_sample *sample)
2179 struct thread *thread;
2180 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
2181 struct addr_location al;
2182 char map_type = 'd';
2183 struct thread_trace *ttrace;
2186 thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
2187 ttrace = thread__trace(thread, trace->output);
2191 if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
2196 if (trace->summary_only)
2199 thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
2202 trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output);
2204 fprintf(trace->output, "%sfault [",
2205 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ?
2208 print_location(trace->output, sample, &al, false, true);
2210 fprintf(trace->output, "] => ");
2212 thread__find_addr_location(thread, cpumode, MAP__VARIABLE,
2216 thread__find_addr_location(thread, cpumode,
2217 MAP__FUNCTION, sample->addr, &al);
2225 print_location(trace->output, sample, &al, true, false);
2227 fprintf(trace->output, " (%c%c)\n", map_type, al.level);
2231 thread__put(thread);
2235 static bool skip_sample(struct trace *trace, struct perf_sample *sample)
2237 if ((trace->pid_list && intlist__find(trace->pid_list, sample->pid)) ||
2238 (trace->tid_list && intlist__find(trace->tid_list, sample->tid)))
2241 if (trace->pid_list || trace->tid_list)
2247 static int trace__process_sample(struct perf_tool *tool,
2248 union perf_event *event,
2249 struct perf_sample *sample,
2250 struct perf_evsel *evsel,
2251 struct machine *machine __maybe_unused)
2253 struct trace *trace = container_of(tool, struct trace, tool);
2256 tracepoint_handler handler = evsel->handler;
2258 if (skip_sample(trace, sample))
2261 if (!trace->full_time && trace->base_time == 0)
2262 trace->base_time = sample->time;
2266 handler(trace, evsel, event, sample);
2272 static int parse_target_str(struct trace *trace)
2274 if (trace->opts.target.pid) {
2275 trace->pid_list = intlist__new(trace->opts.target.pid);
2276 if (trace->pid_list == NULL) {
2277 pr_err("Error parsing process id string\n");
2282 if (trace->opts.target.tid) {
2283 trace->tid_list = intlist__new(trace->opts.target.tid);
2284 if (trace->tid_list == NULL) {
2285 pr_err("Error parsing thread id string\n");
2293 static int trace__record(struct trace *trace, int argc, const char **argv)
2295 unsigned int rec_argc, i, j;
2296 const char **rec_argv;
2297 const char * const record_args[] = {
2304 const char * const sc_args[] = { "-e", };
2305 unsigned int sc_args_nr = ARRAY_SIZE(sc_args);
2306 const char * const majpf_args[] = { "-e", "major-faults" };
2307 unsigned int majpf_args_nr = ARRAY_SIZE(majpf_args);
2308 const char * const minpf_args[] = { "-e", "minor-faults" };
2309 unsigned int minpf_args_nr = ARRAY_SIZE(minpf_args);
2311 /* +1 is for the event string below */
2312 rec_argc = ARRAY_SIZE(record_args) + sc_args_nr + 1 +
2313 majpf_args_nr + minpf_args_nr + argc;
2314 rec_argv = calloc(rec_argc + 1, sizeof(char *));
2316 if (rec_argv == NULL)
2320 for (i = 0; i < ARRAY_SIZE(record_args); i++)
2321 rec_argv[j++] = record_args[i];
2323 if (trace->trace_syscalls) {
2324 for (i = 0; i < sc_args_nr; i++)
2325 rec_argv[j++] = sc_args[i];
2327 /* event string may be different for older kernels - e.g., RHEL6 */
2328 if (is_valid_tracepoint("raw_syscalls:sys_enter"))
2329 rec_argv[j++] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit";
2330 else if (is_valid_tracepoint("syscalls:sys_enter"))
2331 rec_argv[j++] = "syscalls:sys_enter,syscalls:sys_exit";
2333 pr_err("Neither raw_syscalls nor syscalls events exist.\n");
2338 if (trace->trace_pgfaults & TRACE_PFMAJ)
2339 for (i = 0; i < majpf_args_nr; i++)
2340 rec_argv[j++] = majpf_args[i];
2342 if (trace->trace_pgfaults & TRACE_PFMIN)
2343 for (i = 0; i < minpf_args_nr; i++)
2344 rec_argv[j++] = minpf_args[i];
2346 for (i = 0; i < (unsigned int)argc; i++)
2347 rec_argv[j++] = argv[i];
2349 return cmd_record(j, rec_argv, NULL);
2352 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp);
2354 static bool perf_evlist__add_vfs_getname(struct perf_evlist *evlist)
2356 struct perf_evsel *evsel = perf_evsel__newtp("probe", "vfs_getname");
2360 if (perf_evsel__field(evsel, "pathname") == NULL) {
2361 perf_evsel__delete(evsel);
2365 evsel->handler = trace__vfs_getname;
2366 perf_evlist__add(evlist, evsel);
2370 static int perf_evlist__add_pgfault(struct perf_evlist *evlist,
2373 struct perf_evsel *evsel;
2374 struct perf_event_attr attr = {
2375 .type = PERF_TYPE_SOFTWARE,
2379 attr.config = config;
2380 attr.sample_period = 1;
2382 event_attr_init(&attr);
2384 evsel = perf_evsel__new(&attr);
2388 evsel->handler = trace__pgfault;
2389 perf_evlist__add(evlist, evsel);
2394 static void trace__handle_event(struct trace *trace, union perf_event *event, struct perf_sample *sample)
2396 const u32 type = event->header.type;
2397 struct perf_evsel *evsel;
2399 if (!trace->full_time && trace->base_time == 0)
2400 trace->base_time = sample->time;
2402 if (type != PERF_RECORD_SAMPLE) {
2403 trace__process_event(trace, trace->host, event, sample);
2407 evsel = perf_evlist__id2evsel(trace->evlist, sample->id);
2408 if (evsel == NULL) {
2409 fprintf(trace->output, "Unknown tp ID %" PRIu64 ", skipping...\n", sample->id);
2413 if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
2414 sample->raw_data == NULL) {
2415 fprintf(trace->output, "%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
2416 perf_evsel__name(evsel), sample->tid,
2417 sample->cpu, sample->raw_size);
2419 tracepoint_handler handler = evsel->handler;
2420 handler(trace, evsel, event, sample);
2424 static int trace__add_syscall_newtp(struct trace *trace)
2427 struct perf_evlist *evlist = trace->evlist;
2428 struct perf_evsel *sys_enter, *sys_exit;
2430 sys_enter = perf_evsel__syscall_newtp("sys_enter", trace__sys_enter);
2431 if (sys_enter == NULL)
2434 if (perf_evsel__init_sc_tp_ptr_field(sys_enter, args))
2435 goto out_delete_sys_enter;
2437 sys_exit = perf_evsel__syscall_newtp("sys_exit", trace__sys_exit);
2438 if (sys_exit == NULL)
2439 goto out_delete_sys_enter;
2441 if (perf_evsel__init_sc_tp_uint_field(sys_exit, ret))
2442 goto out_delete_sys_exit;
2444 perf_evlist__add(evlist, sys_enter);
2445 perf_evlist__add(evlist, sys_exit);
2447 trace->syscalls.events.sys_enter = sys_enter;
2448 trace->syscalls.events.sys_exit = sys_exit;
2454 out_delete_sys_exit:
2455 perf_evsel__delete_priv(sys_exit);
2456 out_delete_sys_enter:
2457 perf_evsel__delete_priv(sys_enter);
2461 static int trace__set_ev_qualifier_filter(struct trace *trace)
2464 char *filter = asprintf_expr_inout_ints("id", !trace->not_ev_qualifier,
2465 trace->ev_qualifier_ids.nr,
2466 trace->ev_qualifier_ids.entries);
2471 if (!perf_evsel__append_filter(trace->syscalls.events.sys_enter, "&&", filter))
2472 err = perf_evsel__append_filter(trace->syscalls.events.sys_exit, "&&", filter);
2482 static int trace__run(struct trace *trace, int argc, const char **argv)
2484 struct perf_evlist *evlist = trace->evlist;
2485 struct perf_evsel *evsel;
2487 unsigned long before;
2488 const bool forks = argc > 0;
2489 bool draining = false;
2493 if (trace->trace_syscalls && trace__add_syscall_newtp(trace))
2494 goto out_error_raw_syscalls;
2496 if (trace->trace_syscalls)
2497 trace->vfs_getname = perf_evlist__add_vfs_getname(evlist);
2499 if ((trace->trace_pgfaults & TRACE_PFMAJ) &&
2500 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ)) {
2504 if ((trace->trace_pgfaults & TRACE_PFMIN) &&
2505 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MIN))
2509 perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime",
2510 trace__sched_stat_runtime))
2511 goto out_error_sched_stat_runtime;
2513 err = perf_evlist__create_maps(evlist, &trace->opts.target);
2515 fprintf(trace->output, "Problems parsing the target to trace, check your options!\n");
2516 goto out_delete_evlist;
2519 err = trace__symbols_init(trace, evlist);
2521 fprintf(trace->output, "Problems initializing symbol libraries!\n");
2522 goto out_delete_evlist;
2525 perf_evlist__config(evlist, &trace->opts);
2527 signal(SIGCHLD, sig_handler);
2528 signal(SIGINT, sig_handler);
2531 err = perf_evlist__prepare_workload(evlist, &trace->opts.target,
2534 fprintf(trace->output, "Couldn't run the workload!\n");
2535 goto out_delete_evlist;
2539 err = perf_evlist__open(evlist);
2541 goto out_error_open;
2544 * Better not use !target__has_task() here because we need to cover the
2545 * case where no threads were specified in the command line, but a
2546 * workload was, and in that case we will fill in the thread_map when
2547 * we fork the workload in perf_evlist__prepare_workload.
2549 if (trace->filter_pids.nr > 0)
2550 err = perf_evlist__set_filter_pids(evlist, trace->filter_pids.nr, trace->filter_pids.entries);
2551 else if (thread_map__pid(evlist->threads, 0) == -1)
2552 err = perf_evlist__set_filter_pid(evlist, getpid());
2557 if (trace->ev_qualifier_ids.nr > 0) {
2558 err = trace__set_ev_qualifier_filter(trace);
2562 pr_debug("event qualifier tracepoint filter: %s\n",
2563 trace->syscalls.events.sys_exit->filter);
2566 err = perf_evlist__apply_filters(evlist, &evsel);
2568 goto out_error_apply_filters;
2570 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
2572 goto out_error_mmap;
2574 if (!target__none(&trace->opts.target))
2575 perf_evlist__enable(evlist);
2578 perf_evlist__start_workload(evlist);
2580 trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 ||
2581 evlist->threads->nr > 1 ||
2582 perf_evlist__first(evlist)->attr.inherit;
2584 before = trace->nr_events;
2586 for (i = 0; i < evlist->nr_mmaps; i++) {
2587 union perf_event *event;
2589 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
2590 struct perf_sample sample;
2594 err = perf_evlist__parse_sample(evlist, event, &sample);
2596 fprintf(trace->output, "Can't parse sample, err = %d, skipping...\n", err);
2600 trace__handle_event(trace, event, &sample);
2602 perf_evlist__mmap_consume(evlist, i);
2607 if (done && !draining) {
2608 perf_evlist__disable(evlist);
2614 if (trace->nr_events == before) {
2615 int timeout = done ? 100 : -1;
2617 if (!draining && perf_evlist__poll(evlist, timeout) > 0) {
2618 if (perf_evlist__filter_pollfd(evlist, POLLERR | POLLHUP) == 0)
2628 thread__zput(trace->current);
2630 perf_evlist__disable(evlist);
2634 trace__fprintf_thread_summary(trace, trace->output);
2636 if (trace->show_tool_stats) {
2637 fprintf(trace->output, "Stats:\n "
2638 " vfs_getname : %" PRIu64 "\n"
2639 " proc_getname: %" PRIu64 "\n",
2640 trace->stats.vfs_getname,
2641 trace->stats.proc_getname);
2646 perf_evlist__delete(evlist);
2647 trace->evlist = NULL;
2648 trace->live = false;
2651 char errbuf[BUFSIZ];
2653 out_error_sched_stat_runtime:
2654 debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "sched", "sched_stat_runtime");
2657 out_error_raw_syscalls:
2658 debugfs__strerror_open_tp(errno, errbuf, sizeof(errbuf), "raw_syscalls", "sys_(enter|exit)");
2662 perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf));
2666 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
2669 fprintf(trace->output, "%s\n", errbuf);
2670 goto out_delete_evlist;
2672 out_error_apply_filters:
2673 fprintf(trace->output,
2674 "Failed to set filter \"%s\" on event %s with %d (%s)\n",
2675 evsel->filter, perf_evsel__name(evsel), errno,
2676 strerror_r(errno, errbuf, sizeof(errbuf)));
2677 goto out_delete_evlist;
2680 fprintf(trace->output, "Not enough memory to run!\n");
2681 goto out_delete_evlist;
2684 fprintf(trace->output, "errno=%d,%s\n", errno, strerror(errno));
2685 goto out_delete_evlist;
2688 static int trace__replay(struct trace *trace)
2690 const struct perf_evsel_str_handler handlers[] = {
2691 { "probe:vfs_getname", trace__vfs_getname, },
2693 struct perf_data_file file = {
2695 .mode = PERF_DATA_MODE_READ,
2696 .force = trace->force,
2698 struct perf_session *session;
2699 struct perf_evsel *evsel;
2702 trace->tool.sample = trace__process_sample;
2703 trace->tool.mmap = perf_event__process_mmap;
2704 trace->tool.mmap2 = perf_event__process_mmap2;
2705 trace->tool.comm = perf_event__process_comm;
2706 trace->tool.exit = perf_event__process_exit;
2707 trace->tool.fork = perf_event__process_fork;
2708 trace->tool.attr = perf_event__process_attr;
2709 trace->tool.tracing_data = perf_event__process_tracing_data;
2710 trace->tool.build_id = perf_event__process_build_id;
2712 trace->tool.ordered_events = true;
2713 trace->tool.ordering_requires_timestamps = true;
2715 /* add tid to output */
2716 trace->multiple_threads = true;
2718 session = perf_session__new(&file, false, &trace->tool);
2719 if (session == NULL)
2722 if (symbol__init(&session->header.env) < 0)
2725 trace->host = &session->machines.host;
2727 err = perf_session__set_tracepoints_handlers(session, handlers);
2731 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2732 "raw_syscalls:sys_enter");
2733 /* older kernels have syscalls tp versus raw_syscalls */
2735 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2736 "syscalls:sys_enter");
2739 (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
2740 perf_evsel__init_sc_tp_ptr_field(evsel, args))) {
2741 pr_err("Error during initialize raw_syscalls:sys_enter event\n");
2745 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2746 "raw_syscalls:sys_exit");
2748 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2749 "syscalls:sys_exit");
2751 (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
2752 perf_evsel__init_sc_tp_uint_field(evsel, ret))) {
2753 pr_err("Error during initialize raw_syscalls:sys_exit event\n");
2757 evlist__for_each(session->evlist, evsel) {
2758 if (evsel->attr.type == PERF_TYPE_SOFTWARE &&
2759 (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ ||
2760 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MIN ||
2761 evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS))
2762 evsel->handler = trace__pgfault;
2765 err = parse_target_str(trace);
2771 err = perf_session__process_events(session);
2773 pr_err("Failed to process events, error %d", err);
2775 else if (trace->summary)
2776 trace__fprintf_thread_summary(trace, trace->output);
2779 perf_session__delete(session);
2784 static size_t trace__fprintf_threads_header(FILE *fp)
2788 printed = fprintf(fp, "\n Summary of events:\n\n");
2793 static size_t thread__dump_stats(struct thread_trace *ttrace,
2794 struct trace *trace, FILE *fp)
2796 struct stats *stats;
2799 struct int_node *inode = intlist__first(ttrace->syscall_stats);
2804 printed += fprintf(fp, "\n");
2806 printed += fprintf(fp, " syscall calls total min avg max stddev\n");
2807 printed += fprintf(fp, " (msec) (msec) (msec) (msec) (%%)\n");
2808 printed += fprintf(fp, " --------------- -------- --------- --------- --------- --------- ------\n");
2810 /* each int_node is a syscall */
2812 stats = inode->priv;
2814 double min = (double)(stats->min) / NSEC_PER_MSEC;
2815 double max = (double)(stats->max) / NSEC_PER_MSEC;
2816 double avg = avg_stats(stats);
2818 u64 n = (u64) stats->n;
2820 pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0;
2821 avg /= NSEC_PER_MSEC;
2823 sc = &trace->syscalls.table[inode->i];
2824 printed += fprintf(fp, " %-15s", sc->name);
2825 printed += fprintf(fp, " %8" PRIu64 " %9.3f %9.3f %9.3f",
2826 n, avg * n, min, avg);
2827 printed += fprintf(fp, " %9.3f %9.2f%%\n", max, pct);
2830 inode = intlist__next(inode);
2833 printed += fprintf(fp, "\n\n");
2838 /* struct used to pass data to per-thread function */
2839 struct summary_data {
2841 struct trace *trace;
2845 static int trace__fprintf_one_thread(struct thread *thread, void *priv)
2847 struct summary_data *data = priv;
2848 FILE *fp = data->fp;
2849 size_t printed = data->printed;
2850 struct trace *trace = data->trace;
2851 struct thread_trace *ttrace = thread__priv(thread);
2857 ratio = (double)ttrace->nr_events / trace->nr_events * 100.0;
2859 printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
2860 printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
2861 printed += fprintf(fp, "%.1f%%", ratio);
2863 printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
2865 printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
2866 printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
2867 printed += thread__dump_stats(ttrace, trace, fp);
2869 data->printed += printed;
2874 static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp)
2876 struct summary_data data = {
2880 data.printed = trace__fprintf_threads_header(fp);
2882 machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data);
2884 return data.printed;
2887 static int trace__set_duration(const struct option *opt, const char *str,
2888 int unset __maybe_unused)
2890 struct trace *trace = opt->value;
2892 trace->duration_filter = atof(str);
2896 static int trace__set_filter_pids(const struct option *opt, const char *str,
2897 int unset __maybe_unused)
2901 struct trace *trace = opt->value;
2903 * FIXME: introduce a intarray class, plain parse csv and create a
2904 * { int nr, int entries[] } struct...
2906 struct intlist *list = intlist__new(str);
2911 i = trace->filter_pids.nr = intlist__nr_entries(list) + 1;
2912 trace->filter_pids.entries = calloc(i, sizeof(pid_t));
2914 if (trace->filter_pids.entries == NULL)
2917 trace->filter_pids.entries[0] = getpid();
2919 for (i = 1; i < trace->filter_pids.nr; ++i)
2920 trace->filter_pids.entries[i] = intlist__entry(list, i - 1)->i;
2922 intlist__delete(list);
2928 static int trace__open_output(struct trace *trace, const char *filename)
2932 if (!stat(filename, &st) && st.st_size) {
2933 char oldname[PATH_MAX];
2935 scnprintf(oldname, sizeof(oldname), "%s.old", filename);
2937 rename(filename, oldname);
2940 trace->output = fopen(filename, "w");
2942 return trace->output == NULL ? -errno : 0;
2945 static int parse_pagefaults(const struct option *opt, const char *str,
2946 int unset __maybe_unused)
2948 int *trace_pgfaults = opt->value;
2950 if (strcmp(str, "all") == 0)
2951 *trace_pgfaults |= TRACE_PFMAJ | TRACE_PFMIN;
2952 else if (strcmp(str, "maj") == 0)
2953 *trace_pgfaults |= TRACE_PFMAJ;
2954 else if (strcmp(str, "min") == 0)
2955 *trace_pgfaults |= TRACE_PFMIN;
2962 static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
2964 struct perf_evsel *evsel;
2966 evlist__for_each(evlist, evsel)
2967 evsel->handler = handler;
2970 int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2972 const char *trace_usage[] = {
2973 "perf trace [<options>] [<command>]",
2974 "perf trace [<options>] -- <command> [<options>]",
2975 "perf trace record [<options>] [<command>]",
2976 "perf trace record [<options>] -- <command> [<options>]",
2979 struct trace trace = {
2981 .machine = audit_detect_machine(),
2982 .open_id = audit_name_to_syscall("open", trace.audit.machine),
2992 .user_freq = UINT_MAX,
2993 .user_interval = ULLONG_MAX,
2994 .no_buffering = true,
2995 .mmap_pages = UINT_MAX,
2996 .proc_map_timeout = 500,
3000 .trace_syscalls = true,
3002 const char *output_name = NULL;
3003 const char *ev_qualifier_str = NULL;
3004 const struct option trace_options[] = {
3005 OPT_CALLBACK(0, "event", &trace.evlist, "event",
3006 "event selector. use 'perf list' to list available events",
3007 parse_events_option),
3008 OPT_BOOLEAN(0, "comm", &trace.show_comm,
3009 "show the thread COMM next to its id"),
3010 OPT_BOOLEAN(0, "tool_stats", &trace.show_tool_stats, "show tool stats"),
3011 OPT_STRING('e', "expr", &ev_qualifier_str, "expr", "list of syscalls to trace"),
3012 OPT_STRING('o', "output", &output_name, "file", "output file name"),
3013 OPT_STRING('i', "input", &input_name, "file", "Analyze events in file"),
3014 OPT_STRING('p', "pid", &trace.opts.target.pid, "pid",
3015 "trace events on existing process id"),
3016 OPT_STRING('t', "tid", &trace.opts.target.tid, "tid",
3017 "trace events on existing thread id"),
3018 OPT_CALLBACK(0, "filter-pids", &trace, "CSV list of pids",
3019 "pids to filter (by the kernel)", trace__set_filter_pids),
3020 OPT_BOOLEAN('a', "all-cpus", &trace.opts.target.system_wide,
3021 "system-wide collection from all CPUs"),
3022 OPT_STRING('C', "cpu", &trace.opts.target.cpu_list, "cpu",
3023 "list of cpus to monitor"),
3024 OPT_BOOLEAN(0, "no-inherit", &trace.opts.no_inherit,
3025 "child tasks do not inherit counters"),
3026 OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages",
3027 "number of mmap data pages",
3028 perf_evlist__parse_mmap_pages),
3029 OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user",
3031 OPT_CALLBACK(0, "duration", &trace, "float",
3032 "show only events with duration > N.M ms",
3033 trace__set_duration),
3034 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"),
3035 OPT_INCR('v', "verbose", &verbose, "be more verbose"),
3036 OPT_BOOLEAN('T', "time", &trace.full_time,
3037 "Show full timestamp, not time relative to first start"),
3038 OPT_BOOLEAN('s', "summary", &trace.summary_only,
3039 "Show only syscall summary with statistics"),
3040 OPT_BOOLEAN('S', "with-summary", &trace.summary,
3041 "Show all syscalls and summary with statistics"),
3042 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
3043 "Trace pagefaults", parse_pagefaults, "maj"),
3044 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
3045 OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
3046 OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
3047 "per thread proc mmap processing timeout in ms"),
3050 const char * const trace_subcommands[] = { "record", NULL };
3054 signal(SIGSEGV, sighandler_dump_stack);
3055 signal(SIGFPE, sighandler_dump_stack);
3057 trace.evlist = perf_evlist__new();
3059 if (trace.evlist == NULL) {
3060 pr_err("Not enough memory to run!\n");
3065 argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
3066 trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
3068 if (trace.trace_pgfaults) {
3069 trace.opts.sample_address = true;
3070 trace.opts.sample_time = true;
3073 if (trace.evlist->nr_entries > 0)
3074 evlist__set_evsel_handler(trace.evlist, trace__event_handler);
3076 if ((argc >= 1) && (strcmp(argv[0], "record") == 0))
3077 return trace__record(&trace, argc-1, &argv[1]);
3079 /* summary_only implies summary option, but don't overwrite summary if set */
3080 if (trace.summary_only)
3081 trace.summary = trace.summary_only;
3083 if (!trace.trace_syscalls && !trace.trace_pgfaults &&
3084 trace.evlist->nr_entries == 0 /* Was --events used? */) {
3085 pr_err("Please specify something to trace.\n");
3089 if (output_name != NULL) {
3090 err = trace__open_output(&trace, output_name);
3092 perror("failed to create output file");
3097 if (ev_qualifier_str != NULL) {
3098 const char *s = ev_qualifier_str;
3099 struct strlist_config slist_config = {
3100 .dirname = system_path(STRACE_GROUPS_DIR),
3103 trace.not_ev_qualifier = *s == '!';
3104 if (trace.not_ev_qualifier)
3106 trace.ev_qualifier = strlist__new(s, &slist_config);
3107 if (trace.ev_qualifier == NULL) {
3108 fputs("Not enough memory to parse event qualifier",
3114 err = trace__validate_ev_qualifier(&trace);
3119 err = target__validate(&trace.opts.target);
3121 target__strerror(&trace.opts.target, err, bf, sizeof(bf));
3122 fprintf(trace.output, "%s", bf);
3126 err = target__parse_uid(&trace.opts.target);
3128 target__strerror(&trace.opts.target, err, bf, sizeof(bf));
3129 fprintf(trace.output, "%s", bf);
3133 if (!argc && target__none(&trace.opts.target))
3134 trace.opts.target.system_wide = true;
3137 err = trace__replay(&trace);
3139 err = trace__run(&trace, argc, argv);
3142 if (output_name != NULL)
3143 fclose(trace.output);