Module Name:    src
Committed By:   martin
Date:           Wed Oct 23 19:25:39 UTC 2019

Modified Files:
        src/sys/kern [netbsd-9]: kern_sig.c sys_ptrace_common.c
        src/tests/lib/libc/sys [netbsd-9]: t_ptrace_wait.c

Log Message:
Pull up following revision(s) (requested by kamil in ticket #366):

        tests/lib/libc/sys/t_ptrace_wait.c: revision 1.136
        sys/kern/kern_sig.c: revision 1.373
        tests/lib/libc/sys/t_ptrace_wait.c: revision 1.138
        tests/lib/libc/sys/t_ptrace_wait.c: revision 1.139
        sys/kern/kern_sig.c: revision 1.376
        tests/lib/libc/sys/t_ptrace_wait.c: revision 1.140
        sys/kern/sys_ptrace_common.c: revision 1.64

Fix typo in a comment

Enable TEST_LWP_ENABLED in t_ptrace_wait*
The LWP events (created, exited) are now reliable in my local tests.
PR kern/51420
PR kern/51995

Remove the short-circuit lwp_exit() path from sigswitch()

sigswitch() can be called from exit1() through:

   ttywait()->ttysleep()-> 
cv_timedwait_sig()->sleepq_block()->issignal()->sigswitch()

lwp_exit() called for the last LWP triggers exit1() and this causes a panic.
The debugger related signals have short-circuit demise paths in
eventswitch() and other functions, before calling sigswitch().

This change restores the original behavior, but there is an open question
whether the kernel crash is a red herring of misbehavior of ttywait().
This should fix PR kern/54618 by David H. Gutteridge

Fix a race condition when handling concurrent LWP signals and add a test

Fix a race condition that caused PT_GET_SIGINFO to return incorrect
information when multiple signals were delivered concurrently
to different LWPs.  Add a regression test that verifies that when 50
threads concurrently use pthread_kill() on themselves, the debugger
receives all signals with correct information.

The kernel uses separate signal queues for each LWP.  However,
the signal context used to implement PT_GET_SIGINFO is stored in 'struct
proc' and therefore common to all LWPs in the process.  Previously,
this member was filled in kpsignal2(), i.e. when the signal was sent.

This meant that if another LWP managed to send another signal
concurrently, the data was overwritten before the process was stopped.

As a result, PT_GET_SIGINFO did not report the correct LWP and signal
(it could even report a different signal than wait()).  This can be
quite reliably reproduced with the number of 20 LWPs, however it can
also occur with 10.

This patch moves setting of signal context to issignal(), just before
the process is actually stopped.  The data is taken from per-LWP
or per-process signal queue.  The added test confirms that the debugger
correctly receives all signals, and PT_GET_SIGINFO reports both correct
LWP and signal number.
Reviewed by kamil.

Remove preprocessor switch TEST_VFORK_ENABLED in t_ptrace_wait*
vfork(2) tests are now enabled always and confirmed to be stable.

Remove preprocessor switch TEST_LWP_ENABLED in t_ptrace_wait*
LWP tests are now enabled always and confirmed to be stable.


To generate a diff of this commit:
cvs rdiff -u -r1.364.2.7 -r1.364.2.8 src/sys/kern/kern_sig.c
cvs rdiff -u -r1.58.2.8 -r1.58.2.9 src/sys/kern/sys_ptrace_common.c
cvs rdiff -u -r1.131.2.5 -r1.131.2.6 src/tests/lib/libc/sys/t_ptrace_wait.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.364.2.7 src/sys/kern/kern_sig.c:1.364.2.8
--- src/sys/kern/kern_sig.c:1.364.2.7	Tue Oct 15 19:28:16 2019
+++ src/sys/kern/kern_sig.c	Wed Oct 23 19:25:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.364.2.7 2019/10/15 19:28:16 martin Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.364.2.8 2019/10/23 19:25:39 martin 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.364.2.7 2019/10/15 19:28:16 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.364.2.8 2019/10/23 19:25:39 martin Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -1318,10 +1318,6 @@ kpsignal2(struct proc *p, ksiginfo_t *ks
 	if (p->p_stat != SACTIVE && p->p_stat != SSTOP)
 		return 0;
 
-	/* XXX for core dump/debugger */
-	p->p_sigctx.ps_lwp = ksi->ksi_lid;
-	p->p_sigctx.ps_info = ksi->ksi_info;
-
 	/*
 	 * Notify any interested parties of the signal.
 	 */
@@ -1711,21 +1707,6 @@ sigswitch(int ppmask, int signo, bool pr
 	}
 
 	/*
-	 * 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 (proc_lock_held) {
-			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.
@@ -1844,7 +1825,7 @@ int
 issignal(struct lwp *l)
 {
 	struct proc *p;
-	int signo, prop;
+	int siglwp, signo, prop;
 	sigpend_t *sp;
 	sigset_t ss;
 
@@ -1886,6 +1867,7 @@ issignal(struct lwp *l)
 		if (signo == 0) {
 			sp = &l->l_sigpend;
 			ss = sp->sp_set;
+			siglwp = l->l_lid;
 			if ((p->p_lflag & PL_PPWAIT) != 0)
 				sigminusset(&vforksigmask, &ss);
 			sigminusset(&l->l_sigmask, &ss);
@@ -1893,6 +1875,7 @@ issignal(struct lwp *l)
 			if ((signo = firstsig(&ss)) == 0) {
 				sp = &p->p_sigpend;
 				ss = sp->sp_set;
+				siglwp = 0;
 				if ((p->p_lflag & PL_PPWAIT) != 0)
 					sigminusset(&vforksigmask, &ss);
 				sigminusset(&l->l_sigmask, &ss);
@@ -1911,6 +1894,28 @@ issignal(struct lwp *l)
 			}
 		}
 
+		if (sp) {
+			/* Overwrite process' signal context to correspond
+			 * to the currently reported LWP.  This is necessary
+			 * for PT_GET_SIGINFO to report the correct signal when
+			 * multiple LWPs have pending signals.  We do this only
+			 * when the signal comes from the queue, for signals
+			 * created by the debugger we assume it set correct
+			 * siginfo.
+			 */
+			ksiginfo_t *ksi = TAILQ_FIRST(&sp->sp_info);
+			if (ksi) {
+				p->p_sigctx.ps_lwp = ksi->ksi_lid;
+				p->p_sigctx.ps_info = ksi->ksi_info;
+			} else {
+				p->p_sigctx.ps_lwp = siglwp;
+				memset(&p->p_sigctx.ps_info, 0,
+				    sizeof(p->p_sigctx.ps_info));
+				p->p_sigctx.ps_info._signo = signo;
+				p->p_sigctx.ps_info._code = SI_NOINFO;
+			}
+		}
+
 		/*
 		 * We should see pending but ignored signals only if
 		 * we are being traced.

Index: src/sys/kern/sys_ptrace_common.c
diff -u src/sys/kern/sys_ptrace_common.c:1.58.2.8 src/sys/kern/sys_ptrace_common.c:1.58.2.9
--- src/sys/kern/sys_ptrace_common.c:1.58.2.8	Tue Oct 15 19:11:02 2019
+++ src/sys/kern/sys_ptrace_common.c	Wed Oct 23 19:25:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_ptrace_common.c,v 1.58.2.8 2019/10/15 19:11:02 martin Exp $	*/
+/*	$NetBSD: sys_ptrace_common.c,v 1.58.2.9 2019/10/23 19:25:39 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.58.2.8 2019/10/15 19:11:02 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.58.2.9 2019/10/23 19:25:39 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -1275,7 +1275,7 @@ do_ptrace(struct ptrace_methods *ptm, st
 		}
 
 		/*
-		 * Reject setting program cunter to 0x0 if VA0 is disabled.
+		 * Reject setting program counter to 0x0 if VA0 is disabled.
 		 *
 		 * Not all kernels implement this feature to set Program
 		 * Counter in one go in PT_CONTINUE and similar operations.

Index: src/tests/lib/libc/sys/t_ptrace_wait.c
diff -u src/tests/lib/libc/sys/t_ptrace_wait.c:1.131.2.5 src/tests/lib/libc/sys/t_ptrace_wait.c:1.131.2.6
--- src/tests/lib/libc/sys/t_ptrace_wait.c:1.131.2.5	Tue Oct 15 18:47:03 2019
+++ src/tests/lib/libc/sys/t_ptrace_wait.c	Wed Oct 23 19:25:39 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_wait.c,v 1.131.2.5 2019/10/15 18:47:03 martin Exp $	*/
+/*	$NetBSD: t_ptrace_wait.c,v 1.131.2.6 2019/10/23 19:25:39 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace_wait.c,v 1.131.2.5 2019/10/15 18:47:03 martin Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.131.2.6 2019/10/23 19:25:39 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -121,14 +121,6 @@ static int debug = 0;
 	printf("%s() %s:%d " a, __func__, __FILE__, __LINE__,  ##__VA_ARGS__); \
     while (/*CONSTCOND*/0)
 
