Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Enhance reliability of ptrace(2) in a debuggee with...



details:   https://anonhg.NetBSD.org/src/rev/391c80bf5c2d
branches:  trunk
changeset: 455125:391c80bf5c2d
user:      kamil <kamil%NetBSD.org@localhost>
date:      Tue Oct 08 18:02:46 2019 +0000

description:
Enhance reliability of ptrace(2) in a debuggee with multiple LWPs

Stop competing between threads which one emits event signal quicker and
overwriting the signal from another thread.

This fixes missed in action signals.

NetBSD truss can now report reliably all TRAP_SCE/SCX/etc events without
reports of missed ones.

his was one of the reasons why debuggee with multiple threads misbehaved
under a debugger.


This change is v.2 of the previously reverted commit for the same fix.

This version contains recovery path that stopps triggering event SIGTRAP
for a detached debugger.

diffstat:

 sys/kern/kern_sig.c |  59 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 56 insertions(+), 3 deletions(-)

diffs (126 lines):

diff -r 2f7bd1ee7604 -r 391c80bf5c2d sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Tue Oct 08 17:41:04 2019 +0000
+++ b/sys/kern/kern_sig.c       Tue Oct 08 18:02:46 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 kamil Exp $     */
+/*     $NetBSD: kern_sig.c,v 1.367 2019/10/08 18:02:46 kamil Exp $     */
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.366 2019/10/03 22:48:44 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.367 2019/10/08 18:02:46 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -913,6 +913,7 @@
        mutex_enter(proc_lock);
        mutex_enter(p->p_lock);
 
+repeat:
        /*
         * If we are exiting, demise now.
         *
@@ -926,6 +927,16 @@
                /* NOTREACHED */
        }
 
+       /*
+        * The process is already stopping.
+        */
+       if ((p->p_sflag & PS_STOPPING) != 0) {
+               sigswitch(0, p->p_xsig, false);
+               mutex_enter(proc_lock);
+               mutex_enter(p->p_lock);
+               goto repeat; /* XXX */
+       }
+
        mask = &l->l_sigmask;
        ps = p->p_sigacts;
        action = SIGACTION_PS(ps, signo).sa_handler;
@@ -1589,11 +1600,12 @@
        KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) ||
                (code == TRAP_EXEC));
 
+repeat:
        /*
         * If we are exiting, demise now.
         *
         * This avoids notifying tracer and deadlocking.
-       */
+        */
        if (__predict_false(ISSET(p->p_sflag, PS_WEXIT))) {
                mutex_exit(p->p_lock);
                mutex_exit(proc_lock);
@@ -1603,6 +1615,17 @@
        }
 
        /*
+        * If we are no longer traced, abandon this event signal.
+        *
+        * This avoids killing a process after detaching the debugger.
+        */
+       if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) {
+               mutex_exit(p->p_lock);
+               mutex_exit(proc_lock);
+               return;
+       }
+
+       /*
         * If there's a pending SIGKILL process it immediately.
         */
        if (p->p_xsig == SIGKILL ||
@@ -1612,6 +1635,16 @@
                return;
        }
 
+       /*
+        * The process is already stopping.
+        */
+       if ((p->p_sflag & PS_STOPPING) != 0) {
+               sigswitch(0, p->p_xsig, false);
+               mutex_enter(proc_lock);
+               mutex_enter(p->p_lock);
+               goto repeat; /* XXX */
+       }
+
        KSI_INIT_TRAP(&ksi);
        ksi.ksi_lid = l->l_lid;
        ksi.ksi_signo = signo;
@@ -2448,6 +2481,7 @@
 
        mutex_enter(p->p_lock);
 
+repeat:
        /*
         * If we are exiting, demise now.
         *
@@ -2469,6 +2503,25 @@
                return;
        }
 
+       /*
+        * If we are no longer traced, abandon this event signal.
+        *
+        * This avoids killing a process after detaching the debugger.
+        */
+       if (__predict_false(!ISSET(p->p_slflag, PSL_TRACED))) {
+               mutex_exit(p->p_lock);
+               return;
+       }
+
+       /*
+        * The process is already stopping.
+        */
+       if ((p->p_sflag & PS_STOPPING) != 0) {
+               sigswitch(0, p->p_xsig, true);
+               mutex_enter(p->p_lock);
+               goto repeat; /* XXX */
+       }
+
        /* Needed for ktrace */
        ps = p->p_sigacts;
        action = SIGACTION_PS(ps, signo).sa_handler;



Home | Main Index | Thread Index | Old Index