From 55392e9b2d0873a861d2a39e00e85f6b5c0b7ea6 Mon Sep 17 00:00:00 2001 From: Alex Franchuk Date: Thu, 5 Jan 2023 10:37:38 -0500 Subject: [PATCH] Don't fail when ptrace::detach returns ESRCH. ESRCH indicates that the thread has disappeared while we had it stopped. We don't consider this an error. Closes #29. --- src/linux/ptrace_dumper.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/linux/ptrace_dumper.rs b/src/linux/ptrace_dumper.rs index bc03cae3..12014464 100644 --- a/src/linux/ptrace_dumper.rs +++ b/src/linux/ptrace_dumper.rs @@ -50,6 +50,22 @@ impl Drop for PtraceDumper { } } +/// PTRACE_DETACH the given pid. +/// +/// This handles special errno cases (ESRCH) which we won't consider errors. +fn ptrace_detach(child: Pid) -> Result<(), DumperError> { + let pid = nix::unistd::Pid::from_raw(child); + ptrace::detach(pid, None).or_else(|e| { + // errno is set to ESRCH if the pid no longer exists, but we don't want to error in that + // case. + if e == nix::Error::ESRCH { + Ok(()) + } else { + Err(DumperError::PtraceDetachError(child, e)) + } + }) +} + impl PtraceDumper { /// Constructs a dumper for extracting information of a given process /// with a process ID of |pid|. @@ -106,7 +122,6 @@ impl PtraceDumper { /// Suspends a thread by attaching to it. pub fn suspend_thread(child: Pid) -> Result<(), DumperError> { use DumperError::PtraceAttachError as AttachErr; - use DumperError::PtraceDetachError as DetachErr; let pid = nix::unistd::Pid::from_raw(child); // This may fail if the thread has just died or debugged. @@ -116,7 +131,7 @@ impl PtraceDumper { Ok(_) => break, Err(_e @ Errno::EINTR) => continue, Err(e) => { - ptrace::detach(pid, None).map_err(|e| DetachErr(child, e))?; + ptrace_detach(child)?; return Err(DumperError::WaitPidError(child, e)); } } @@ -145,7 +160,7 @@ impl PtraceDumper { skip_thread = true; } if skip_thread { - ptrace::detach(pid, None).map_err(|e| DetachErr(child, e))?; + ptrace_detach(child)?; return Err(DumperError::DetachSkippedThread(child)); } } @@ -154,10 +169,7 @@ impl PtraceDumper { /// Resumes a thread by detaching from it. pub fn resume_thread(child: Pid) -> Result<(), DumperError> { - use DumperError::PtraceDetachError as DetachErr; - let pid = nix::unistd::Pid::from_raw(child); - ptrace::detach(pid, None).map_err(|e| DetachErr(child, e))?; - Ok(()) + ptrace_detach(child) } pub fn suspend_threads(&mut self) -> Result<(), DumperError> {