Source-Changes-HG archive

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

[src/trunk]: src/sys/kern Stop trying to inform debugger about events from an...



details:   https://anonhg.NetBSD.org/src/rev/4cb3c819f4a2
branches:  trunk
changeset: 451787:4cb3c819f4a2
user:      kamil <kamil%NetBSD.org@localhost>
date:      Tue Jun 04 11:54:03 2019 +0000

description:
Stop trying to inform debugger about events from an exiting child

Do not emit signals to parent for if a process is demising:

 - fork/vfork/similar
 - lwp created/exited
 - exec
 - syscall entry/exit

With these changes Go applications can be traced without a clash under
a debugger, at least without deadlocking always. The culprit reason was
an attempt to inform a debugger in the middle of exit1() call about
a dying LWP. Go applications perform exit(2) without collecting threads
first. Verified with GDB and picotrace-based utilities like sigtracer.

PR kern/53120
PR port-arm/51677
PR bin/54060
PR bin/49662
PR kern/52548

diffstat:

 sys/kern/kern_lwp.c |  18 ++++++++++++----
 sys/kern/kern_sig.c |  57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 7 deletions(-)

diffs (138 lines):

diff -r 3b7b64e18388 -r 4cb3c819f4a2 sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c       Tue Jun 04 11:37:39 2019 +0000
+++ b/sys/kern/kern_lwp.c       Tue Jun 04 11:54:03 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lwp.c,v 1.201 2019/05/17 03:34:26 ozaki-r Exp $   */
+/*     $NetBSD: kern_lwp.c,v 1.202 2019/06/04 11:54:03 kamil Exp $     */
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.201 2019/05/17 03:34:26 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.202 2019/06/04 11:54:03 kamil Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -1084,9 +1084,17 @@
        if ((p->p_slflag & (PSL_TRACED|PSL_TRACELWP_EXIT)) ==
            (PSL_TRACED|PSL_TRACELWP_EXIT)) {
                mutex_enter(p->p_lock);
-               p->p_lwp_exited = l->l_lid;
-               eventswitch(TRAP_LWP);
-               mutex_enter(proc_lock);
+               if (ISSET(p->p_sflag, PS_WEXIT)) {
+                       mutex_exit(p->p_lock);
+                       /*
+                        * We are exiting, bail out without informing parent
+                        * about a terminating LWP as it would deadlock.
+                        */
+               } else {
+                       p->p_lwp_exited = l->l_lid;
+                       eventswitch(TRAP_LWP);
+                       mutex_enter(proc_lock);
+               }
        }
 
        LIST_REMOVE(l, l_list);
diff -r 3b7b64e18388 -r 4cb3c819f4a2 sys/kern/kern_sig.c
--- a/sys/kern/kern_sig.c       Tue Jun 04 11:37:39 2019 +0000
+++ b/sys/kern/kern_sig.c       Tue Jun 04 11:54:03 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_sig.c,v 1.358 2019/05/06 08:05:03 kamil Exp $     */
+/*     $NetBSD: kern_sig.c,v 1.359 2019/06/04 11:54:03 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.358 2019/05/06 08:05:03 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.359 2019/06/04 11:54:03 kamil Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -913,6 +913,19 @@
        mutex_enter(proc_lock);
        mutex_enter(p->p_lock);
 
+       /*
+        * 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);
+               lwp_exit(l);
+               panic("trapsignal");
+               /* NOTREACHED */
+       }
+
        mask = &l->l_sigmask;
        ps = p->p_sigacts;
        action = SIGACTION_PS(ps, signo).sa_handler;
@@ -1569,6 +1582,19 @@
                (code == TRAP_EXEC));
 
        /*
+        * 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);
+               lwp_exit(l);
+               panic("eventswitch");
+               /* NOTREACHED */
+       }
+
+       /*
         * If there's a pending SIGKILL process it immediately.
         */
        if (p->p_xsig == SIGKILL ||
@@ -1622,6 +1648,21 @@
        KASSERT(p->p_nrlwps > 0);
 
        /*
+        * 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);
+               if (relock) {
+                       mutex_exit(proc_lock);
+               }
+               lwp_exit(l);
+               panic("sigswitch");
+               /* NOTREACHED */
+       }
+
+       /*
         * On entry we know that the process needs to stop.  If it's
         * the result of a 'sideways' stop signal that has been sourced
         * through issignal(), then stop other LWPs in the process too.
@@ -2395,6 +2436,18 @@
        mutex_enter(p->p_lock);
 
        /*
+        * 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);
+               lwp_exit(l);
+               panic("proc_stoptrace");
+               /* NOTREACHED */
+       }
+
+       /*
         * If there's a pending SIGKILL process it immediately.
         */
        if (p->p_xsig == SIGKILL ||



Home | Main Index | Thread Index | Old Index