[DTrace-devel] [PATCH 2/7] libproc: non-ptraceable processes are not dead

Nick Alcock nick.alcock at oracle.com
Wed Mar 20 14:15:32 UTC 2024


You're only supposed to call Ptrace() on invasively-grabbed processes that
have already had a PTRACE_SEIZE set up on them.  But if you accidentally
call it on a noninvasively-traced process instead, this fails horribly
(ptrace() returns -ECHILD, Ptrace() misfires and erroneously concludes the
process is dead, most other operations on that process fail spuriously from
then on).  The proxying system makes it much easier to accidentally call
Ptrace() on a process than it was when Ptrace() was originally written: it's
not only the monitoring threads that call it any more, the main thread does
it all over the place (relying on proxying to the monitoring thread to do
its job), and it should *not* be incumbent on the main thread to check
whether children are invasively traced or not all over the place.

Since noninvasively-traced processes cannot be ptrace-stopped, Ptrace() has
no real utility for nontraced processes, so it's best to just NOP it in this
case (the balacing Puntrace() will already silently do nothing in such a
case).  This stops it mistakenly marking the process dead, which is a
definite improvement! (If it actually *is* dead, we'll figure that out soon
enough as soon as we start trying to do anything else to it.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
 libproc/Pcontrol.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/libproc/Pcontrol.c b/libproc/Pcontrol.c
index 123e44fa44392..790b62428f097 100644
--- a/libproc/Pcontrol.c
+++ b/libproc/Pcontrol.c
@@ -679,6 +679,14 @@ Pwait_internal(struct ps_prochandle *P, boolean_t block, int *return_early)
 	if (P->state == PS_DEAD)
 		return 0;
 
+	/*
+	 * If a noninvasively traced process gets Pwait()ed on (which is
+	 * routine, its use is pervasive), don't wait: we'll only get an ECHILD,
+	 * which will spuriously cause us to conclude that the process is dead.
+	 */
+	if (P->noninvasive)
+		return 0;
+
 	do {
 		errno = 0;
 
-- 
2.44.0.273.ge0bd14271f




More information about the DTrace-devel mailing list