From 536b8250cd6860353b6976c34d5f6a118ee0e74e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Mon, 12 Jul 2021 19:13:11 +0200 Subject: [PATCH 1/5] Add --syscalls option (linux only) --- Cargo.toml | 4 + src/config.rs | 24 ++- src/python_spy.rs | 423 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 450 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a428d91f..1c987524 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,10 @@ license = "MIT" build="build.rs" edition="2018" +[features] +default = ["trace_syscalls"] +trace_syscalls = [] + [dependencies] clap = {version="2", features=["wrap_help"]} console = "0.15" diff --git a/src/config.rs b/src/config.rs index a50f4a4d..d4c42605 100644 --- a/src/config.rs +++ b/src/config.rs @@ -52,6 +52,8 @@ pub struct Config { pub full_filenames: bool, #[doc(hidden)] pub lineno: LineNo, + #[doc(hidden)] + pub trace_syscalls: bool, } arg_enum!{ @@ -95,7 +97,7 @@ impl Default for Config { duration: RecordDuration::Unlimited, native: false, gil_only: false, include_idle: false, include_thread_ids: false, hide_progress: false, capture_output: true, dump_json: false, dump_locals: 0, subprocesses: false, - full_filenames: false, lineno: LineNo::LastInstruction } + full_filenames: false, lineno: LineNo::LastInstruction, trace_syscalls: false} } } @@ -121,6 +123,11 @@ impl Config { .short("n") .long("native") .help("Collect stack traces from native extensions written in Cython, C or C++"); + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + let trace_syscalls = Arg::with_name("trace_syscalls") + .short("S") + .long("syscalls") + .help("Collect syscall traces (Linux only)"); #[cfg(not(target_os="freebsd"))] let nonblocking = Arg::with_name("nonblocking") @@ -249,6 +256,14 @@ impl Config { #[cfg(unwind)] let dump = dump.arg(native.clone()); + // add syscall traces if appropiate + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + let record = record.arg(trace_syscalls.clone()); + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + let top = top.arg(trace_syscalls.clone()); + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + let dump = dump.arg(trace_syscalls.clone()); + // Nonblocking isn't an option for freebsd, remove #[cfg(not(target_os="freebsd"))] let record = record.arg(nonblocking.clone()); @@ -307,6 +322,13 @@ impl Config { config.include_idle = matches.occurrences_of("idle") > 0; config.gil_only = matches.occurrences_of("gil") > 0; config.include_thread_ids = matches.occurrences_of("threads") > 0; + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + { + config.trace_syscalls = matches.occurrences_of("trace_syscalls") > 0; + if config.trace_syscalls { + config.include_idle = true; + } + } config.native = matches.occurrences_of("native") > 0; config.hide_progress = matches.occurrences_of("hideprogress") > 0; diff --git a/src/python_spy.rs b/src/python_spy.rs index d3ce67a5..bbf32f27 100644 --- a/src/python_spy.rs +++ b/src/python_spy.rs @@ -17,6 +17,400 @@ use remoteprocess::{Process, ProcessMemory, Pid, Tid}; use proc_maps::{get_process_maps, MapRange}; +#[cfg(all(target_os = "linux", feature = "trace_syscalls"))] +lazy_static! { + static ref SYSCALLS: HashMap = { + let mut m = HashMap::new(); + m.insert(0, "read"); + m.insert(1, "write"); + m.insert(2, "open"); + m.insert(3, "close"); + m.insert(4, "stat"); + m.insert(5, "fstat"); + m.insert(6, "lstat"); + m.insert(7, "poll"); + m.insert(8, "lseek"); + m.insert(9, "mmap"); + m.insert(10, "mprotect"); + m.insert(11, "munmap"); + m.insert(12, "brk"); + m.insert(13, "rt_sigaction"); + m.insert(14, "rt_sigprocmask"); + m.insert(15, "rt_sigreturn"); + m.insert(16, "ioctl"); + m.insert(17, "pread64"); + m.insert(18, "pwrite64"); + m.insert(19, "readv"); + m.insert(20, "writev"); + m.insert(21, "access"); + m.insert(22, "pipe"); + m.insert(23, "select"); + m.insert(24, "sched_yield"); + m.insert(25, "mremap"); + m.insert(26, "msync"); + m.insert(27, "mincore"); + m.insert(28, "madvise"); + m.insert(29, "shmget"); + m.insert(30, "shmat"); + m.insert(31, "shmctl"); + m.insert(32, "dup"); + m.insert(33, "dup2"); + m.insert(34, "pause"); + m.insert(35, "nanosleep"); + m.insert(36, "getitimer"); + m.insert(37, "alarm"); + m.insert(38, "setitimer"); + m.insert(39, "getpid"); + m.insert(40, "sendfile"); + m.insert(41, "socket"); + m.insert(42, "connect"); + m.insert(43, "accept"); + m.insert(44, "sendto"); + m.insert(45, "recvfrom"); + m.insert(46, "sendmsg"); + m.insert(47, "recvmsg"); + m.insert(48, "shutdown"); + m.insert(49, "bind"); + m.insert(50, "listen"); + m.insert(51, "getsockname"); + m.insert(52, "getpeername"); + m.insert(53, "socketpair"); + m.insert(54, "setsockopt"); + m.insert(55, "getsockopt"); + m.insert(56, "clone"); + m.insert(57, "fork"); + m.insert(58, "vfork"); + m.insert(59, "execve"); + m.insert(60, "exit"); + m.insert(61, "wait4"); + m.insert(62, "kill"); + m.insert(63, "uname"); + m.insert(64, "semget"); + m.insert(65, "semop"); + m.insert(66, "semctl"); + m.insert(67, "shmdt"); + m.insert(68, "msgget"); + m.insert(69, "msgsnd"); + m.insert(70, "msgrcv"); + m.insert(71, "msgctl"); + m.insert(72, "fcntl"); + m.insert(73, "flock"); + m.insert(74, "fsync"); + m.insert(75, "fdatasync"); + m.insert(76, "truncate"); + m.insert(77, "ftruncate"); + m.insert(78, "getdents"); + m.insert(79, "getcwd"); + m.insert(80, "chdir"); + m.insert(81, "fchdir"); + m.insert(82, "rename"); + m.insert(83, "mkdir"); + m.insert(84, "rmdir"); + m.insert(85, "creat"); + m.insert(86, "link"); + m.insert(87, "unlink"); + m.insert(88, "symlink"); + m.insert(89, "readlink"); + m.insert(90, "chmod"); + m.insert(91, "fchmod"); + m.insert(92, "chown"); + m.insert(93, "fchown"); + m.insert(94, "lchown"); + m.insert(95, "umask"); + m.insert(96, "gettimeofday"); + m.insert(97, "getrlimit"); + m.insert(98, "getrusage"); + m.insert(99, "sysinfo"); + m.insert(100, "times"); + m.insert(101, "ptrace"); + m.insert(102, "getuid"); + m.insert(103, "syslog"); + m.insert(104, "getgid"); + m.insert(105, "setuid"); + m.insert(106, "setgid"); + m.insert(107, "geteuid"); + m.insert(108, "getegid"); + m.insert(109, "setpgid"); + m.insert(110, "getppid"); + m.insert(111, "getpgrp"); + m.insert(112, "setsid"); + m.insert(113, "setreuid"); + m.insert(114, "setregid"); + m.insert(115, "getgroups"); + m.insert(116, "setgroups"); + m.insert(117, "setresuid"); + m.insert(118, "getresuid"); + m.insert(119, "setresgid"); + m.insert(120, "getresgid"); + m.insert(121, "getpgid"); + m.insert(122, "setfsuid"); + m.insert(123, "setfsgid"); + m.insert(124, "getsid"); + m.insert(125, "capget"); + m.insert(126, "capset"); + m.insert(127, "rt_sigpending"); + m.insert(128, "rt_sigtimedwait"); + m.insert(129, "rt_sigqueueinfo"); + m.insert(130, "rt_sigsuspend"); + m.insert(131, "sigaltstack"); + m.insert(132, "utime"); + m.insert(133, "mknod"); + m.insert(134, "uselib"); + m.insert(135, "personality"); + m.insert(136, "ustat"); + m.insert(137, "statfs"); + m.insert(138, "fstatfs"); + m.insert(139, "sysfs"); + m.insert(140, "getpriority"); + m.insert(141, "setpriority"); + m.insert(142, "sched_setparam"); + m.insert(143, "sched_getparam"); + m.insert(144, "sched_setscheduler"); + m.insert(145, "sched_getscheduler"); + m.insert(146, "sched_get_priority_max"); + m.insert(147, "sched_get_priority_min"); + m.insert(148, "sched_rr_get_interval"); + m.insert(149, "mlock"); + m.insert(150, "munlock"); + m.insert(151, "mlockall"); + m.insert(152, "munlockall"); + m.insert(153, "vhangup"); + m.insert(154, "modify_ldt"); + m.insert(155, "pivot_root"); + m.insert(156, "_sysctl"); + m.insert(157, "prctl"); + m.insert(158, "arch_prctl"); + m.insert(159, "adjtimex"); + m.insert(160, "setrlimit"); + m.insert(161, "chroot"); + m.insert(162, "sync"); + m.insert(163, "acct"); + m.insert(164, "settimeofday"); + m.insert(165, "mount"); + m.insert(166, "umount2"); + m.insert(167, "swapon"); + m.insert(168, "swapoff"); + m.insert(169, "reboot"); + m.insert(170, "sethostname"); + m.insert(171, "setdomainname"); + m.insert(172, "iopl"); + m.insert(173, "ioperm"); + m.insert(174, "create_module"); + m.insert(175, "init_module"); + m.insert(176, "delete_module"); + m.insert(177, "get_kernel_syms"); + m.insert(178, "query_module"); + m.insert(179, "quotactl"); + m.insert(180, "nfsservctl"); + m.insert(181, "getpmsg"); + m.insert(182, "putpmsg"); + m.insert(183, "afs_syscall"); + m.insert(184, "tuxcall"); + m.insert(185, "security"); + m.insert(186, "gettid"); + m.insert(187, "readahead"); + m.insert(188, "setxattr"); + m.insert(189, "lsetxattr"); + m.insert(190, "fsetxattr"); + m.insert(191, "getxattr"); + m.insert(192, "lgetxattr"); + m.insert(193, "fgetxattr"); + m.insert(194, "listxattr"); + m.insert(195, "llistxattr"); + m.insert(196, "flistxattr"); + m.insert(197, "removexattr"); + m.insert(198, "lremovexattr"); + m.insert(199, "fremovexattr"); + m.insert(200, "tkill"); + m.insert(201, "time"); + m.insert(202, "futex"); + m.insert(203, "sched_setaffinity"); + m.insert(204, "sched_getaffinity"); + m.insert(205, "set_thread_area"); + m.insert(206, "io_setup"); + m.insert(207, "io_destroy"); + m.insert(208, "io_getevents"); + m.insert(209, "io_submit"); + m.insert(210, "io_cancel"); + m.insert(211, "get_thread_area"); + m.insert(212, "lookup_dcookie"); + m.insert(213, "epoll_create"); + m.insert(214, "epoll_ctl_old"); + m.insert(215, "epoll_wait_old"); + m.insert(216, "remap_file_pages"); + m.insert(217, "getdents64"); + m.insert(218, "set_tid_address"); + m.insert(219, "restart_syscall"); + m.insert(220, "semtimedop"); + m.insert(221, "fadvise64"); + m.insert(222, "timer_create"); + m.insert(223, "timer_settime"); + m.insert(224, "timer_gettime"); + m.insert(225, "timer_getoverrun"); + m.insert(226, "timer_delete"); + m.insert(227, "clock_settime"); + m.insert(228, "clock_gettime"); + m.insert(229, "clock_getres"); + m.insert(230, "clock_nanosleep"); + m.insert(231, "exit_group"); + m.insert(232, "epoll_wait"); + m.insert(233, "epoll_ctl"); + m.insert(234, "tgkill"); + m.insert(235, "utimes"); + m.insert(236, "vserver"); + m.insert(237, "mbind"); + m.insert(238, "set_mempolicy"); + m.insert(239, "get_mempolicy"); + m.insert(240, "mq_open"); + m.insert(241, "mq_unlink"); + m.insert(242, "mq_timedsend"); + m.insert(243, "mq_timedreceive"); + m.insert(244, "mq_notify"); + m.insert(245, "mq_getsetattr"); + m.insert(246, "kexec_load"); + m.insert(247, "waitid"); + m.insert(248, "add_key"); + m.insert(249, "request_key"); + m.insert(250, "keyctl"); + m.insert(251, "ioprio_set"); + m.insert(252, "ioprio_get"); + m.insert(253, "inotify_init"); + m.insert(254, "inotify_add_watch"); + m.insert(255, "inotify_rm_watch"); + m.insert(256, "migrate_pages"); + m.insert(257, "openat"); + m.insert(258, "mkdirat"); + m.insert(259, "mknodat"); + m.insert(260, "fchownat"); + m.insert(261, "futimesat"); + m.insert(262, "newfstatat"); + m.insert(263, "unlinkat"); + m.insert(264, "renameat"); + m.insert(265, "linkat"); + m.insert(266, "symlinkat"); + m.insert(267, "readlinkat"); + m.insert(268, "fchmodat"); + m.insert(269, "faccessat"); + m.insert(270, "pselect6"); + m.insert(271, "ppoll"); + m.insert(272, "unshare"); + m.insert(273, "set_robust_list"); + m.insert(274, "get_robust_list"); + m.insert(275, "splice"); + m.insert(276, "tee"); + m.insert(277, "sync_file_range"); + m.insert(278, "vmsplice"); + m.insert(279, "move_pages"); + m.insert(280, "utimensat"); + m.insert(281, "epoll_pwait"); + m.insert(282, "signalfd"); + m.insert(283, "timerfd_create"); + m.insert(284, "eventfd"); + m.insert(285, "fallocate"); + m.insert(286, "timerfd_settime"); + m.insert(287, "timerfd_gettime"); + m.insert(288, "accept4"); + m.insert(289, "signalfd4"); + m.insert(290, "eventfd2"); + m.insert(291, "epoll_create1"); + m.insert(292, "dup3"); + m.insert(293, "pipe2"); + m.insert(294, "inotify_init1"); + m.insert(295, "preadv"); + m.insert(296, "pwritev"); + m.insert(297, "rt_tgsigqueueinfo"); + m.insert(298, "perf_event_open"); + m.insert(299, "recvmmsg"); + m.insert(300, "fanotify_init"); + m.insert(301, "fanotify_mark"); + m.insert(302, "prlimit64"); + m.insert(303, "name_to_handle_at"); + m.insert(304, "open_by_handle_at"); + m.insert(305, "clock_adjtime"); + m.insert(306, "syncfs"); + m.insert(307, "sendmmsg"); + m.insert(308, "setns"); + m.insert(309, "getcpu"); + m.insert(310, "process_vm_readv"); + m.insert(311, "process_vm_writev"); + m.insert(312, "kcmp"); + m.insert(313, "finit_module"); + m.insert(314, "sched_setattr"); + m.insert(315, "sched_getattr"); + m.insert(316, "renameat2"); + m.insert(317, "seccomp"); + m.insert(318, "getrandom"); + m.insert(319, "memfd_create"); + m.insert(320, "kexec_file_load"); + m.insert(321, "bpf"); + m.insert(322, "execveat"); + m.insert(323, "userfaultfd"); + m.insert(324, "membarrier"); + m.insert(325, "mlock2"); + m.insert(326, "copy_file_range"); + m.insert(327, "preadv2"); + m.insert(328, "pwritev2"); + m.insert(329, "pkey_mprotect"); + m.insert(330, "pkey_alloc"); + m.insert(331, "pkey_free"); + m.insert(332, "statx"); + m.insert(333, "io_pgetevents"); + m.insert(334, "rseq"); + m.insert(424, "pidfd_send_signal"); + m.insert(425, "io_uring_setup"); + m.insert(426, "io_uring_enter"); + m.insert(427, "io_uring_register"); + m.insert(428, "open_tree"); + m.insert(429, "move_mount"); + m.insert(430, "fsopen"); + m.insert(431, "fsconfig"); + m.insert(432, "fsmount"); + m.insert(433, "fspick"); + m.insert(434, "pidfd_open"); + m.insert(435, "clone3"); + m.insert(437, "openat2"); + m.insert(438, "pidfd_getfd"); + m.insert(439, "faccessat2"); + m.insert(512, "rt_sigaction"); + m.insert(513, "rt_sigreturn"); + m.insert(514, "ioctl"); + m.insert(515, "readv"); + m.insert(516, "writev"); + m.insert(517, "recvfrom"); + m.insert(518, "sendmsg"); + m.insert(519, "recvmsg"); + m.insert(520, "execve"); + m.insert(521, "ptrace"); + m.insert(522, "rt_sigpending"); + m.insert(523, "rt_sigtimedwait"); + m.insert(524, "rt_sigqueueinfo"); + m.insert(525, "sigaltstack"); + m.insert(526, "timer_create"); + m.insert(527, "mq_notify"); + m.insert(528, "kexec_load"); + m.insert(529, "waitid"); + m.insert(530, "set_robust_list"); + m.insert(531, "get_robust_list"); + m.insert(532, "vmsplice"); + m.insert(533, "move_pages"); + m.insert(534, "preadv"); + m.insert(535, "pwritev"); + m.insert(536, "rt_tgsigqueueinfo"); + m.insert(537, "recvmmsg"); + m.insert(538, "sendmmsg"); + m.insert(539, "process_vm_readv"); + m.insert(540, "process_vm_writev"); + m.insert(541, "setsockopt"); + m.insert(542, "getsockopt"); + m.insert(543, "io_setup"); + m.insert(544, "io_submit"); + m.insert(545, "execveat"); + m.insert(546, "preadv2"); + m.insert(547, "pwritev2"); + m + }; +} + use crate::binary_parser::{parse_binary, BinaryInfo}; use crate::config::{Config, LockingStrategy, LineNo}; #[cfg(unwind)] @@ -263,6 +657,35 @@ impl PythonSpy { trace.active = !self._heuristic_is_thread_idle(&trace); } + // Read current syscall (if any) + #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + { + if self.config.trace_syscalls { + if let Some(tid) = os_thread_id { + let path = format!("/proc/{}/task/{}/syscall", self.pid, tid); + if let Ok(contents) = std::fs::read_to_string(&path) { + let mut it = contents.splitn(2, " "); + if let Some(syscall) = it.next() { + if let Ok(syscall) = &syscall[..].parse::() { + let name = SYSCALLS.get(syscall).map(|s| format!("{} syscall", s)); + let name = name.unwrap_or_else(|| format!("syscall #{}", syscall)); + + let frame = crate::stack_trace::Frame { + name, + filename: "".to_string(), + line: 0, + module: None, + short_filename: None, + locals: None, + }; + trace.frames.insert(0, frame); + } + } + } + } + } + } + // Merge in the native stack frames if necessary #[cfg(unwind)] { From 5606f9a3beba4dd8d0ba8968ef057bfcdfc7e949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Fri, 16 Jul 2021 08:27:13 +0200 Subject: [PATCH 2/5] Use syscalls crate --- Cargo.lock | 10 ++ Cargo.toml | 5 +- src/python_spy.rs | 403 +--------------------------------------------- 3 files changed, 20 insertions(+), 398 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d983b87b..a1efee8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -817,6 +817,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "syscalls", "tempfile", "termios", "winapi 0.3.9", @@ -1119,6 +1120,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "syscalls" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad4126c98e506c5c2ada914b40c17b57a99f7d7044e35ff631a3504effb28e4" +dependencies = [ + "cc", +] + [[package]] name = "tap" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 1c987524..48f027e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,10 @@ edition="2018" [features] default = ["trace_syscalls"] -trace_syscalls = [] +trace_syscalls = ["syscalls"] + +[target.'cfg(target_os = "linux")'.dependencies] +syscalls = {version="0.3.3", optional=true} [dependencies] clap = {version="2", features=["wrap_help"]} diff --git a/src/python_spy.rs b/src/python_spy.rs index bbf32f27..ac4c4fc7 100644 --- a/src/python_spy.rs +++ b/src/python_spy.rs @@ -16,400 +16,8 @@ use lazy_static::lazy_static; use remoteprocess::{Process, ProcessMemory, Pid, Tid}; use proc_maps::{get_process_maps, MapRange}; - -#[cfg(all(target_os = "linux", feature = "trace_syscalls"))] -lazy_static! { - static ref SYSCALLS: HashMap = { - let mut m = HashMap::new(); - m.insert(0, "read"); - m.insert(1, "write"); - m.insert(2, "open"); - m.insert(3, "close"); - m.insert(4, "stat"); - m.insert(5, "fstat"); - m.insert(6, "lstat"); - m.insert(7, "poll"); - m.insert(8, "lseek"); - m.insert(9, "mmap"); - m.insert(10, "mprotect"); - m.insert(11, "munmap"); - m.insert(12, "brk"); - m.insert(13, "rt_sigaction"); - m.insert(14, "rt_sigprocmask"); - m.insert(15, "rt_sigreturn"); - m.insert(16, "ioctl"); - m.insert(17, "pread64"); - m.insert(18, "pwrite64"); - m.insert(19, "readv"); - m.insert(20, "writev"); - m.insert(21, "access"); - m.insert(22, "pipe"); - m.insert(23, "select"); - m.insert(24, "sched_yield"); - m.insert(25, "mremap"); - m.insert(26, "msync"); - m.insert(27, "mincore"); - m.insert(28, "madvise"); - m.insert(29, "shmget"); - m.insert(30, "shmat"); - m.insert(31, "shmctl"); - m.insert(32, "dup"); - m.insert(33, "dup2"); - m.insert(34, "pause"); - m.insert(35, "nanosleep"); - m.insert(36, "getitimer"); - m.insert(37, "alarm"); - m.insert(38, "setitimer"); - m.insert(39, "getpid"); - m.insert(40, "sendfile"); - m.insert(41, "socket"); - m.insert(42, "connect"); - m.insert(43, "accept"); - m.insert(44, "sendto"); - m.insert(45, "recvfrom"); - m.insert(46, "sendmsg"); - m.insert(47, "recvmsg"); - m.insert(48, "shutdown"); - m.insert(49, "bind"); - m.insert(50, "listen"); - m.insert(51, "getsockname"); - m.insert(52, "getpeername"); - m.insert(53, "socketpair"); - m.insert(54, "setsockopt"); - m.insert(55, "getsockopt"); - m.insert(56, "clone"); - m.insert(57, "fork"); - m.insert(58, "vfork"); - m.insert(59, "execve"); - m.insert(60, "exit"); - m.insert(61, "wait4"); - m.insert(62, "kill"); - m.insert(63, "uname"); - m.insert(64, "semget"); - m.insert(65, "semop"); - m.insert(66, "semctl"); - m.insert(67, "shmdt"); - m.insert(68, "msgget"); - m.insert(69, "msgsnd"); - m.insert(70, "msgrcv"); - m.insert(71, "msgctl"); - m.insert(72, "fcntl"); - m.insert(73, "flock"); - m.insert(74, "fsync"); - m.insert(75, "fdatasync"); - m.insert(76, "truncate"); - m.insert(77, "ftruncate"); - m.insert(78, "getdents"); - m.insert(79, "getcwd"); - m.insert(80, "chdir"); - m.insert(81, "fchdir"); - m.insert(82, "rename"); - m.insert(83, "mkdir"); - m.insert(84, "rmdir"); - m.insert(85, "creat"); - m.insert(86, "link"); - m.insert(87, "unlink"); - m.insert(88, "symlink"); - m.insert(89, "readlink"); - m.insert(90, "chmod"); - m.insert(91, "fchmod"); - m.insert(92, "chown"); - m.insert(93, "fchown"); - m.insert(94, "lchown"); - m.insert(95, "umask"); - m.insert(96, "gettimeofday"); - m.insert(97, "getrlimit"); - m.insert(98, "getrusage"); - m.insert(99, "sysinfo"); - m.insert(100, "times"); - m.insert(101, "ptrace"); - m.insert(102, "getuid"); - m.insert(103, "syslog"); - m.insert(104, "getgid"); - m.insert(105, "setuid"); - m.insert(106, "setgid"); - m.insert(107, "geteuid"); - m.insert(108, "getegid"); - m.insert(109, "setpgid"); - m.insert(110, "getppid"); - m.insert(111, "getpgrp"); - m.insert(112, "setsid"); - m.insert(113, "setreuid"); - m.insert(114, "setregid"); - m.insert(115, "getgroups"); - m.insert(116, "setgroups"); - m.insert(117, "setresuid"); - m.insert(118, "getresuid"); - m.insert(119, "setresgid"); - m.insert(120, "getresgid"); - m.insert(121, "getpgid"); - m.insert(122, "setfsuid"); - m.insert(123, "setfsgid"); - m.insert(124, "getsid"); - m.insert(125, "capget"); - m.insert(126, "capset"); - m.insert(127, "rt_sigpending"); - m.insert(128, "rt_sigtimedwait"); - m.insert(129, "rt_sigqueueinfo"); - m.insert(130, "rt_sigsuspend"); - m.insert(131, "sigaltstack"); - m.insert(132, "utime"); - m.insert(133, "mknod"); - m.insert(134, "uselib"); - m.insert(135, "personality"); - m.insert(136, "ustat"); - m.insert(137, "statfs"); - m.insert(138, "fstatfs"); - m.insert(139, "sysfs"); - m.insert(140, "getpriority"); - m.insert(141, "setpriority"); - m.insert(142, "sched_setparam"); - m.insert(143, "sched_getparam"); - m.insert(144, "sched_setscheduler"); - m.insert(145, "sched_getscheduler"); - m.insert(146, "sched_get_priority_max"); - m.insert(147, "sched_get_priority_min"); - m.insert(148, "sched_rr_get_interval"); - m.insert(149, "mlock"); - m.insert(150, "munlock"); - m.insert(151, "mlockall"); - m.insert(152, "munlockall"); - m.insert(153, "vhangup"); - m.insert(154, "modify_ldt"); - m.insert(155, "pivot_root"); - m.insert(156, "_sysctl"); - m.insert(157, "prctl"); - m.insert(158, "arch_prctl"); - m.insert(159, "adjtimex"); - m.insert(160, "setrlimit"); - m.insert(161, "chroot"); - m.insert(162, "sync"); - m.insert(163, "acct"); - m.insert(164, "settimeofday"); - m.insert(165, "mount"); - m.insert(166, "umount2"); - m.insert(167, "swapon"); - m.insert(168, "swapoff"); - m.insert(169, "reboot"); - m.insert(170, "sethostname"); - m.insert(171, "setdomainname"); - m.insert(172, "iopl"); - m.insert(173, "ioperm"); - m.insert(174, "create_module"); - m.insert(175, "init_module"); - m.insert(176, "delete_module"); - m.insert(177, "get_kernel_syms"); - m.insert(178, "query_module"); - m.insert(179, "quotactl"); - m.insert(180, "nfsservctl"); - m.insert(181, "getpmsg"); - m.insert(182, "putpmsg"); - m.insert(183, "afs_syscall"); - m.insert(184, "tuxcall"); - m.insert(185, "security"); - m.insert(186, "gettid"); - m.insert(187, "readahead"); - m.insert(188, "setxattr"); - m.insert(189, "lsetxattr"); - m.insert(190, "fsetxattr"); - m.insert(191, "getxattr"); - m.insert(192, "lgetxattr"); - m.insert(193, "fgetxattr"); - m.insert(194, "listxattr"); - m.insert(195, "llistxattr"); - m.insert(196, "flistxattr"); - m.insert(197, "removexattr"); - m.insert(198, "lremovexattr"); - m.insert(199, "fremovexattr"); - m.insert(200, "tkill"); - m.insert(201, "time"); - m.insert(202, "futex"); - m.insert(203, "sched_setaffinity"); - m.insert(204, "sched_getaffinity"); - m.insert(205, "set_thread_area"); - m.insert(206, "io_setup"); - m.insert(207, "io_destroy"); - m.insert(208, "io_getevents"); - m.insert(209, "io_submit"); - m.insert(210, "io_cancel"); - m.insert(211, "get_thread_area"); - m.insert(212, "lookup_dcookie"); - m.insert(213, "epoll_create"); - m.insert(214, "epoll_ctl_old"); - m.insert(215, "epoll_wait_old"); - m.insert(216, "remap_file_pages"); - m.insert(217, "getdents64"); - m.insert(218, "set_tid_address"); - m.insert(219, "restart_syscall"); - m.insert(220, "semtimedop"); - m.insert(221, "fadvise64"); - m.insert(222, "timer_create"); - m.insert(223, "timer_settime"); - m.insert(224, "timer_gettime"); - m.insert(225, "timer_getoverrun"); - m.insert(226, "timer_delete"); - m.insert(227, "clock_settime"); - m.insert(228, "clock_gettime"); - m.insert(229, "clock_getres"); - m.insert(230, "clock_nanosleep"); - m.insert(231, "exit_group"); - m.insert(232, "epoll_wait"); - m.insert(233, "epoll_ctl"); - m.insert(234, "tgkill"); - m.insert(235, "utimes"); - m.insert(236, "vserver"); - m.insert(237, "mbind"); - m.insert(238, "set_mempolicy"); - m.insert(239, "get_mempolicy"); - m.insert(240, "mq_open"); - m.insert(241, "mq_unlink"); - m.insert(242, "mq_timedsend"); - m.insert(243, "mq_timedreceive"); - m.insert(244, "mq_notify"); - m.insert(245, "mq_getsetattr"); - m.insert(246, "kexec_load"); - m.insert(247, "waitid"); - m.insert(248, "add_key"); - m.insert(249, "request_key"); - m.insert(250, "keyctl"); - m.insert(251, "ioprio_set"); - m.insert(252, "ioprio_get"); - m.insert(253, "inotify_init"); - m.insert(254, "inotify_add_watch"); - m.insert(255, "inotify_rm_watch"); - m.insert(256, "migrate_pages"); - m.insert(257, "openat"); - m.insert(258, "mkdirat"); - m.insert(259, "mknodat"); - m.insert(260, "fchownat"); - m.insert(261, "futimesat"); - m.insert(262, "newfstatat"); - m.insert(263, "unlinkat"); - m.insert(264, "renameat"); - m.insert(265, "linkat"); - m.insert(266, "symlinkat"); - m.insert(267, "readlinkat"); - m.insert(268, "fchmodat"); - m.insert(269, "faccessat"); - m.insert(270, "pselect6"); - m.insert(271, "ppoll"); - m.insert(272, "unshare"); - m.insert(273, "set_robust_list"); - m.insert(274, "get_robust_list"); - m.insert(275, "splice"); - m.insert(276, "tee"); - m.insert(277, "sync_file_range"); - m.insert(278, "vmsplice"); - m.insert(279, "move_pages"); - m.insert(280, "utimensat"); - m.insert(281, "epoll_pwait"); - m.insert(282, "signalfd"); - m.insert(283, "timerfd_create"); - m.insert(284, "eventfd"); - m.insert(285, "fallocate"); - m.insert(286, "timerfd_settime"); - m.insert(287, "timerfd_gettime"); - m.insert(288, "accept4"); - m.insert(289, "signalfd4"); - m.insert(290, "eventfd2"); - m.insert(291, "epoll_create1"); - m.insert(292, "dup3"); - m.insert(293, "pipe2"); - m.insert(294, "inotify_init1"); - m.insert(295, "preadv"); - m.insert(296, "pwritev"); - m.insert(297, "rt_tgsigqueueinfo"); - m.insert(298, "perf_event_open"); - m.insert(299, "recvmmsg"); - m.insert(300, "fanotify_init"); - m.insert(301, "fanotify_mark"); - m.insert(302, "prlimit64"); - m.insert(303, "name_to_handle_at"); - m.insert(304, "open_by_handle_at"); - m.insert(305, "clock_adjtime"); - m.insert(306, "syncfs"); - m.insert(307, "sendmmsg"); - m.insert(308, "setns"); - m.insert(309, "getcpu"); - m.insert(310, "process_vm_readv"); - m.insert(311, "process_vm_writev"); - m.insert(312, "kcmp"); - m.insert(313, "finit_module"); - m.insert(314, "sched_setattr"); - m.insert(315, "sched_getattr"); - m.insert(316, "renameat2"); - m.insert(317, "seccomp"); - m.insert(318, "getrandom"); - m.insert(319, "memfd_create"); - m.insert(320, "kexec_file_load"); - m.insert(321, "bpf"); - m.insert(322, "execveat"); - m.insert(323, "userfaultfd"); - m.insert(324, "membarrier"); - m.insert(325, "mlock2"); - m.insert(326, "copy_file_range"); - m.insert(327, "preadv2"); - m.insert(328, "pwritev2"); - m.insert(329, "pkey_mprotect"); - m.insert(330, "pkey_alloc"); - m.insert(331, "pkey_free"); - m.insert(332, "statx"); - m.insert(333, "io_pgetevents"); - m.insert(334, "rseq"); - m.insert(424, "pidfd_send_signal"); - m.insert(425, "io_uring_setup"); - m.insert(426, "io_uring_enter"); - m.insert(427, "io_uring_register"); - m.insert(428, "open_tree"); - m.insert(429, "move_mount"); - m.insert(430, "fsopen"); - m.insert(431, "fsconfig"); - m.insert(432, "fsmount"); - m.insert(433, "fspick"); - m.insert(434, "pidfd_open"); - m.insert(435, "clone3"); - m.insert(437, "openat2"); - m.insert(438, "pidfd_getfd"); - m.insert(439, "faccessat2"); - m.insert(512, "rt_sigaction"); - m.insert(513, "rt_sigreturn"); - m.insert(514, "ioctl"); - m.insert(515, "readv"); - m.insert(516, "writev"); - m.insert(517, "recvfrom"); - m.insert(518, "sendmsg"); - m.insert(519, "recvmsg"); - m.insert(520, "execve"); - m.insert(521, "ptrace"); - m.insert(522, "rt_sigpending"); - m.insert(523, "rt_sigtimedwait"); - m.insert(524, "rt_sigqueueinfo"); - m.insert(525, "sigaltstack"); - m.insert(526, "timer_create"); - m.insert(527, "mq_notify"); - m.insert(528, "kexec_load"); - m.insert(529, "waitid"); - m.insert(530, "set_robust_list"); - m.insert(531, "get_robust_list"); - m.insert(532, "vmsplice"); - m.insert(533, "move_pages"); - m.insert(534, "preadv"); - m.insert(535, "pwritev"); - m.insert(536, "rt_tgsigqueueinfo"); - m.insert(537, "recvmmsg"); - m.insert(538, "sendmmsg"); - m.insert(539, "process_vm_readv"); - m.insert(540, "process_vm_writev"); - m.insert(541, "setsockopt"); - m.insert(542, "getsockopt"); - m.insert(543, "io_setup"); - m.insert(544, "io_submit"); - m.insert(545, "execveat"); - m.insert(546, "preadv2"); - m.insert(547, "pwritev2"); - m - }; -} +#[cfg(all(target_os="linux", feature="trace_syscalls"))] +use syscalls::SyscallNo; use crate::binary_parser::{parse_binary, BinaryInfo}; use crate::config::{Config, LockingStrategy, LineNo}; @@ -666,9 +274,10 @@ impl PythonSpy { if let Ok(contents) = std::fs::read_to_string(&path) { let mut it = contents.splitn(2, " "); if let Some(syscall) = it.next() { - if let Ok(syscall) = &syscall[..].parse::() { - let name = SYSCALLS.get(syscall).map(|s| format!("{} syscall", s)); - let name = name.unwrap_or_else(|| format!("syscall #{}", syscall)); + if let Ok(syscall_no) = &syscall[..].parse::() { + let syscall = SyscallNo::new(*syscall_no as usize); + let name = syscall.map(|s| format!("{} syscall", s.name())); + let name = name.unwrap_or_else(|| format!("syscall #{}", syscall_no)); let frame = crate::stack_trace::Frame { name, From b3e01d54d17029f6f75cd10e290714167b77c812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Fri, 16 Jul 2021 08:28:33 +0200 Subject: [PATCH 3/5] Make --syscalls not imply --idle --- src/config.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/config.rs b/src/config.rs index d4c42605..1ab5f81b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -325,9 +325,6 @@ impl Config { #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] { config.trace_syscalls = matches.occurrences_of("trace_syscalls") > 0; - if config.trace_syscalls { - config.include_idle = true; - } } config.native = matches.occurrences_of("native") > 0; From c2902da16e2a08c9eec9417b6cb51464690df2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Mon, 16 Aug 2021 22:09:40 +0200 Subject: [PATCH 4/5] Restrict --syscalls option to x86_64 --- Cargo.toml | 2 +- src/config.rs | 10 +++++----- src/python_spy.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 48f027e2..474c49e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ edition="2018" default = ["trace_syscalls"] trace_syscalls = ["syscalls"] -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(all(target_os="linux", target_arch="x86_64"))'.dependencies] syscalls = {version="0.3.3", optional=true} [dependencies] diff --git a/src/config.rs b/src/config.rs index 1ab5f81b..186a2868 100644 --- a/src/config.rs +++ b/src/config.rs @@ -123,7 +123,7 @@ impl Config { .short("n") .long("native") .help("Collect stack traces from native extensions written in Cython, C or C++"); - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] let trace_syscalls = Arg::with_name("trace_syscalls") .short("S") .long("syscalls") @@ -257,11 +257,11 @@ impl Config { let dump = dump.arg(native.clone()); // add syscall traces if appropiate - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] let record = record.arg(trace_syscalls.clone()); - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] let top = top.arg(trace_syscalls.clone()); - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] let dump = dump.arg(trace_syscalls.clone()); // Nonblocking isn't an option for freebsd, remove @@ -322,7 +322,7 @@ impl Config { config.include_idle = matches.occurrences_of("idle") > 0; config.gil_only = matches.occurrences_of("gil") > 0; config.include_thread_ids = matches.occurrences_of("threads") > 0; - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] { config.trace_syscalls = matches.occurrences_of("trace_syscalls") > 0; } diff --git a/src/python_spy.rs b/src/python_spy.rs index ac4c4fc7..0950eab1 100644 --- a/src/python_spy.rs +++ b/src/python_spy.rs @@ -16,7 +16,7 @@ use lazy_static::lazy_static; use remoteprocess::{Process, ProcessMemory, Pid, Tid}; use proc_maps::{get_process_maps, MapRange}; -#[cfg(all(target_os="linux", feature="trace_syscalls"))] +#[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] use syscalls::SyscallNo; use crate::binary_parser::{parse_binary, BinaryInfo}; @@ -266,7 +266,7 @@ impl PythonSpy { } // Read current syscall (if any) - #[cfg(all(target_os = "linux", feature = "trace_syscalls"))] + #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] { if self.config.trace_syscalls { if let Some(tid) = os_thread_id { From 198977fd573dd39bc7e00fac6792a81ad96ce120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Tue, 28 Dec 2021 21:45:09 +0100 Subject: [PATCH 5/5] Fix typo in comment --- src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 186a2868..c97598c6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -256,7 +256,7 @@ impl Config { #[cfg(unwind)] let dump = dump.arg(native.clone()); - // add syscall traces if appropiate + // add syscall traces if appropriate #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))] let record = record.arg(trace_syscalls.clone()); #[cfg(all(target_os="linux", target_arch="x86_64", feature="trace_syscalls"))]