-#ifndef TEST_VFORK_ENABLED
-#define TEST_VFORK_ENABLED 1
-#endif
-
-#ifndef TEST_LWP_ENABLED
-#define TEST_LWP_ENABLED 0
-#endif
-
 /// ----------------------------------------------------------------------------
 
 static void
@@ -3269,7 +3261,6 @@ FORK_TEST(fork15, "fork", true, false, t
 FORK_TEST(fork16, "fork", true, true, true, true)
 #endif
 
-#if TEST_VFORK_ENABLED
 FORK_TEST(vfork1, "vfork", false, false, false, false)
 #if defined(TWAIT_HAVE_PID)
 FORK_TEST(vfork2, "vfork", false, true, false, false)
@@ -3294,7 +3285,6 @@ FORK_TEST(vfork14, "vfork", true, true, 
 FORK_TEST(vfork15, "vfork", true, false, true, true)
 FORK_TEST(vfork16, "vfork", true, true, true, true)
 #endif
-#endif
 
 FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
 FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
@@ -3497,22 +3487,17 @@ ATF_TC_BODY(name, tc)							\
 
 FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
 FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
-#if TEST_VFORK_ENABLED
 FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
 FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
-#endif
 
 FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
 FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
-#if TEST_VFORK_ENABLED
 FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
 FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
 #endif
-#endif
 
 /// ----------------------------------------------------------------------------
 
-#if TEST_VFORK_ENABLED
 static void
 traceme_vfork_fork_body(pid_t (*fn)(void))
 {
@@ -3571,7 +3556,6 @@ ATF_TC_BODY(name, tc)							\
 
 TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
 TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
-#endif
 
 /// ----------------------------------------------------------------------------
 
@@ -5496,11 +5480,6 @@ trace_threads(bool trace_create, bool tr
 	/* Track created and exited threads */
 	bool traced_lwps[__arraycount(t)];
 
-#if !TEST_LWP_ENABLED
-	if (trace_create || trace_exit)
-		atf_tc_skip("PR kern/51995");
-#endif
-
 	DPRINTF("Before forking process PID=%d\n", getpid());
 	SYSCALL_REQUIRE((child = fork()) != -1);
 	if (child == 0) {
@@ -6126,13 +6105,11 @@ FORK2_TEST(posix_spawn_singalmasked, "sp
 FORK2_TEST(posix_spawn_singalignored, "spawn", false, true)
 FORK2_TEST(fork_singalmasked, "fork", true, false)
 FORK2_TEST(fork_singalignored, "fork", false, true)
-#if TEST_VFORK_ENABLED
 FORK2_TEST(vfork_singalmasked, "vfork", true, false)
 FORK2_TEST(vfork_singalignored, "vfork", false, true)
 FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false)
 FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true)
 #endif
-#endif
 
 /// ----------------------------------------------------------------------------
 
@@ -6991,7 +6968,6 @@ CLONE_TEST(clone_files8, CLONE_FILES, tr
 //CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true)
 #endif
 
-#if TEST_VFORK_ENABLED
 CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false)
 #if defined(TWAIT_HAVE_PID)
 CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false)
@@ -7004,7 +6980,6 @@ CLONE_TEST(clone_vfork6, CLONE_VFORK, tr
 CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true)
 CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true)
 #endif
-#endif
 
 /// ----------------------------------------------------------------------------
 
@@ -7367,15 +7342,12 @@ CLONE_TEST2(clone_files_signalignored, C
 CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
 //CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
 //CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true)  // XXX
-#if TEST_VFORK_ENABLED
 CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
 CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
 #endif
-#endif
 
 /// ----------------------------------------------------------------------------
 
-#if TEST_VFORK_ENABLED
 #if defined(TWAIT_HAVE_PID)
 static void
 traceme_vfork_clone_body(int flags)
@@ -7456,7 +7428,6 @@ TRACEME_VFORK_CLONE_TEST(traceme_vfork_c
 //TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND)  // XXX
 TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
 #endif
-#endif
 
 /// ----------------------------------------------------------------------------
 
@@ -7722,6 +7693,152 @@ ATF_TC_BODY(core_dump_procinfo, tc)
 
 /// ----------------------------------------------------------------------------
 
+#if defined(TWAIT_HAVE_STATUS)
+
+ATF_TC(thread_concurrent_signals);
+ATF_TC_HEAD(thread_concurrent_signals, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify that concurrent signals issued to a single thread "
+	    "are reported correctly");
+}
+
+/* List of signals to use for the test */
+const int thread_concurrent_signals_list[] = {
+	SIGIO,
+	SIGXCPU,
+	SIGXFSZ,
+	SIGVTALRM,
+	SIGPROF,
+	SIGWINCH,
+	SIGINFO,
+	SIGUSR1,
+	SIGUSR2
+};
+
+pthread_barrier_t thread_concurrent_signals_barrier;
+
+static void *
+thread_concurrent_signals_thread(void *arg)
+{
+	int sigval = thread_concurrent_signals_list[
+	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
+	pthread_barrier_wait(&thread_concurrent_signals_barrier);
+	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
+		_lwp_self());
+	pthread_kill(pthread_self(), sigval);
+	return NULL;
+}
+
+#define THREAD_CONCURRENT_SIGNALS_NUM 50
+
+ATF_TC_BODY(thread_concurrent_signals, tc)
+{
+	const int exitval = 5;
+	const int sigval = SIGSTOP;
+	pid_t child, wpid;
+	int status;
+	int signal_counts[THREAD_CONCURRENT_SIGNALS_NUM] = {0};
+	unsigned int i;
+
+	DPRINTF("Before forking process PID=%d\n", getpid());
+	SYSCALL_REQUIRE((child = fork()) != -1);
+	if (child == 0) {
+		pthread_t threads[THREAD_CONCURRENT_SIGNALS_NUM];
+
+		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
+		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+		DPRINTF("Before raising %s from child\n", strsignal(sigval));
+		FORKEE_ASSERT(raise(sigval) == 0);
+
+		DPRINTF("Before starting threads from the child\n");
+		FORKEE_ASSERT(pthread_barrier_init(
+		    &thread_concurrent_signals_barrier, NULL,
+		    __arraycount(threads)) == 0);
+
+		for (i = 0; i < __arraycount(threads); i++) {
+			FORKEE_ASSERT(pthread_create(&threads[i], NULL,
+			    thread_concurrent_signals_thread, NULL) == 0);
+		}
+
+		DPRINTF("Before joining threads from the child\n");
+		for (i = 0; i < __arraycount(threads); i++) {
+			FORKEE_ASSERT(pthread_join(threads[i], NULL) == 0);
+		}
+
+		FORKEE_ASSERT(pthread_barrier_destroy(
+		    &thread_concurrent_signals_barrier) == 0);
+
+		DPRINTF("Before exiting of the child process\n");
+		_exit(exitval);
+	}
+	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+	validate_status_stopped(status, sigval);
+
+	DPRINTF("Before resuming the child process where it left off\n");
+	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+
+	DPRINTF("Before entering signal collection loop\n");
+	while (1) {
+		ptrace_siginfo_t info;
+		int expected_sig;
+
+		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
+		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
+		    child);
+		if (WIFEXITED(status))
+			break;
+		/* Note: we use validate_status_stopped() to get nice error
+		 * message.  Signal is irrelevant since it won't be reached.
+		 */
+		else if (!WIFSTOPPED(status))
+			validate_status_stopped(status, 0);
+
+		DPRINTF("Before calling PT_GET_SIGINFO\n");
+		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
+		    sizeof(info)) != -1);
+
+		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
+		    info.psi_siginfo.si_signo, info.psi_lwpid,
+		    WSTOPSIG(status));
+
+		expected_sig = thread_concurrent_signals_list[info.psi_lwpid %
+		    __arraycount(thread_concurrent_signals_list)];
+		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, expected_sig,
+		    "lwp=%d, expected %d, got %d", info.psi_lwpid,
+		    expected_sig, info.psi_siginfo.si_signo);
+		ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
+		    "lwp=%d, expected %d, got %d", info.psi_lwpid,
+		    expected_sig, WSTOPSIG(status));
+
+		/* We assume that LWPs will be given successive numbers starting
+		 * from 2.
+		 */
+		ATF_REQUIRE(info.psi_lwpid >= 2);
+		ATF_REQUIRE((unsigned int)info.psi_lwpid <
+		    __arraycount(signal_counts)+2);
+		signal_counts[info.psi_lwpid-2]++;
+
+		DPRINTF("Before resuming the child process\n");
+		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
+	}
+
+	for (i = 0; i < __arraycount(signal_counts); i++)
+		ATF_CHECK_EQ_MSG(signal_counts[i], 1, "signal_counts[%d]=%d",
+		    i, signal_counts[i]);
+
+	validate_status_exited(status, exitval);
+}
+
+#endif /*defined(TWAIT_HAVE_STATUS)*/
+
+/// ----------------------------------------------------------------------------
+
 #include "t_ptrace_amd64_wait.h"
 #include "t_ptrace_i386_wait.h"
 #include "t_ptrace_x86_wait.h"
