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
This commit is contained in:
parent
43729d11af
commit
bcb2d04797
|
@ -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 @@ lwp_exit(struct lwp *l)
|
|||
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);
|
||||
|
|
|
@ -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 @@ trapsignal(struct lwp *l, ksiginfo_t *ksi)
|
|||
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;
|
||||
|
@ -1568,6 +1581,19 @@ eventswitch(int code)
|
|||
KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) ||
|
||||
(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.
|
||||
*/
|
||||
|
@ -1621,6 +1647,21 @@ sigswitch(int ppmask, int signo, bool relock)
|
|||
KASSERT(l->l_stat == LSONPROC);
|
||||
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
|
||||
|
@ -2394,6 +2435,18 @@ proc_stoptrace(int trapno, int sysnum, const register_t args[],
|
|||
|
||||
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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue