Skip to content
Permalink
Browse files

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.

This was one of the reasons why debuggee with multiple threads misbehaved
under a debugger.
  • Loading branch information...
krytarowski committed Jun 21, 2019
1 parent 2ffe3f0 commit 254e517f2cf1fa3b90977f5d02d86a4589d3e6ce
Showing with 34 additions and 2 deletions.
  1. +34 −2 sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.362 2019/06/21 01:03:51 kamil Exp $ */
/* $NetBSD: kern_sig.c,v 1.363 2019/06/21 04:02:57 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.362 2019/06/21 01:03:51 kamil Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.363 2019/06/21 04:02:57 kamil Exp $");

#include "opt_ptrace.h"
#include "opt_dtrace.h"
@@ -913,6 +913,7 @@ trapsignal(struct lwp *l, ksiginfo_t *ksi)
mutex_enter(proc_lock);
mutex_enter(p->p_lock);

repeat:
/*
* If we are exiting, demise now.
*
@@ -926,6 +927,16 @@ trapsignal(struct lwp *l, ksiginfo_t *ksi)
/* 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;
@@ -1580,6 +1591,7 @@ eventswitch(int code)
KASSERT((code == TRAP_CHLD) || (code == TRAP_LWP) ||
(code == TRAP_EXEC));

repeat:
/*
* If we are exiting, demise now.
*
@@ -1603,6 +1615,16 @@ eventswitch(int code)
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_info._signo = signo;
@@ -2434,6 +2456,7 @@ proc_stoptrace(int trapno, int sysnum, const register_t args[],

mutex_enter(p->p_lock);

repeat:
/*
* If we are exiting, demise now.
*
@@ -2455,6 +2478,15 @@ proc_stoptrace(int trapno, int sysnum, const register_t args[],
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;

0 comments on commit 254e517

Please sign in to comment.
You can’t perform that action at this time.