@@ -7926,7 +8043,6 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork15);
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork16);
 
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC(tp, vfork1);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
@@ -7943,7 +8059,6 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16);
-#endif
 
 	ATF_TP_ADD_TC(tp, posix_spawn1);
 	ATF_TP_ADD_TC(tp, posix_spawn2);
@@ -7964,22 +8079,16 @@ ATF_TP_ADD_TCS(tp)
 
 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner);
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker);
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone);
-#endif
 
 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner);
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker);
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone);
-#endif
 
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC(tp, traceme_vfork_fork);
 	ATF_TP_ADD_TC(tp, traceme_vfork_vfork);
-#endif
 
 	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
 	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
@@ -8110,12 +8219,10 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored);
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked);
 	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored);
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked);
 	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored);
-#endif
 
 	ATF_TP_ADD_TC(tp, signal9);
 	ATF_TP_ADD_TC(tp, signal10);
@@ -8173,7 +8280,6 @@ ATF_TP_ADD_TCS(tp)
 //	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
 //	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
 
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC(tp, clone_vfork1);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3);
@@ -8182,7 +8288,6 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8);
-#endif
 
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked);
@@ -8194,19 +8299,15 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked);
 //	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
 //	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored);
 	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked);
-#endif
 
-#if TEST_VFORK_ENABLED
 	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone);
 	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm);
 	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs);
 	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files);
 //	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
 	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
-#endif
 
 	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
 	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
@@ -8214,6 +8315,10 @@ ATF_TP_ADD_TCS(tp)
 
 	ATF_TP_ADD_TC(tp, core_dump_procinfo);
 
+#if defined(TWAIT_HAVE_STATUS)
+	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
+#endif
+
 	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
 	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
 	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();

Reply via email to