t_ptrace_wait.c revision 1.180
1/*	$NetBSD: t_ptrace_wait.c,v 1.180 2020/05/04 22:34:22 kamil Exp $	*/
2
3/*-
4 * Copyright (c) 2016, 2017, 2018, 2019 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__RCSID("$NetBSD: t_ptrace_wait.c,v 1.180 2020/05/04 22:34:22 kamil Exp $");
31
32#define __LEGACY_PT_LWPINFO
33
34#include <sys/param.h>
35#include <sys/types.h>
36#include <sys/exec_elf.h>
37#include <sys/mman.h>
38#include <sys/ptrace.h>
39#include <sys/resource.h>
40#include <sys/stat.h>
41#include <sys/syscall.h>
42#include <sys/sysctl.h>
43#include <sys/uio.h>
44#include <sys/wait.h>
45#include <machine/reg.h>
46#include <assert.h>
47#include <elf.h>
48#include <err.h>
49#include <errno.h>
50#include <fcntl.h>
51#include <lwp.h>
52#include <pthread.h>
53#include <sched.h>
54#include <signal.h>
55#include <spawn.h>
56#include <stdint.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <strings.h>
60#include <time.h>
61#include <unistd.h>
62
63#if defined(__i386__) || defined(__x86_64__)
64#include <cpuid.h>
65#include <x86/cpu_extended_state.h>
66#include <x86/specialreg.h>
67#endif
68
69#include <libelf.h>
70#include <gelf.h>
71
72#include <atf-c.h>
73
74#ifdef ENABLE_TESTS
75
76/* Assumptions in the kernel code that must be kept. */
77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) ==
78    sizeof(((siginfo_t *)0)->si_pe_report_event));
79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
80    sizeof(((siginfo_t *)0)->si_pe_other_pid));
81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) ==
82    sizeof(((siginfo_t *)0)->si_pe_lwp));
83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
84    sizeof(((struct ptrace_state *)0)->pe_lwp));
85
86#include "h_macros.h"
87
88#include "t_ptrace_wait.h"
89#include "msg.h"
90
91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
92    strerror(errno))
93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
94    "%d(%s) != %d", res, strerror(res), exp)
95
96static int debug = 0;
97
98#define DPRINTF(a, ...)	do  \
99	if (debug) \
100	printf("%s() %d.%d %s:%d " a, \
101	__func__, getpid(), _lwp_self(), __FILE__, __LINE__,  ##__VA_ARGS__); \
102    while (/*CONSTCOND*/0)
103
104/// ----------------------------------------------------------------------------
105
106static void
107traceme_raise(int sigval)
108{
109	const int exitval = 5;
110	pid_t child, wpid;
111#if defined(TWAIT_HAVE_STATUS)
112	int status;
113#endif
114
115	ptrace_state_t state, zero_state;
116	const int slen = sizeof(state);
117	struct ptrace_siginfo info;
118	memset(&zero_state, 0, sizeof(zero_state));
119	memset(&info, 0, sizeof(info));
120
121	DPRINTF("Before forking process PID=%d\n", getpid());
122	SYSCALL_REQUIRE((child = fork()) != -1);
123	if (child == 0) {
124		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
125		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
126
127		DPRINTF("Before raising %s from child\n", strsignal(sigval));
128		FORKEE_ASSERT(raise(sigval) == 0);
129
130		switch (sigval) {
131		case SIGKILL:
132			/* NOTREACHED */
133			FORKEE_ASSERTX(0 && "This shall not be reached");
134			__unreachable();
135		default:
136			DPRINTF("Before exiting of the child process\n");
137			_exit(exitval);
138		}
139	}
140	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
141
142	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
143	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
144
145	switch (sigval) {
146	case SIGKILL:
147		validate_status_signaled(status, sigval, 0);
148		SYSCALL_REQUIRE(
149		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) == -1);
150
151		break;
152	default:
153		validate_status_stopped(status, sigval);
154
155		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
156			"child\n");
157		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
158			sizeof(info)) != -1);
159
160		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
161		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
162			"si_errno=%#x\n",
163			info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
164			info.psi_siginfo.si_errno);
165
166		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
167		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
168
169		DPRINTF("Assert that PT_GET_PROCESS_STATE returns non-error");
170		SYSCALL_REQUIRE(
171		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
172		ATF_REQUIRE(memcmp(&state, &zero_state, slen) == 0);
173
174		DPRINTF("Before resuming the child process where it left off "
175		    "and without signal to be sent\n");
176		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
177
178		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
179		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
180		    child);
181		break;
182	}
183
184	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
185	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
186}
187
188#define TRACEME_RAISE(test, sig)					\
189ATF_TC(test);								\
190ATF_TC_HEAD(test, tc)							\
191{									\
192	atf_tc_set_md_var(tc, "descr",					\
193	    "Verify " #sig " followed by _exit(2) in a child");		\
194}									\
195									\
196ATF_TC_BODY(test, tc)							\
197{									\
198									\
199	traceme_raise(sig);						\
200}
201
202TRACEME_RAISE(traceme_raise1, SIGKILL) /* non-maskable */
203TRACEME_RAISE(traceme_raise2, SIGSTOP) /* non-maskable */
204TRACEME_RAISE(traceme_raise3, SIGABRT) /* regular abort trap */
205TRACEME_RAISE(traceme_raise4, SIGHUP)  /* hangup */
206TRACEME_RAISE(traceme_raise5, SIGCONT) /* continued? */
207TRACEME_RAISE(traceme_raise6, SIGTRAP) /* crash signal */
208TRACEME_RAISE(traceme_raise7, SIGBUS) /* crash signal */
209TRACEME_RAISE(traceme_raise8, SIGILL) /* crash signal */
210TRACEME_RAISE(traceme_raise9, SIGFPE) /* crash signal */
211TRACEME_RAISE(traceme_raise10, SIGSEGV) /* crash signal */
212
213/// ----------------------------------------------------------------------------
214
215static void
216traceme_raisesignal_ignored(int sigignored)
217{
218	const int exitval = 5;
219	const int sigval = SIGSTOP;
220	pid_t child, wpid;
221	struct sigaction sa;
222#if defined(TWAIT_HAVE_STATUS)
223	int status;
224#endif
225	struct ptrace_siginfo info;
226
227	memset(&info, 0, sizeof(info));
228
229	DPRINTF("Before forking process PID=%d\n", getpid());
230	SYSCALL_REQUIRE((child = fork()) != -1);
231	if (child == 0) {
232		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
233		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
234
235		memset(&sa, 0, sizeof(sa));
236		sa.sa_handler = SIG_IGN;
237		sigemptyset(&sa.sa_mask);
238		FORKEE_ASSERT(sigaction(sigignored, &sa, NULL) != -1);
239
240		DPRINTF("Before raising %s from child\n", strsignal(sigval));
241		FORKEE_ASSERT(raise(sigval) == 0);
242
243		DPRINTF("Before raising %s from child\n",
244		    strsignal(sigignored));
245		FORKEE_ASSERT(raise(sigignored) == 0);
246
247		DPRINTF("Before exiting of the child process\n");
248		_exit(exitval);
249	}
250	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
251
252	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
253	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
254
255	validate_status_stopped(status, sigval);
256
257	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
258	SYSCALL_REQUIRE(
259	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
260
261	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
262	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
263	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
264	    info.psi_siginfo.si_errno);
265
266	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
267	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
268
269	DPRINTF("Before resuming the child process where it left off and "
270	    "without signal to be sent\n");
271	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
272
273	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
274	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
275
276	validate_status_stopped(status, sigignored);
277
278	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
279	SYSCALL_REQUIRE(
280	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
281
282	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
283	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
284	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
285	    info.psi_siginfo.si_errno);
286
287	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigignored);
288	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
289
290	DPRINTF("Before resuming the child process where it left off and "
291	    "without signal to be sent\n");
292	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
293
294	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
295	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
296
297	validate_status_exited(status, exitval);
298
299	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
300	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
301}
302
303#define TRACEME_RAISESIGNAL_IGNORED(test, sig)				\
304ATF_TC(test);								\
305ATF_TC_HEAD(test, tc)							\
306{									\
307	atf_tc_set_md_var(tc, "descr",					\
308	    "Verify that ignoring (with SIG_IGN) " #sig " in tracee "	\
309	    "does not stop tracer from catching this raised signal");	\
310}									\
311									\
312ATF_TC_BODY(test, tc)							\
313{									\
314									\
315	traceme_raisesignal_ignored(sig);				\
316}
317
318// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
319TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored1, SIGABRT) /* abort */
320TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored2, SIGHUP)  /* hangup */
321TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored3, SIGCONT) /* cont. */
322TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored4, SIGTRAP) /* crash */
323TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored5, SIGBUS) /* crash */
324TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored6, SIGILL) /* crash */
325TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored7, SIGFPE) /* crash */
326TRACEME_RAISESIGNAL_IGNORED(traceme_raisesignal_ignored8, SIGSEGV) /* crash */
327
328/// ----------------------------------------------------------------------------
329
330static void
331traceme_raisesignal_masked(int sigmasked)
332{
333	const int exitval = 5;
334	const int sigval = SIGSTOP;
335	pid_t child, wpid;
336#if defined(TWAIT_HAVE_STATUS)
337	int status;
338#endif
339	sigset_t intmask;
340	struct ptrace_siginfo info;
341
342	memset(&info, 0, sizeof(info));
343
344	DPRINTF("Before forking process PID=%d\n", getpid());
345	SYSCALL_REQUIRE((child = fork()) != -1);
346	if (child == 0) {
347		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
348		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
349
350		sigemptyset(&intmask);
351		sigaddset(&intmask, sigmasked);
352		sigprocmask(SIG_BLOCK, &intmask, NULL);
353
354		DPRINTF("Before raising %s from child\n", strsignal(sigval));
355		FORKEE_ASSERT(raise(sigval) == 0);
356
357		DPRINTF("Before raising %s breakpoint from child\n",
358		    strsignal(sigmasked));
359		FORKEE_ASSERT(raise(sigmasked) == 0);
360
361		DPRINTF("Before exiting of the child process\n");
362		_exit(exitval);
363	}
364	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
365
366	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
367	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
368
369	validate_status_stopped(status, sigval);
370
371	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
372	SYSCALL_REQUIRE(
373	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
374
375	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
376	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
377	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
378	    info.psi_siginfo.si_errno);
379
380	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
381	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
382
383	DPRINTF("Before resuming the child process where it left off and "
384	    "without signal to be sent\n");
385	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
386
387	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
388	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
389
390	validate_status_exited(status, exitval);
391
392	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
393	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
394}
395
396#define TRACEME_RAISESIGNAL_MASKED(test, sig)				\
397ATF_TC(test);								\
398ATF_TC_HEAD(test, tc)							\
399{									\
400	atf_tc_set_md_var(tc, "descr",					\
401	    "Verify that masking (with SIG_BLOCK) " #sig " in tracee "	\
402	    "stops tracer from catching this raised signal");		\
403}									\
404									\
405ATF_TC_BODY(test, tc)							\
406{									\
407									\
408	traceme_raisesignal_masked(sig);				\
409}
410
411// A signal handler for SIGKILL and SIGSTOP cannot be masked.
412TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked1, SIGABRT) /* abort trap */
413TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked2, SIGHUP)  /* hangup */
414TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked3, SIGCONT) /* continued? */
415TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked4, SIGTRAP) /* crash sig. */
416TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked5, SIGBUS) /* crash sig. */
417TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked6, SIGILL) /* crash sig. */
418TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked7, SIGFPE) /* crash sig. */
419TRACEME_RAISESIGNAL_MASKED(traceme_raisesignal_masked8, SIGSEGV) /* crash sig. */
420
421/// ----------------------------------------------------------------------------
422
423static void
424traceme_crash(int sig)
425{
426	pid_t child, wpid;
427#if defined(TWAIT_HAVE_STATUS)
428	int status;
429#endif
430	struct ptrace_siginfo info;
431
432#ifndef PTRACE_ILLEGAL_ASM
433	if (sig == SIGILL)
434		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
435#endif
436
437	if (sig == SIGFPE && !are_fpu_exceptions_supported())
438		atf_tc_skip("FP exceptions are not supported");
439
440	memset(&info, 0, sizeof(info));
441
442	DPRINTF("Before forking process PID=%d\n", getpid());
443	SYSCALL_REQUIRE((child = fork()) != -1);
444	if (child == 0) {
445		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
446		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
447
448		DPRINTF("Before executing a trap\n");
449		switch (sig) {
450		case SIGTRAP:
451			trigger_trap();
452			break;
453		case SIGSEGV:
454			trigger_segv();
455			break;
456		case SIGILL:
457			trigger_ill();
458			break;
459		case SIGFPE:
460			trigger_fpe();
461			break;
462		case SIGBUS:
463			trigger_bus();
464			break;
465		default:
466			/* NOTREACHED */
467			FORKEE_ASSERTX(0 && "This shall not be reached");
468		}
469
470		/* NOTREACHED */
471		FORKEE_ASSERTX(0 && "This shall not be reached");
472	}
473	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
474
475	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
476	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
477
478	validate_status_stopped(status, sig);
479
480	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
481	SYSCALL_REQUIRE(
482	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
483
484	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
485	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
486	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
487	    info.psi_siginfo.si_errno);
488
489	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
490	switch (sig) {
491	case SIGTRAP:
492		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
493		break;
494	case SIGSEGV:
495		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
496		break;
497	case SIGILL:
498		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
499		            info.psi_siginfo.si_code <= ILL_BADSTK);
500		break;
501	case SIGFPE:
502		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
503		break;
504	case SIGBUS:
505		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
506		break;
507	}
508
509	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
510
511	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
512	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
513
514	validate_status_signaled(status, SIGKILL, 0);
515
516	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
517	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
518}
519
520#define TRACEME_CRASH(test, sig)					\
521ATF_TC(test);								\
522ATF_TC_HEAD(test, tc)							\
523{									\
524	atf_tc_set_md_var(tc, "descr",					\
525	    "Verify crash signal " #sig " in a child after PT_TRACE_ME"); \
526}									\
527									\
528ATF_TC_BODY(test, tc)							\
529{									\
530									\
531	traceme_crash(sig);						\
532}
533
534TRACEME_CRASH(traceme_crash_trap, SIGTRAP)
535TRACEME_CRASH(traceme_crash_segv, SIGSEGV)
536TRACEME_CRASH(traceme_crash_ill, SIGILL)
537TRACEME_CRASH(traceme_crash_fpe, SIGFPE)
538TRACEME_CRASH(traceme_crash_bus, SIGBUS)
539
540/// ----------------------------------------------------------------------------
541
542static void
543traceme_signalmasked_crash(int sig)
544{
545	const int sigval = SIGSTOP;
546	pid_t child, wpid;
547#if defined(TWAIT_HAVE_STATUS)
548	int status;
549#endif
550	struct ptrace_siginfo info;
551	sigset_t intmask;
552	struct kinfo_proc2 kp;
553	size_t len = sizeof(kp);
554
555	int name[6];
556	const size_t namelen = __arraycount(name);
557	ki_sigset_t kp_sigmask;
558
559#ifndef PTRACE_ILLEGAL_ASM
560	if (sig == SIGILL)
561		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
562#endif
563
564	if (sig == SIGFPE && !are_fpu_exceptions_supported())
565		atf_tc_skip("FP exceptions are not supported");
566
567	memset(&info, 0, sizeof(info));
568
569	DPRINTF("Before forking process PID=%d\n", getpid());
570	SYSCALL_REQUIRE((child = fork()) != -1);
571	if (child == 0) {
572		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
573		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
574
575		sigemptyset(&intmask);
576		sigaddset(&intmask, sig);
577		sigprocmask(SIG_BLOCK, &intmask, NULL);
578
579		DPRINTF("Before raising %s from child\n", strsignal(sigval));
580		FORKEE_ASSERT(raise(sigval) == 0);
581
582		DPRINTF("Before executing a trap\n");
583		switch (sig) {
584		case SIGTRAP:
585			trigger_trap();
586			break;
587		case SIGSEGV:
588			trigger_segv();
589			break;
590		case SIGILL:
591			trigger_ill();
592			break;
593		case SIGFPE:
594			trigger_fpe();
595			break;
596		case SIGBUS:
597			trigger_bus();
598			break;
599		default:
600			/* NOTREACHED */
601			FORKEE_ASSERTX(0 && "This shall not be reached");
602		}
603
604		/* NOTREACHED */
605		FORKEE_ASSERTX(0 && "This shall not be reached");
606	}
607	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
608
609	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
610	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
611
612	validate_status_stopped(status, sigval);
613
614	name[0] = CTL_KERN,
615	name[1] = KERN_PROC2,
616	name[2] = KERN_PROC_PID;
617	name[3] = child;
618	name[4] = sizeof(kp);
619	name[5] = 1;
620
621	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
622
623	kp_sigmask = kp.p_sigmask;
624
625	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
626	SYSCALL_REQUIRE(
627	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
628
629	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
630	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
631	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
632	    info.psi_siginfo.si_errno);
633
634	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
635	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
636
637	DPRINTF("Before resuming the child process where it left off and "
638	    "without signal to be sent\n");
639	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
640
641	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
642	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
643
644	validate_status_stopped(status, sig);
645
646	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
647	SYSCALL_REQUIRE(
648	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
649
650	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
651	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
652	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
653	    info.psi_siginfo.si_errno);
654
655	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
656
657	DPRINTF("kp_sigmask="
658	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
659	    kp_sigmask.__bits[0], kp_sigmask.__bits[1], kp_sigmask.__bits[2],
660	    kp_sigmask.__bits[3]);
661
662	DPRINTF("kp.p_sigmask="
663	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
664	    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
665	    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
666
667	ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask, sizeof(kp_sigmask)));
668
669	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
670	switch (sig) {
671	case SIGTRAP:
672		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
673		break;
674	case SIGSEGV:
675		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
676		break;
677	case SIGILL:
678		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
679		            info.psi_siginfo.si_code <= ILL_BADSTK);
680		break;
681	case SIGFPE:
682		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
683		break;
684	case SIGBUS:
685		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
686		break;
687	}
688
689	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
690
691	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
692	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
693
694	validate_status_signaled(status, SIGKILL, 0);
695
696	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
697	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
698}
699
700#define TRACEME_SIGNALMASKED_CRASH(test, sig)				\
701ATF_TC(test);								\
702ATF_TC_HEAD(test, tc)							\
703{									\
704	atf_tc_set_md_var(tc, "descr",					\
705	    "Verify masked crash signal " #sig " in a child after "	\
706	    "PT_TRACE_ME is delivered to its tracer");			\
707}									\
708									\
709ATF_TC_BODY(test, tc)							\
710{									\
711									\
712	traceme_signalmasked_crash(sig);				\
713}
714
715TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_trap, SIGTRAP)
716TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_segv, SIGSEGV)
717TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_ill, SIGILL)
718TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_fpe, SIGFPE)
719TRACEME_SIGNALMASKED_CRASH(traceme_signalmasked_crash_bus, SIGBUS)
720
721/// ----------------------------------------------------------------------------
722
723static void
724traceme_signalignored_crash(int sig)
725{
726	const int sigval = SIGSTOP;
727	pid_t child, wpid;
728#if defined(TWAIT_HAVE_STATUS)
729	int status;
730#endif
731	struct sigaction sa;
732	struct ptrace_siginfo info;
733	struct kinfo_proc2 kp;
734	size_t len = sizeof(kp);
735
736	int name[6];
737	const size_t namelen = __arraycount(name);
738	ki_sigset_t kp_sigignore;
739
740#ifndef PTRACE_ILLEGAL_ASM
741	if (sig == SIGILL)
742		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
743#endif
744
745	if (sig == SIGFPE && !are_fpu_exceptions_supported())
746		atf_tc_skip("FP exceptions are not supported");
747
748	memset(&info, 0, sizeof(info));
749
750	DPRINTF("Before forking process PID=%d\n", getpid());
751	SYSCALL_REQUIRE((child = fork()) != -1);
752	if (child == 0) {
753		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
754		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
755
756		memset(&sa, 0, sizeof(sa));
757		sa.sa_handler = SIG_IGN;
758		sigemptyset(&sa.sa_mask);
759
760		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
761
762		DPRINTF("Before raising %s from child\n", strsignal(sigval));
763		FORKEE_ASSERT(raise(sigval) == 0);
764
765		DPRINTF("Before executing a trap\n");
766		switch (sig) {
767		case SIGTRAP:
768			trigger_trap();
769			break;
770		case SIGSEGV:
771			trigger_segv();
772			break;
773		case SIGILL:
774			trigger_ill();
775			break;
776		case SIGFPE:
777			trigger_fpe();
778			break;
779		case SIGBUS:
780			trigger_bus();
781			break;
782		default:
783			/* NOTREACHED */
784			FORKEE_ASSERTX(0 && "This shall not be reached");
785		}
786
787		/* NOTREACHED */
788		FORKEE_ASSERTX(0 && "This shall not be reached");
789	}
790	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
791
792	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
793	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
794
795	validate_status_stopped(status, sigval);
796
797	name[0] = CTL_KERN,
798	name[1] = KERN_PROC2,
799	name[2] = KERN_PROC_PID;
800	name[3] = child;
801	name[4] = sizeof(kp);
802	name[5] = 1;
803
804	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
805
806	kp_sigignore = kp.p_sigignore;
807
808	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
809	SYSCALL_REQUIRE(
810	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
811
812	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
813	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
814	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
815	    info.psi_siginfo.si_errno);
816
817	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
818	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
819
820	DPRINTF("Before resuming the child process where it left off and "
821	    "without signal to be sent\n");
822	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
823
824	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
825	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
826
827	validate_status_stopped(status, sig);
828
829	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
830	SYSCALL_REQUIRE(
831	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
832
833	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
834	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
835	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
836	    info.psi_siginfo.si_errno);
837
838	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
839
840	DPRINTF("kp_sigignore="
841	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
842	    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
843	    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
844
845	DPRINTF("kp.p_sigignore="
846	    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
847	    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
848	    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
849
850	ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore, sizeof(kp_sigignore)));
851
852	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sig);
853	switch (sig) {
854	case SIGTRAP:
855		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
856		break;
857	case SIGSEGV:
858		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
859		break;
860	case SIGILL:
861		ATF_REQUIRE(info.psi_siginfo.si_code >= ILL_ILLOPC &&
862		            info.psi_siginfo.si_code <= ILL_BADSTK);
863		break;
864	case SIGFPE:
865		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
866		break;
867	case SIGBUS:
868		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
869		break;
870	}
871
872	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
873
874	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
875	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
876
877	validate_status_signaled(status, SIGKILL, 0);
878
879	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
880	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
881}
882
883#define TRACEME_SIGNALIGNORED_CRASH(test, sig)				\
884ATF_TC(test);								\
885ATF_TC_HEAD(test, tc)							\
886{									\
887	atf_tc_set_md_var(tc, "descr",					\
888	    "Verify ignored crash signal " #sig " in a child after "	\
889	    "PT_TRACE_ME is delivered to its tracer"); 			\
890}									\
891									\
892ATF_TC_BODY(test, tc)							\
893{									\
894									\
895	traceme_signalignored_crash(sig);				\
896}
897
898TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_trap, SIGTRAP)
899TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_segv, SIGSEGV)
900TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_ill, SIGILL)
901TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_fpe, SIGFPE)
902TRACEME_SIGNALIGNORED_CRASH(traceme_signalignored_crash_bus, SIGBUS)
903
904/// ----------------------------------------------------------------------------
905
906static void
907traceme_sendsignal_handle(int sigsent, void (*sah)(int a), int *traceme_caught)
908{
909	const int exitval = 5;
910	const int sigval = SIGSTOP;
911	pid_t child, wpid;
912	struct sigaction sa;
913#if defined(TWAIT_HAVE_STATUS)
914	int status;
915#endif
916	struct ptrace_siginfo info;
917
918	memset(&info, 0, sizeof(info));
919
920	DPRINTF("Before forking process PID=%d\n", getpid());
921	SYSCALL_REQUIRE((child = fork()) != -1);
922	if (child == 0) {
923		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
924		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
925
926		sa.sa_handler = sah;
927		sa.sa_flags = SA_SIGINFO;
928		sigemptyset(&sa.sa_mask);
929
930		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
931
932		DPRINTF("Before raising %s from child\n", strsignal(sigval));
933		FORKEE_ASSERT(raise(sigval) == 0);
934
935		FORKEE_ASSERT_EQ(*traceme_caught, 1);
936
937		DPRINTF("Before exiting of the child process\n");
938		_exit(exitval);
939	}
940	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
941
942	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
943	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
944
945	validate_status_stopped(status, sigval);
946
947	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
948	SYSCALL_REQUIRE(
949	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
950
951	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
952	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
953	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
954	    info.psi_siginfo.si_errno);
955
956	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
957	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
958
959	DPRINTF("Before resuming the child process where it left off and with "
960	    "signal %s to be sent\n", strsignal(sigsent));
961	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
962
963	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
964	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
965
966	validate_status_exited(status, exitval);
967
968	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
969	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
970}
971
972#define TRACEME_SENDSIGNAL_HANDLE(test, sig)				\
973ATF_TC(test);								\
974ATF_TC_HEAD(test, tc)							\
975{									\
976	atf_tc_set_md_var(tc, "descr",					\
977	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
978	    "handled correctly and caught by a signal handler");	\
979}									\
980									\
981static int test##_caught = 0;						\
982									\
983static void								\
984test##_sighandler(int arg)						\
985{									\
986	FORKEE_ASSERT_EQ(arg, sig);					\
987									\
988	++ test##_caught;						\
989}									\
990									\
991ATF_TC_BODY(test, tc)							\
992{									\
993									\
994	traceme_sendsignal_handle(sig, test##_sighandler, & test##_caught); \
995}
996
997// A signal handler for SIGKILL and SIGSTOP cannot be registered.
998TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle1, SIGABRT) /* abort trap */
999TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle2, SIGHUP)  /* hangup */
1000TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle3, SIGCONT) /* continued? */
1001TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle4, SIGTRAP) /* crash sig. */
1002TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle5, SIGBUS) /* crash sig. */
1003TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle6, SIGILL) /* crash sig. */
1004TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle7, SIGFPE) /* crash sig. */
1005TRACEME_SENDSIGNAL_HANDLE(traceme_sendsignal_handle8, SIGSEGV) /* crash sig. */
1006
1007/// ----------------------------------------------------------------------------
1008
1009static void
1010traceme_sendsignal_masked(int sigsent)
1011{
1012	const int exitval = 5;
1013	const int sigval = SIGSTOP;
1014	pid_t child, wpid;
1015	sigset_t set;
1016#if defined(TWAIT_HAVE_STATUS)
1017	int status;
1018#endif
1019	struct ptrace_siginfo info;
1020
1021	memset(&info, 0, sizeof(info));
1022
1023	DPRINTF("Before forking process PID=%d\n", getpid());
1024	SYSCALL_REQUIRE((child = fork()) != -1);
1025	if (child == 0) {
1026		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1027		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1028
1029		sigemptyset(&set);
1030		sigaddset(&set, sigsent);
1031		FORKEE_ASSERT(sigprocmask(SIG_BLOCK, &set, NULL) != -1);
1032
1033		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1034		FORKEE_ASSERT(raise(sigval) == 0);
1035
1036		_exit(exitval);
1037	}
1038	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1039
1040	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1041	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1042
1043	validate_status_stopped(status, sigval);
1044
1045	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1046	SYSCALL_REQUIRE(
1047	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1048
1049	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1050	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1051	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1052	    info.psi_siginfo.si_errno);
1053
1054	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1055	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1056
1057	DPRINTF("Before resuming the child process where it left off and with "
1058	    "signal %s to be sent\n", strsignal(sigsent));
1059	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1060
1061	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1062	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1063
1064	validate_status_exited(status, exitval);
1065
1066	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1067	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1068}
1069
1070#define TRACEME_SENDSIGNAL_MASKED(test, sig)				\
1071ATF_TC(test);								\
1072ATF_TC_HEAD(test, tc)							\
1073{									\
1074	atf_tc_set_md_var(tc, "descr",					\
1075	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1076	    "handled correctly and the signal is masked by SIG_BLOCK");	\
1077}									\
1078									\
1079ATF_TC_BODY(test, tc)							\
1080{									\
1081									\
1082	traceme_sendsignal_masked(sig);					\
1083}
1084
1085// A signal handler for SIGKILL and SIGSTOP cannot be masked.
1086TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked1, SIGABRT) /* abort trap */
1087TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked2, SIGHUP)  /* hangup */
1088TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked3, SIGCONT) /* continued? */
1089TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked4, SIGTRAP) /* crash sig. */
1090TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked5, SIGBUS) /* crash sig. */
1091TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked6, SIGILL) /* crash sig. */
1092TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked7, SIGFPE) /* crash sig. */
1093TRACEME_SENDSIGNAL_MASKED(traceme_sendsignal_masked8, SIGSEGV) /* crash sig. */
1094
1095/// ----------------------------------------------------------------------------
1096
1097static void
1098traceme_sendsignal_ignored(int sigsent)
1099{
1100	const int exitval = 5;
1101	const int sigval = SIGSTOP;
1102	pid_t child, wpid;
1103	struct sigaction sa;
1104#if defined(TWAIT_HAVE_STATUS)
1105	int status;
1106#endif
1107	struct ptrace_siginfo info;
1108
1109	memset(&info, 0, sizeof(info));
1110
1111	DPRINTF("Before forking process PID=%d\n", getpid());
1112	SYSCALL_REQUIRE((child = fork()) != -1);
1113	if (child == 0) {
1114		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1115
1116		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1117
1118		memset(&sa, 0, sizeof(sa));
1119		sa.sa_handler = SIG_IGN;
1120		sigemptyset(&sa.sa_mask);
1121		FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1);
1122
1123		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1124		FORKEE_ASSERT(raise(sigval) == 0);
1125
1126		_exit(exitval);
1127	}
1128	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1129
1130	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1131	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1132
1133	validate_status_stopped(status, sigval);
1134
1135	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1136	SYSCALL_REQUIRE(
1137	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1138
1139	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1140	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1141	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1142	    info.psi_siginfo.si_errno);
1143
1144	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1145	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1146
1147	DPRINTF("Before resuming the child process where it left off and with "
1148	    "signal %s to be sent\n", strsignal(sigsent));
1149	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1150
1151	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1152	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1153
1154	validate_status_exited(status, exitval);
1155
1156	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1157	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1158}
1159
1160#define TRACEME_SENDSIGNAL_IGNORED(test, sig)				\
1161ATF_TC(test);								\
1162ATF_TC_HEAD(test, tc)							\
1163{									\
1164	atf_tc_set_md_var(tc, "descr",					\
1165	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1166	    "handled correctly and the signal is masked by SIG_IGN");	\
1167}									\
1168									\
1169ATF_TC_BODY(test, tc)							\
1170{									\
1171									\
1172	traceme_sendsignal_ignored(sig);				\
1173}
1174
1175// A signal handler for SIGKILL and SIGSTOP cannot be ignored.
1176TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored1, SIGABRT) /* abort */
1177TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored2, SIGHUP)  /* hangup */
1178TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored3, SIGCONT) /* continued */
1179TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored4, SIGTRAP) /* crash s. */
1180TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored5, SIGBUS) /* crash s. */
1181TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored6, SIGILL) /* crash s. */
1182TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored7, SIGFPE) /* crash s. */
1183TRACEME_SENDSIGNAL_IGNORED(traceme_sendsignal_ignored8, SIGSEGV) /* crash s. */
1184
1185/// ----------------------------------------------------------------------------
1186
1187static void
1188traceme_sendsignal_simple(int sigsent)
1189{
1190	const int sigval = SIGSTOP;
1191	int exitval = 0;
1192	pid_t child, wpid;
1193#if defined(TWAIT_HAVE_STATUS)
1194	int status;
1195	int expect_core;
1196
1197	switch (sigsent) {
1198	case SIGABRT:
1199	case SIGTRAP:
1200	case SIGBUS:
1201	case SIGILL:
1202	case SIGFPE:
1203	case SIGSEGV:
1204		expect_core = 1;
1205		break;
1206	default:
1207		expect_core = 0;
1208		break;
1209	}
1210#endif
1211	struct ptrace_siginfo info;
1212
1213	memset(&info, 0, sizeof(info));
1214
1215	DPRINTF("Before forking process PID=%d\n", getpid());
1216	SYSCALL_REQUIRE((child = fork()) != -1);
1217	if (child == 0) {
1218		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1219		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1220
1221		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1222		FORKEE_ASSERT(raise(sigval) == 0);
1223
1224		switch (sigsent) {
1225		case SIGCONT:
1226		case SIGSTOP:
1227			_exit(exitval);
1228		default:
1229			/* NOTREACHED */
1230			FORKEE_ASSERTX(0 && "This shall not be reached");
1231		}
1232	}
1233	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1234
1235	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1236	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1237
1238	validate_status_stopped(status, sigval);
1239
1240	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1241	SYSCALL_REQUIRE(
1242	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1243
1244	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1245	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1246	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1247	    info.psi_siginfo.si_errno);
1248
1249	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1250	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1251
1252	DPRINTF("Before resuming the child process where it left off and with "
1253	    "signal %s to be sent\n", strsignal(sigsent));
1254	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1);
1255
1256	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1257	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1258
1259	switch (sigsent) {
1260	case SIGSTOP:
1261		validate_status_stopped(status, sigsent);
1262		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1263		    "child\n");
1264		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1265		    sizeof(info)) != -1);
1266
1267		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1268		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1269		    "si_errno=%#x\n",
1270		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1271		    info.psi_siginfo.si_errno);
1272
1273		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1274		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1275
1276		DPRINTF("Before resuming the child process where it left off "
1277		    "and with signal %s to be sent\n", strsignal(sigsent));
1278		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1279
1280		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1281		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1282		    child);
1283		/* FALLTHROUGH */
1284	case SIGCONT:
1285		validate_status_exited(status, exitval);
1286		break;
1287	default:
1288		validate_status_signaled(status, sigsent, expect_core);
1289		break;
1290	}
1291
1292	DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
1293	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1294}
1295
1296#define TRACEME_SENDSIGNAL_SIMPLE(test, sig)				\
1297ATF_TC(test);								\
1298ATF_TC_HEAD(test, tc)							\
1299{									\
1300	atf_tc_set_md_var(tc, "descr",					\
1301	    "Verify that a signal " #sig " emitted by a tracer to a child is " \
1302	    "handled correctly in a child without a signal handler");	\
1303}									\
1304									\
1305ATF_TC_BODY(test, tc)							\
1306{									\
1307									\
1308	traceme_sendsignal_simple(sig);					\
1309}
1310
1311TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple1, SIGKILL) /* non-maskable*/
1312TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple2, SIGSTOP) /* non-maskable*/
1313TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple3, SIGABRT) /* abort trap */
1314TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple4, SIGHUP)  /* hangup */
1315TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple5, SIGCONT) /* continued? */
1316TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple6, SIGTRAP) /* crash sig. */
1317TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple7, SIGBUS) /* crash sig. */
1318TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple8, SIGILL) /* crash sig. */
1319TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple9, SIGFPE) /* crash sig. */
1320TRACEME_SENDSIGNAL_SIMPLE(traceme_sendsignal_simple10, SIGSEGV) /* crash sig. */
1321
1322/// ----------------------------------------------------------------------------
1323
1324ATF_TC(traceme_pid1_parent);
1325ATF_TC_HEAD(traceme_pid1_parent, tc)
1326{
1327	atf_tc_set_md_var(tc, "descr",
1328	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
1329}
1330
1331ATF_TC_BODY(traceme_pid1_parent, tc)
1332{
1333	struct msg_fds parent_child;
1334	int exitval_child1 = 1, exitval_child2 = 2;
1335	pid_t child1, child2, wpid;
1336	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1337#if defined(TWAIT_HAVE_STATUS)
1338	int status;
1339#endif
1340
1341	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
1342
1343	DPRINTF("Before forking process PID=%d\n", getpid());
1344	SYSCALL_REQUIRE((child1 = fork()) != -1);
1345	if (child1 == 0) {
1346		DPRINTF("Before forking process PID=%d\n", getpid());
1347		SYSCALL_REQUIRE((child2 = fork()) != -1);
1348		if (child2 != 0) {
1349			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
1350			    getpid(), child2);
1351			_exit(exitval_child1);
1352		}
1353		CHILD_FROM_PARENT("exit child1", parent_child, msg);
1354
1355		DPRINTF("Assert that our parent is PID1 (initproc)\n");
1356		FORKEE_ASSERT_EQ(getppid(), 1);
1357
1358		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1359		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
1360		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
1361
1362		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
1363
1364		_exit(exitval_child2);
1365	}
1366	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
1367
1368	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1369	TWAIT_REQUIRE_SUCCESS(
1370	    wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1);
1371
1372	validate_status_exited(status, exitval_child1);
1373
1374	DPRINTF("Notify that child1 is dead\n");
1375	PARENT_TO_CHILD("exit child1", parent_child, msg);
1376
1377	DPRINTF("Wait for exiting of child2\n");
1378	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
1379}
1380
1381/// ----------------------------------------------------------------------------
1382
1383static void
1384traceme_vfork_raise(int sigval)
1385{
1386	const int exitval = 5, exitval_watcher = 10;
1387	pid_t child, parent, watcher, wpid;
1388	int rv;
1389#if defined(TWAIT_HAVE_STATUS)
1390	int status;
1391
1392	/* volatile workarounds GCC -Werror=clobbered */
1393	volatile int expect_core;
1394
1395	switch (sigval) {
1396	case SIGABRT:
1397	case SIGTRAP:
1398	case SIGBUS:
1399	case SIGILL:
1400	case SIGFPE:
1401	case SIGSEGV:
1402		expect_core = 1;
1403		break;
1404	default:
1405		expect_core = 0;
1406		break;
1407	}
1408#endif
1409
1410	/*
1411	 * Spawn a dedicated thread to watch for a stopped child and emit
1412	 * the SIGKILL signal to it.
1413	 *
1414	 * vfork(2) might clobber watcher, this means that it's safer and
1415	 * simpler to reparent this process to initproc and forget about it.
1416	 */
1417	if (sigval == SIGSTOP) {
1418		parent = getpid();
1419
1420		watcher = fork();
1421		ATF_REQUIRE(watcher != 1);
1422		if (watcher == 0) {
1423			/* Double fork(2) trick to reparent to initproc */
1424			watcher = fork();
1425			FORKEE_ASSERT_NEQ(watcher, -1);
1426			if (watcher != 0)
1427				_exit(exitval_watcher);
1428
1429			child = await_stopped_child(parent);
1430
1431			errno = 0;
1432			rv = kill(child, SIGKILL);
1433			FORKEE_ASSERT_EQ(rv, 0);
1434			FORKEE_ASSERT_EQ(errno, 0);
1435
1436			/* This exit value will be collected by initproc */
1437			_exit(0);
1438		}
1439		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1440		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(watcher, &status, 0),
1441		    watcher);
1442
1443		validate_status_exited(status, exitval_watcher);
1444
1445		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1446		TWAIT_REQUIRE_FAILURE(ECHILD,
1447		    wpid = TWAIT_GENERIC(watcher, &status, 0));
1448	}
1449
1450	DPRINTF("Before forking process PID=%d\n", getpid());
1451	SYSCALL_REQUIRE((child = vfork()) != -1);
1452	if (child == 0) {
1453		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1454		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1455
1456		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1457		FORKEE_ASSERT(raise(sigval) == 0);
1458
1459		switch (sigval) {
1460		case SIGSTOP:
1461		case SIGKILL:
1462		case SIGABRT:
1463		case SIGHUP:
1464		case SIGTRAP:
1465		case SIGBUS:
1466		case SIGILL:
1467		case SIGFPE:
1468		case SIGSEGV:
1469			/* NOTREACHED */
1470			FORKEE_ASSERTX(0 && "This shall not be reached");
1471			__unreachable();
1472		default:
1473			DPRINTF("Before exiting of the child process\n");
1474			_exit(exitval);
1475		}
1476	}
1477	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1478
1479	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1480	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1481
1482	switch (sigval) {
1483	case SIGKILL:
1484	case SIGABRT:
1485	case SIGHUP:
1486	case SIGTRAP:
1487	case SIGBUS:
1488	case SIGILL:
1489	case SIGFPE:
1490	case SIGSEGV:
1491		validate_status_signaled(status, sigval, expect_core);
1492		break;
1493	case SIGSTOP:
1494		validate_status_signaled(status, SIGKILL, 0);
1495		break;
1496	case SIGCONT:
1497	case SIGTSTP:
1498	case SIGTTIN:
1499	case SIGTTOU:
1500		validate_status_exited(status, exitval);
1501		break;
1502	default:
1503		/* NOTREACHED */
1504		ATF_REQUIRE(0 && "NOT IMPLEMENTED");
1505		break;
1506	}
1507
1508	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1509	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1510}
1511
1512#define TRACEME_VFORK_RAISE(test, sig)					\
1513ATF_TC(test);								\
1514ATF_TC_HEAD(test, tc)							\
1515{									\
1516	atf_tc_set_md_var(tc, "descr",					\
1517	    "Verify PT_TRACE_ME followed by raise of " #sig " in a "	\
1518	    "vfork(2)ed child");					\
1519}									\
1520									\
1521ATF_TC_BODY(test, tc)							\
1522{									\
1523									\
1524	traceme_vfork_raise(sig);					\
1525}
1526
1527TRACEME_VFORK_RAISE(traceme_vfork_raise1, SIGKILL) /* non-maskable */
1528TRACEME_VFORK_RAISE(traceme_vfork_raise2, SIGSTOP) /* non-maskable */
1529TRACEME_VFORK_RAISE(traceme_vfork_raise3, SIGTSTP) /* ignored in vfork(2) */
1530TRACEME_VFORK_RAISE(traceme_vfork_raise4, SIGTTIN) /* ignored in vfork(2) */
1531TRACEME_VFORK_RAISE(traceme_vfork_raise5, SIGTTOU) /* ignored in vfork(2) */
1532TRACEME_VFORK_RAISE(traceme_vfork_raise6, SIGABRT) /* regular abort trap */
1533TRACEME_VFORK_RAISE(traceme_vfork_raise7, SIGHUP)  /* hangup */
1534TRACEME_VFORK_RAISE(traceme_vfork_raise8, SIGCONT) /* continued? */
1535TRACEME_VFORK_RAISE(traceme_vfork_raise9, SIGTRAP) /* crash signal */
1536TRACEME_VFORK_RAISE(traceme_vfork_raise10, SIGBUS) /* crash signal */
1537TRACEME_VFORK_RAISE(traceme_vfork_raise11, SIGILL) /* crash signal */
1538TRACEME_VFORK_RAISE(traceme_vfork_raise12, SIGFPE) /* crash signal */
1539TRACEME_VFORK_RAISE(traceme_vfork_raise13, SIGSEGV) /* crash signal */
1540
1541/// ----------------------------------------------------------------------------
1542
1543static void
1544traceme_vfork_crash(int sig)
1545{
1546	pid_t child, wpid;
1547#if defined(TWAIT_HAVE_STATUS)
1548	int status;
1549#endif
1550
1551#ifndef PTRACE_ILLEGAL_ASM
1552	if (sig == SIGILL)
1553		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1554#endif
1555
1556	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1557		atf_tc_skip("FP exceptions are not supported");
1558
1559	DPRINTF("Before forking process PID=%d\n", getpid());
1560	SYSCALL_REQUIRE((child = vfork()) != -1);
1561	if (child == 0) {
1562		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1563		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1564
1565		DPRINTF("Before executing a trap\n");
1566		switch (sig) {
1567		case SIGTRAP:
1568			trigger_trap();
1569			break;
1570		case SIGSEGV:
1571			trigger_segv();
1572			break;
1573		case SIGILL:
1574			trigger_ill();
1575			break;
1576		case SIGFPE:
1577			trigger_fpe();
1578			break;
1579		case SIGBUS:
1580			trigger_bus();
1581			break;
1582		default:
1583			/* NOTREACHED */
1584			FORKEE_ASSERTX(0 && "This shall not be reached");
1585		}
1586
1587		/* NOTREACHED */
1588		FORKEE_ASSERTX(0 && "This shall not be reached");
1589	}
1590	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1591
1592	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1593	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1594
1595	validate_status_signaled(status, sig, 1);
1596
1597	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1598	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1599}
1600
1601#define TRACEME_VFORK_CRASH(test, sig)					\
1602ATF_TC(test);								\
1603ATF_TC_HEAD(test, tc)							\
1604{									\
1605	atf_tc_set_md_var(tc, "descr",					\
1606	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1607	    "vfork(2)ed child");					\
1608}									\
1609									\
1610ATF_TC_BODY(test, tc)							\
1611{									\
1612									\
1613	traceme_vfork_crash(sig);					\
1614}
1615
1616TRACEME_VFORK_CRASH(traceme_vfork_crash_trap, SIGTRAP)
1617TRACEME_VFORK_CRASH(traceme_vfork_crash_segv, SIGSEGV)
1618TRACEME_VFORK_CRASH(traceme_vfork_crash_ill, SIGILL)
1619TRACEME_VFORK_CRASH(traceme_vfork_crash_fpe, SIGFPE)
1620TRACEME_VFORK_CRASH(traceme_vfork_crash_bus, SIGBUS)
1621
1622/// ----------------------------------------------------------------------------
1623
1624static void
1625traceme_vfork_signalmasked_crash(int sig)
1626{
1627	pid_t child, wpid;
1628#if defined(TWAIT_HAVE_STATUS)
1629	int status;
1630#endif
1631	sigset_t intmask;
1632
1633#ifndef PTRACE_ILLEGAL_ASM
1634	if (sig == SIGILL)
1635		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1636#endif
1637
1638	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1639		atf_tc_skip("FP exceptions are not supported");
1640
1641	DPRINTF("Before forking process PID=%d\n", getpid());
1642	SYSCALL_REQUIRE((child = vfork()) != -1);
1643	if (child == 0) {
1644		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1645		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1646
1647		sigemptyset(&intmask);
1648		sigaddset(&intmask, sig);
1649		sigprocmask(SIG_BLOCK, &intmask, NULL);
1650
1651		DPRINTF("Before executing a trap\n");
1652		switch (sig) {
1653		case SIGTRAP:
1654			trigger_trap();
1655			break;
1656		case SIGSEGV:
1657			trigger_segv();
1658			break;
1659		case SIGILL:
1660			trigger_ill();
1661			break;
1662		case SIGFPE:
1663			trigger_fpe();
1664			break;
1665		case SIGBUS:
1666			trigger_bus();
1667			break;
1668		default:
1669			/* NOTREACHED */
1670			FORKEE_ASSERTX(0 && "This shall not be reached");
1671		}
1672
1673		/* NOTREACHED */
1674		FORKEE_ASSERTX(0 && "This shall not be reached");
1675	}
1676	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1677
1678	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1679	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1680
1681	validate_status_signaled(status, sig, 1);
1682
1683	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1684	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1685}
1686
1687#define TRACEME_VFORK_SIGNALMASKED_CRASH(test, sig)			\
1688ATF_TC(test);								\
1689ATF_TC_HEAD(test, tc)							\
1690{									\
1691	atf_tc_set_md_var(tc, "descr",					\
1692	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1693	    "vfork(2)ed child with a masked signal");			\
1694}									\
1695									\
1696ATF_TC_BODY(test, tc)							\
1697{									\
1698									\
1699	traceme_vfork_signalmasked_crash(sig);				\
1700}
1701
1702TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_trap, SIGTRAP)
1703TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_segv, SIGSEGV)
1704TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_ill, SIGILL)
1705TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_fpe, SIGFPE)
1706TRACEME_VFORK_SIGNALMASKED_CRASH(traceme_vfork_signalmasked_crash_bus, SIGBUS)
1707
1708/// ----------------------------------------------------------------------------
1709
1710static void
1711traceme_vfork_signalignored_crash(int sig)
1712{
1713	pid_t child, wpid;
1714#if defined(TWAIT_HAVE_STATUS)
1715	int status;
1716#endif
1717	struct sigaction sa;
1718
1719#ifndef PTRACE_ILLEGAL_ASM
1720	if (sig == SIGILL)
1721		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1722#endif
1723
1724	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1725		atf_tc_skip("FP exceptions are not supported");
1726
1727	DPRINTF("Before forking process PID=%d\n", getpid());
1728	SYSCALL_REQUIRE((child = vfork()) != -1);
1729	if (child == 0) {
1730		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1731		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1732
1733		memset(&sa, 0, sizeof(sa));
1734		sa.sa_handler = SIG_IGN;
1735		sigemptyset(&sa.sa_mask);
1736
1737		FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
1738
1739		DPRINTF("Before executing a trap\n");
1740		switch (sig) {
1741		case SIGTRAP:
1742			trigger_trap();
1743			break;
1744		case SIGSEGV:
1745			trigger_segv();
1746			break;
1747		case SIGILL:
1748			trigger_ill();
1749			break;
1750		case SIGFPE:
1751			trigger_fpe();
1752			break;
1753		case SIGBUS:
1754			trigger_bus();
1755			break;
1756		default:
1757			/* NOTREACHED */
1758			FORKEE_ASSERTX(0 && "This shall not be reached");
1759		}
1760
1761		/* NOTREACHED */
1762		FORKEE_ASSERTX(0 && "This shall not be reached");
1763	}
1764	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1765
1766	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1767	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1768
1769	validate_status_signaled(status, sig, 1);
1770
1771	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1772	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1773}
1774
1775#define TRACEME_VFORK_SIGNALIGNORED_CRASH(test, sig)			\
1776ATF_TC(test);								\
1777ATF_TC_HEAD(test, tc)							\
1778{									\
1779	atf_tc_set_md_var(tc, "descr",					\
1780	    "Verify PT_TRACE_ME followed by a crash signal " #sig " in a " \
1781	    "vfork(2)ed child with ignored signal");			\
1782}									\
1783									\
1784ATF_TC_BODY(test, tc)							\
1785{									\
1786									\
1787	traceme_vfork_signalignored_crash(sig);				\
1788}
1789
1790TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_trap,
1791    SIGTRAP)
1792TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_segv,
1793    SIGSEGV)
1794TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_ill,
1795    SIGILL)
1796TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_fpe,
1797    SIGFPE)
1798TRACEME_VFORK_SIGNALIGNORED_CRASH(traceme_vfork_signalignored_crash_bus,
1799    SIGBUS)
1800
1801/// ----------------------------------------------------------------------------
1802
1803static void
1804traceme_vfork_exec(bool masked, bool ignored)
1805{
1806	const int sigval = SIGTRAP;
1807	pid_t child, wpid;
1808#if defined(TWAIT_HAVE_STATUS)
1809	int status;
1810#endif
1811	struct sigaction sa;
1812	struct ptrace_siginfo info;
1813	sigset_t intmask;
1814	struct kinfo_proc2 kp;
1815	size_t len = sizeof(kp);
1816
1817	int name[6];
1818	const size_t namelen = __arraycount(name);
1819	ki_sigset_t kp_sigmask;
1820	ki_sigset_t kp_sigignore;
1821
1822	memset(&info, 0, sizeof(info));
1823
1824	DPRINTF("Before forking process PID=%d\n", getpid());
1825	SYSCALL_REQUIRE((child = vfork()) != -1);
1826	if (child == 0) {
1827		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1828		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1829
1830		if (masked) {
1831			sigemptyset(&intmask);
1832			sigaddset(&intmask, sigval);
1833			sigprocmask(SIG_BLOCK, &intmask, NULL);
1834		}
1835
1836		if (ignored) {
1837			memset(&sa, 0, sizeof(sa));
1838			sa.sa_handler = SIG_IGN;
1839			sigemptyset(&sa.sa_mask);
1840			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
1841		}
1842
1843		DPRINTF("Before calling execve(2) from child\n");
1844		execlp("/bin/echo", "/bin/echo", NULL);
1845
1846		/* NOTREACHED */
1847		FORKEE_ASSERTX(0 && "Not reached");
1848	}
1849	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1850
1851	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1852	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1853
1854	validate_status_stopped(status, sigval);
1855
1856	name[0] = CTL_KERN,
1857	name[1] = KERN_PROC2,
1858	name[2] = KERN_PROC_PID;
1859	name[3] = getpid();
1860	name[4] = sizeof(kp);
1861	name[5] = 1;
1862
1863	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1864
1865	if (masked)
1866		kp_sigmask = kp.p_sigmask;
1867
1868	if (ignored)
1869		kp_sigignore = kp.p_sigignore;
1870
1871	name[3] = getpid();
1872
1873	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1874
1875	if (masked) {
1876		DPRINTF("kp_sigmask="
1877		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1878		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1879		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1880
1881	        DPRINTF("kp.p_sigmask="
1882	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1883	            kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1884	            kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1885
1886		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
1887		    sizeof(kp_sigmask)));
1888	}
1889
1890	if (ignored) {
1891		DPRINTF("kp_sigignore="
1892		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1893		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1894		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1895
1896	        DPRINTF("kp.p_sigignore="
1897	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1898	            kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1899	            kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1900
1901		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
1902		    sizeof(kp_sigignore)));
1903	}
1904
1905	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1906	SYSCALL_REQUIRE(
1907	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1908
1909	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1910	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1911	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1912	    info.psi_siginfo.si_errno);
1913
1914	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1915	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1916
1917	DPRINTF("Before resuming the child process where it left off and "
1918	    "without signal to be sent\n");
1919	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1920
1921	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1922	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1923
1924	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1925	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1926}
1927
1928#define TRACEME_VFORK_EXEC(test, masked, ignored)			\
1929ATF_TC(test);								\
1930ATF_TC_HEAD(test, tc)							\
1931{									\
1932	atf_tc_set_md_var(tc, "descr",					\
1933	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed "	\
1934	    "child%s%s", masked ? " with masked signal" : "",		\
1935	    masked ? " with ignored signal" : "");			\
1936}									\
1937									\
1938ATF_TC_BODY(test, tc)							\
1939{									\
1940									\
1941	traceme_vfork_exec(masked, ignored);				\
1942}
1943
1944TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false)
1945TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false)
1946TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true)
1947
1948/// ----------------------------------------------------------------------------
1949
1950#if defined(TWAIT_HAVE_PID)
1951static void
1952unrelated_tracer_sees_crash(int sig, bool masked, bool ignored)
1953{
1954	const int sigval = SIGSTOP;
1955	struct msg_fds parent_tracee, parent_tracer;
1956	const int exitval = 10;
1957	pid_t tracee, tracer, wpid;
1958	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1959#if defined(TWAIT_HAVE_STATUS)
1960	int status;
1961#endif
1962	struct sigaction sa;
1963	struct ptrace_siginfo info;
1964	sigset_t intmask;
1965	struct kinfo_proc2 kp;
1966	size_t len = sizeof(kp);
1967
1968	int name[6];
1969	const size_t namelen = __arraycount(name);
1970	ki_sigset_t kp_sigmask;
1971	ki_sigset_t kp_sigignore;
1972
1973#ifndef PTRACE_ILLEGAL_ASM
1974	if (sig == SIGILL)
1975		atf_tc_skip("PTRACE_ILLEGAL_ASM not defined");
1976#endif
1977
1978	if (sig == SIGFPE && !are_fpu_exceptions_supported())
1979		atf_tc_skip("FP exceptions are not supported");
1980
1981	memset(&info, 0, sizeof(info));
1982
1983	DPRINTF("Spawn tracee\n");
1984	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1985	tracee = atf_utils_fork();
1986	if (tracee == 0) {
1987		// Wait for parent to let us crash
1988		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
1989
1990		if (masked) {
1991			sigemptyset(&intmask);
1992			sigaddset(&intmask, sig);
1993			sigprocmask(SIG_BLOCK, &intmask, NULL);
1994		}
1995
1996		if (ignored) {
1997			memset(&sa, 0, sizeof(sa));
1998			sa.sa_handler = SIG_IGN;
1999			sigemptyset(&sa.sa_mask);
2000			FORKEE_ASSERT(sigaction(sig, &sa, NULL) != -1);
2001		}
2002
2003		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2004		FORKEE_ASSERT(raise(sigval) == 0);
2005
2006		DPRINTF("Before executing a trap\n");
2007		switch (sig) {
2008		case SIGTRAP:
2009			trigger_trap();
2010			break;
2011		case SIGSEGV:
2012			trigger_segv();
2013			break;
2014		case SIGILL:
2015			trigger_ill();
2016			break;
2017		case SIGFPE:
2018			trigger_fpe();
2019			break;
2020		case SIGBUS:
2021			trigger_bus();
2022			break;
2023		default:
2024			/* NOTREACHED */
2025			FORKEE_ASSERTX(0 && "This shall not be reached");
2026		}
2027
2028		/* NOTREACHED */
2029		FORKEE_ASSERTX(0 && "This shall not be reached");
2030	}
2031
2032	DPRINTF("Spawn debugger\n");
2033	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2034	tracer = atf_utils_fork();
2035	if (tracer == 0) {
2036		/* Fork again and drop parent to reattach to PID 1 */
2037		tracer = atf_utils_fork();
2038		if (tracer != 0)
2039			_exit(exitval);
2040
2041		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2042		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2043
2044		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2045		FORKEE_REQUIRE_SUCCESS(
2046		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2047
2048		forkee_status_stopped(status, SIGSTOP);
2049
2050		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2051		    "traced process\n");
2052		SYSCALL_REQUIRE(
2053		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2054
2055		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2056		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2057		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2058		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2059
2060		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
2061		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
2062
2063		/* Resume tracee with PT_CONTINUE */
2064		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2065
2066		/* Inform parent that tracer has attached to tracee */
2067		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2068
2069		/* Wait for parent to tell use that tracee should have exited */
2070		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2071
2072		/* Wait for tracee and assert that it exited */
2073		FORKEE_REQUIRE_SUCCESS(
2074		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2075
2076		forkee_status_stopped(status, sigval);
2077
2078		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2079		    "traced process\n");
2080		SYSCALL_REQUIRE(
2081		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2082
2083		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2084		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2085		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2086		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2087
2088		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
2089		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
2090
2091		name[0] = CTL_KERN,
2092		name[1] = KERN_PROC2,
2093		name[2] = KERN_PROC_PID;
2094		name[3] = tracee;
2095		name[4] = sizeof(kp);
2096		name[5] = 1;
2097
2098		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2099
2100		if (masked)
2101			kp_sigmask = kp.p_sigmask;
2102
2103		if (ignored)
2104			kp_sigignore = kp.p_sigignore;
2105
2106		/* Resume tracee with PT_CONTINUE */
2107		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2108
2109		/* Wait for tracee and assert that it exited */
2110		FORKEE_REQUIRE_SUCCESS(
2111		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2112
2113		forkee_status_stopped(status, sig);
2114
2115		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
2116		    "traced process\n");
2117		SYSCALL_REQUIRE(
2118		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
2119
2120		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2121		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2122		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
2123		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
2124
2125		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sig);
2126
2127		FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2128
2129		if (masked) {
2130			DPRINTF("kp_sigmask="
2131			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2132			    PRIx32 "\n",
2133			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
2134			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
2135
2136			DPRINTF("kp.p_sigmask="
2137			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2138			    PRIx32 "\n",
2139			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
2140			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
2141
2142			FORKEE_ASSERTX(!memcmp(&kp_sigmask, &kp.p_sigmask,
2143			    sizeof(kp_sigmask)));
2144		}
2145
2146		if (ignored) {
2147			DPRINTF("kp_sigignore="
2148			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2149			    PRIx32 "\n",
2150			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
2151			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
2152
2153			DPRINTF("kp.p_sigignore="
2154			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
2155			    PRIx32 "\n",
2156			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
2157			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
2158
2159			FORKEE_ASSERTX(!memcmp(&kp_sigignore, &kp.p_sigignore,
2160			    sizeof(kp_sigignore)));
2161		}
2162
2163		switch (sig) {
2164		case SIGTRAP:
2165			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, TRAP_BRKPT);
2166			break;
2167		case SIGSEGV:
2168			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SEGV_MAPERR);
2169			break;
2170		case SIGILL:
2171			FORKEE_ASSERT(info.psi_siginfo.si_code >= ILL_ILLOPC &&
2172			            info.psi_siginfo.si_code <= ILL_BADSTK);
2173			break;
2174		case SIGFPE:
2175			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, FPE_INTDIV);
2176			break;
2177		case SIGBUS:
2178			FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, BUS_ADRERR);
2179			break;
2180		}
2181
2182		FORKEE_ASSERT(ptrace(PT_KILL, tracee, NULL, 0) != -1);
2183		DPRINTF("Before calling %s() for the tracee\n", TWAIT_FNAME);
2184		FORKEE_REQUIRE_SUCCESS(
2185		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2186
2187		forkee_status_signaled(status, SIGKILL, 0);
2188
2189		/* Inform parent that tracer is exiting normally */
2190		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
2191
2192		DPRINTF("Before exiting of the tracer process\n");
2193		_exit(0 /* collect by initproc */);
2194	}
2195
2196	DPRINTF("Wait for the tracer process (direct child) to exit "
2197	    "calling %s()\n", TWAIT_FNAME);
2198	TWAIT_REQUIRE_SUCCESS(
2199	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2200
2201	validate_status_exited(status, exitval);
2202
2203	DPRINTF("Wait for the non-exited tracee process with %s()\n",
2204	    TWAIT_FNAME);
2205	TWAIT_REQUIRE_SUCCESS(
2206	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2207
2208	DPRINTF("Wait for the tracer to attach to the tracee\n");
2209	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2210
2211	DPRINTF("Resume the tracee and let it crash\n");
2212	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2213
2214	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
2215	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2216
2217	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2218	    TWAIT_FNAME);
2219	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2220
2221	validate_status_signaled(status, SIGKILL, 0);
2222
2223	DPRINTF("Await normal exit of tracer\n");
2224	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
2225
2226	msg_close(&parent_tracer);
2227	msg_close(&parent_tracee);
2228}
2229
2230#define UNRELATED_TRACER_SEES_CRASH(test, sig)				\
2231ATF_TC(test);								\
2232ATF_TC_HEAD(test, tc)							\
2233{									\
2234	atf_tc_set_md_var(tc, "descr",					\
2235	    "Assert that an unrelated tracer sees crash signal from "	\
2236	    "the debuggee");						\
2237}									\
2238									\
2239ATF_TC_BODY(test, tc)							\
2240{									\
2241									\
2242	unrelated_tracer_sees_crash(sig, false, false);			\
2243}
2244
2245UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_trap, SIGTRAP)
2246UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_segv, SIGSEGV)
2247UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_ill, SIGILL)
2248UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_fpe, SIGFPE)
2249UNRELATED_TRACER_SEES_CRASH(unrelated_tracer_sees_crash_bus, SIGBUS)
2250
2251#define UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(test, sig)		\
2252ATF_TC(test);								\
2253ATF_TC_HEAD(test, tc)							\
2254{									\
2255	atf_tc_set_md_var(tc, "descr",					\
2256	    "Assert that an unrelated tracer sees crash signal from "	\
2257	    "the debuggee with masked signal");				\
2258}									\
2259									\
2260ATF_TC_BODY(test, tc)							\
2261{									\
2262									\
2263	unrelated_tracer_sees_crash(sig, true, false);			\
2264}
2265
2266UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2267    unrelated_tracer_sees_signalmasked_crash_trap, SIGTRAP)
2268UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2269    unrelated_tracer_sees_signalmasked_crash_segv, SIGSEGV)
2270UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2271    unrelated_tracer_sees_signalmasked_crash_ill, SIGILL)
2272UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2273    unrelated_tracer_sees_signalmasked_crash_fpe, SIGFPE)
2274UNRELATED_TRACER_SEES_SIGNALMASKED_CRASH(
2275    unrelated_tracer_sees_signalmasked_crash_bus, SIGBUS)
2276
2277#define UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(test, sig)		\
2278ATF_TC(test);								\
2279ATF_TC_HEAD(test, tc)							\
2280{									\
2281	atf_tc_set_md_var(tc, "descr",					\
2282	    "Assert that an unrelated tracer sees crash signal from "	\
2283	    "the debuggee with signal ignored");			\
2284}									\
2285									\
2286ATF_TC_BODY(test, tc)							\
2287{									\
2288									\
2289	unrelated_tracer_sees_crash(sig, false, true);			\
2290}
2291
2292UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2293    unrelated_tracer_sees_signalignored_crash_trap, SIGTRAP)
2294UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2295    unrelated_tracer_sees_signalignored_crash_segv, SIGSEGV)
2296UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2297    unrelated_tracer_sees_signalignored_crash_ill, SIGILL)
2298UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2299    unrelated_tracer_sees_signalignored_crash_fpe, SIGFPE)
2300UNRELATED_TRACER_SEES_SIGNALIGNORED_CRASH(
2301    unrelated_tracer_sees_signalignored_crash_bus, SIGBUS)
2302#endif
2303
2304/// ----------------------------------------------------------------------------
2305
2306#if defined(TWAIT_HAVE_PID)
2307static void
2308tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated,
2309                                             bool stopped)
2310{
2311	/*
2312	 * notimeout - disable timeout in await zombie function
2313	 * unrelated - attach from unrelated tracer reparented to initproc
2314	 * stopped - attach to a stopped process
2315	 */
2316
2317	struct msg_fds parent_tracee, parent_tracer;
2318	const int exitval_tracee = 5;
2319	const int exitval_tracer = 10;
2320	pid_t tracee, tracer, wpid;
2321	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2322#if defined(TWAIT_HAVE_STATUS)
2323	int status;
2324#endif
2325
2326	/*
2327	 * Only a subset of options are supported.
2328	 */
2329	ATF_REQUIRE((!notimeout && !unrelated && !stopped) ||
2330	            (!notimeout && unrelated && !stopped) ||
2331	            (notimeout && !unrelated && !stopped) ||
2332	            (!notimeout && unrelated && stopped));
2333
2334	DPRINTF("Spawn tracee\n");
2335	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2336	tracee = atf_utils_fork();
2337	if (tracee == 0) {
2338		if (stopped) {
2339			DPRINTF("Stop self PID %d\n", getpid());
2340			raise(SIGSTOP);
2341		}
2342
2343		// Wait for parent to let us exit
2344		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2345		_exit(exitval_tracee);
2346	}
2347
2348	DPRINTF("Spawn debugger\n");
2349	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2350	tracer = atf_utils_fork();
2351	if (tracer == 0) {
2352		if(unrelated) {
2353			/* Fork again and drop parent to reattach to PID 1 */
2354			tracer = atf_utils_fork();
2355			if (tracer != 0)
2356				_exit(exitval_tracer);
2357		}
2358
2359		if (stopped) {
2360			DPRINTF("Await for a stopped parent PID %d\n", tracee);
2361			await_stopped(tracee);
2362		}
2363
2364		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2365		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2366
2367		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2368		FORKEE_REQUIRE_SUCCESS(
2369		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2370
2371		forkee_status_stopped(status, SIGSTOP);
2372
2373		/* Resume tracee with PT_CONTINUE */
2374		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2375
2376		/* Inform parent that tracer has attached to tracee */
2377		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2378
2379		/* Wait for parent to tell use that tracee should have exited */
2380		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2381
2382		/* Wait for tracee and assert that it exited */
2383		FORKEE_REQUIRE_SUCCESS(
2384		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2385
2386		forkee_status_exited(status, exitval_tracee);
2387		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
2388
2389		DPRINTF("Before exiting of the tracer process\n");
2390		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
2391	}
2392
2393	if (unrelated) {
2394		DPRINTF("Wait for the tracer process (direct child) to exit "
2395		    "calling %s()\n", TWAIT_FNAME);
2396		TWAIT_REQUIRE_SUCCESS(
2397		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2398
2399		validate_status_exited(status, exitval_tracer);
2400
2401		DPRINTF("Wait for the non-exited tracee process with %s()\n",
2402		    TWAIT_FNAME);
2403		TWAIT_REQUIRE_SUCCESS(
2404		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
2405	}
2406
2407	DPRINTF("Wait for the tracer to attach to the tracee\n");
2408	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
2409
2410	DPRINTF("Resume the tracee and let it exit\n");
2411	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
2412
2413	DPRINTF("Detect that tracee is zombie\n");
2414	if (notimeout)
2415		await_zombie_raw(tracee, 0);
2416	else
2417		await_zombie(tracee);
2418
2419	DPRINTF("Assert that there is no status about tracee %d - "
2420	    "Tracer must detect zombie first - calling %s()\n", tracee,
2421	    TWAIT_FNAME);
2422	TWAIT_REQUIRE_SUCCESS(
2423	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2424
2425	if (unrelated) {
2426		DPRINTF("Resume the tracer and let it detect exited tracee\n");
2427		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
2428	} else {
2429		DPRINTF("Tell the tracer child should have exited\n");
2430		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
2431		DPRINTF("Wait for tracer to finish its job and exit - calling "
2432			"%s()\n", TWAIT_FNAME);
2433
2434		DPRINTF("Wait from tracer child to complete waiting for "
2435			"tracee\n");
2436		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2437		    tracer);
2438
2439		validate_status_exited(status, exitval_tracer);
2440	}
2441
2442	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2443	    TWAIT_FNAME);
2444	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2445
2446	validate_status_exited(status, exitval_tracee);
2447
2448	msg_close(&parent_tracer);
2449	msg_close(&parent_tracee);
2450}
2451
2452ATF_TC(tracer_sees_terminaton_before_the_parent);
2453ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
2454{
2455	atf_tc_set_md_var(tc, "descr",
2456	    "Assert that tracer sees process termination before the parent");
2457}
2458
2459ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
2460{
2461
2462	tracer_sees_terminaton_before_the_parent_raw(false, false, false);
2463}
2464
2465ATF_TC(tracer_sysctl_lookup_without_duplicates);
2466ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
2467{
2468	atf_tc_set_md_var(tc, "timeout", "15");
2469	atf_tc_set_md_var(tc, "descr",
2470	    "Assert that await_zombie() in attach1 always finds a single "
2471	    "process and no other error is reported");
2472}
2473
2474ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
2475{
2476	time_t start, end;
2477	double diff;
2478	unsigned long N = 0;
2479
2480	/*
2481	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
2482	 * This test body isn't specific to this race, however it's just good
2483	 * enough for this purposes, no need to invent a dedicated code flow.
2484	 */
2485
2486	start = time(NULL);
2487	while (true) {
2488		DPRINTF("Step: %lu\n", N);
2489		tracer_sees_terminaton_before_the_parent_raw(true, false,
2490		                                             false);
2491		end = time(NULL);
2492		diff = difftime(end, start);
2493		if (diff >= 5.0)
2494			break;
2495		++N;
2496	}
2497	DPRINTF("Iterations: %lu\n", N);
2498}
2499
2500ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
2501ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2502{
2503	atf_tc_set_md_var(tc, "descr",
2504	    "Assert that tracer sees process termination before the parent");
2505}
2506
2507ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
2508{
2509
2510	tracer_sees_terminaton_before_the_parent_raw(false, true, false);
2511}
2512
2513ATF_TC(tracer_attach_to_unrelated_stopped_process);
2514ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc)
2515{
2516	atf_tc_set_md_var(tc, "descr",
2517	    "Assert that tracer can attach to an unrelated stopped process");
2518}
2519
2520ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc)
2521{
2522
2523	tracer_sees_terminaton_before_the_parent_raw(false, true, true);
2524}
2525#endif
2526
2527/// ----------------------------------------------------------------------------
2528
2529static void
2530parent_attach_to_its_child(bool stopped)
2531{
2532	struct msg_fds parent_tracee;
2533	const int exitval_tracee = 5;
2534	pid_t tracee, wpid;
2535	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2536#if defined(TWAIT_HAVE_STATUS)
2537	int status;
2538#endif
2539
2540	DPRINTF("Spawn tracee\n");
2541	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2542	tracee = atf_utils_fork();
2543	if (tracee == 0) {
2544		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2545		DPRINTF("Parent should now attach to tracee\n");
2546
2547		if (stopped) {
2548			DPRINTF("Stop self PID %d\n", getpid());
2549			SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2550		}
2551
2552		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
2553		/* Wait for message from the parent */
2554		_exit(exitval_tracee);
2555	}
2556	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2557
2558	if (stopped) {
2559		DPRINTF("Await for a stopped tracee PID %d\n", tracee);
2560		await_stopped(tracee);
2561	}
2562
2563	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
2564	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2565
2566	DPRINTF("Wait for the stopped tracee process with %s()\n",
2567	    TWAIT_FNAME);
2568	TWAIT_REQUIRE_SUCCESS(
2569	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2570
2571	validate_status_stopped(status, SIGSTOP);
2572
2573	DPRINTF("Resume tracee with PT_CONTINUE\n");
2574	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2575
2576	DPRINTF("Let the tracee exit now\n");
2577	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
2578
2579	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
2580	TWAIT_REQUIRE_SUCCESS(
2581	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2582
2583	validate_status_exited(status, exitval_tracee);
2584
2585	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
2586	TWAIT_REQUIRE_FAILURE(ECHILD,
2587	    wpid = TWAIT_GENERIC(tracee, &status, 0));
2588
2589	msg_close(&parent_tracee);
2590}
2591
2592ATF_TC(parent_attach_to_its_child);
2593ATF_TC_HEAD(parent_attach_to_its_child, tc)
2594{
2595	atf_tc_set_md_var(tc, "descr",
2596	    "Assert that tracer parent can PT_ATTACH to its child");
2597}
2598
2599ATF_TC_BODY(parent_attach_to_its_child, tc)
2600{
2601
2602	parent_attach_to_its_child(false);
2603}
2604
2605ATF_TC(parent_attach_to_its_stopped_child);
2606ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc)
2607{
2608	atf_tc_set_md_var(tc, "descr",
2609	    "Assert that tracer parent can PT_ATTACH to its stopped child");
2610}
2611
2612ATF_TC_BODY(parent_attach_to_its_stopped_child, tc)
2613{
2614
2615	parent_attach_to_its_child(true);
2616}
2617
2618/// ----------------------------------------------------------------------------
2619
2620static void
2621child_attach_to_its_parent(bool stopped)
2622{
2623	struct msg_fds parent_tracee;
2624	const int exitval_tracer = 5;
2625	pid_t tracer, wpid;
2626	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2627#if defined(TWAIT_HAVE_STATUS)
2628	int status;
2629#endif
2630
2631	DPRINTF("Spawn tracer\n");
2632	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2633	tracer = atf_utils_fork();
2634	if (tracer == 0) {
2635		/* Wait for message from the parent */
2636		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
2637
2638		if (stopped) {
2639			DPRINTF("Await for a stopped parent PID %d\n",
2640			        getppid());
2641			await_stopped(getppid());
2642		}
2643
2644		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
2645		    getppid());
2646		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
2647
2648		DPRINTF("Wait for the stopped parent process with %s()\n",
2649		    TWAIT_FNAME);
2650		FORKEE_REQUIRE_SUCCESS(
2651		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
2652
2653		forkee_status_stopped(status, SIGSTOP);
2654
2655		DPRINTF("Resume parent with PT_DETACH\n");
2656		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
2657		    != -1);
2658
2659		/* Tell parent we are ready */
2660		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
2661
2662		_exit(exitval_tracer);
2663	}
2664
2665	DPRINTF("Wait for the tracer to become ready\n");
2666	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
2667
2668	if (stopped) {
2669		DPRINTF("Stop self PID %d\n", getpid());
2670		SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
2671	}
2672
2673	DPRINTF("Allow the tracer to exit now\n");
2674	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
2675
2676	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
2677	TWAIT_REQUIRE_SUCCESS(
2678	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
2679
2680	validate_status_exited(status, exitval_tracer);
2681
2682	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
2683	TWAIT_REQUIRE_FAILURE(ECHILD,
2684	    wpid = TWAIT_GENERIC(tracer, &status, 0));
2685
2686	msg_close(&parent_tracee);
2687}
2688
2689ATF_TC(child_attach_to_its_parent);
2690ATF_TC_HEAD(child_attach_to_its_parent, tc)
2691{
2692	atf_tc_set_md_var(tc, "descr",
2693	    "Assert that tracer child can PT_ATTACH to its parent");
2694}
2695
2696ATF_TC_BODY(child_attach_to_its_parent, tc)
2697{
2698
2699	child_attach_to_its_parent(false);
2700}
2701
2702ATF_TC(child_attach_to_its_stopped_parent);
2703ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc)
2704{
2705	atf_tc_set_md_var(tc, "descr",
2706	    "Assert that tracer child can PT_ATTACH to its stopped parent");
2707}
2708
2709ATF_TC_BODY(child_attach_to_its_stopped_parent, tc)
2710{
2711	/*
2712	 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as
2713	 * this causes a pipe (established from atf-run) to be broken.
2714	 * atf-run uses this mechanism to monitor whether a test is alive.
2715	 *
2716	 * As a workaround spawn this test as a subprocess.
2717	 */
2718
2719	const int exitval = 15;
2720	pid_t child, wpid;
2721#if defined(TWAIT_HAVE_STATUS)
2722	int status;
2723#endif
2724
2725	SYSCALL_REQUIRE((child = fork()) != -1);
2726	if (child == 0) {
2727		child_attach_to_its_parent(true);
2728		_exit(exitval);
2729	} else {
2730		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2731		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2732
2733		validate_status_exited(status, exitval);
2734
2735		DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
2736		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2737	}
2738}
2739
2740/// ----------------------------------------------------------------------------
2741
2742#if defined(TWAIT_HAVE_PID)
2743
2744enum tracee_sees_its_original_parent_type {
2745	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2746	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2747	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
2748};
2749
2750static void
2751tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
2752{
2753	struct msg_fds parent_tracer, parent_tracee;
2754	const int exitval_tracee = 5;
2755	const int exitval_tracer = 10;
2756	pid_t parent, tracee, tracer, wpid;
2757	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
2758#if defined(TWAIT_HAVE_STATUS)
2759	int status;
2760#endif
2761	/* sysctl(3) - kinfo_proc2 */
2762	int name[CTL_MAXNAME];
2763	struct kinfo_proc2 kp;
2764	size_t len = sizeof(kp);
2765	unsigned int namelen;
2766
2767	/* procfs - status  */
2768	FILE *fp;
2769	struct stat st;
2770	const char *fname = "/proc/curproc/status";
2771	char s_executable[MAXPATHLEN];
2772	int s_pid, s_ppid;
2773	int rv;
2774
2775	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
2776		SYSCALL_REQUIRE(
2777		    (rv = stat(fname, &st)) == 0 || (errno == ENOENT));
2778		if (rv != 0)
2779			atf_tc_skip("/proc/curproc/status not found");
2780	}
2781
2782	DPRINTF("Spawn tracee\n");
2783	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
2784	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
2785	tracee = atf_utils_fork();
2786	if (tracee == 0) {
2787		parent = getppid();
2788
2789		/* Emit message to the parent */
2790		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
2791		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
2792
2793		switch (type) {
2794		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
2795			FORKEE_ASSERT_EQ(parent, getppid());
2796			break;
2797		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
2798			namelen = 0;
2799			name[namelen++] = CTL_KERN;
2800			name[namelen++] = KERN_PROC2;
2801			name[namelen++] = KERN_PROC_PID;
2802			name[namelen++] = getpid();
2803			name[namelen++] = len;
2804			name[namelen++] = 1;
2805
2806			FORKEE_ASSERT_EQ(
2807			    sysctl(name, namelen, &kp, &len, NULL, 0), 0);
2808			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
2809			break;
2810		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
2811			/*
2812			 * Format:
2813			 *  EXECUTABLE PID PPID ...
2814			 */
2815			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
2816			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
2817			FORKEE_ASSERT_EQ(fclose(fp), 0);
2818			FORKEE_ASSERT_EQ(parent, s_ppid);
2819			break;
2820		}
2821
2822		_exit(exitval_tracee);
2823	}
2824	DPRINTF("Wait for child to record its parent identifier (pid)\n");
2825	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
2826
2827	DPRINTF("Spawn debugger\n");
2828	tracer = atf_utils_fork();
2829	if (tracer == 0) {
2830		/* No IPC to communicate with the child */
2831		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
2832		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
2833
2834		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
2835		FORKEE_REQUIRE_SUCCESS(
2836		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2837
2838		forkee_status_stopped(status, SIGSTOP);
2839
2840		/* Resume tracee with PT_CONTINUE */
2841		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
2842
2843		/* Inform parent that tracer has attached to tracee */
2844		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
2845
2846		/* Wait for parent to tell use that tracee should have exited */
2847		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
2848
2849		/* Wait for tracee and assert that it exited */
2850		FORKEE_REQUIRE_SUCCESS(
2851		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
2852
2853		forkee_status_exited(status, exitval_tracee);
2854
2855		DPRINTF("Before exiting of the tracer process\n");
2856		_exit(exitval_tracer);
2857	}
2858
2859	DPRINTF("Wait for the tracer to attach to the tracee\n");
2860	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
2861
2862	DPRINTF("Resume the tracee and let it exit\n");
2863	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
2864
2865	DPRINTF("Detect that tracee is zombie\n");
2866	await_zombie(tracee);
2867
2868	DPRINTF("Assert that there is no status about tracee - "
2869	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
2870	TWAIT_REQUIRE_SUCCESS(
2871	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
2872
2873	DPRINTF("Tell the tracer child should have exited\n");
2874	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
2875
2876	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
2877	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
2878	    tracer);
2879
2880	validate_status_exited(status, exitval_tracer);
2881
2882	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
2883	    TWAIT_FNAME);
2884	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
2885	    tracee);
2886
2887	validate_status_exited(status, exitval_tracee);
2888
2889	msg_close(&parent_tracer);
2890	msg_close(&parent_tracee);
2891}
2892
2893#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)		\
2894ATF_TC(test);								\
2895ATF_TC_HEAD(test, tc)							\
2896{									\
2897	atf_tc_set_md_var(tc, "descr",					\
2898	    "Assert that tracee sees its original parent when being traced " \
2899	    "(check " descr ")");					\
2900}									\
2901									\
2902ATF_TC_BODY(test, tc)							\
2903{									\
2904									\
2905	tracee_sees_its_original_parent(type);				\
2906}
2907
2908TRACEE_SEES_ITS_ORIGINAL_PARENT(
2909	tracee_sees_its_original_parent_getppid,
2910	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
2911	"getppid(2)");
2912TRACEE_SEES_ITS_ORIGINAL_PARENT(
2913	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
2914	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
2915	"sysctl(3) and kinfo_proc2");
2916TRACEE_SEES_ITS_ORIGINAL_PARENT(
2917	tracee_sees_its_original_parent_procfs_status,
2918	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
2919	"the status file in procfs");
2920#endif
2921
2922/// ----------------------------------------------------------------------------
2923
2924static void
2925eventmask_preserved(int event)
2926{
2927	const int exitval = 5;
2928	const int sigval = SIGSTOP;
2929	pid_t child, wpid;
2930#if defined(TWAIT_HAVE_STATUS)
2931	int status;
2932#endif
2933	ptrace_event_t set_event, get_event;
2934	const int len = sizeof(ptrace_event_t);
2935
2936	DPRINTF("Before forking process PID=%d\n", getpid());
2937	SYSCALL_REQUIRE((child = fork()) != -1);
2938	if (child == 0) {
2939		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2940		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2941
2942		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2943		FORKEE_ASSERT(raise(sigval) == 0);
2944
2945		DPRINTF("Before exiting of the child process\n");
2946		_exit(exitval);
2947	}
2948	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2949
2950	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2951	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2952
2953	validate_status_stopped(status, sigval);
2954
2955	set_event.pe_set_event = event;
2956	SYSCALL_REQUIRE(
2957	    ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
2958	SYSCALL_REQUIRE(
2959	    ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
2960	DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event,
2961	    get_event.pe_set_event);
2962	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
2963
2964	DPRINTF("Before resuming the child process where it left off and "
2965	    "without signal to be sent\n");
2966	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2967
2968	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2969	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2970
2971	validate_status_exited(status, exitval);
2972
2973	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2974	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2975}
2976
2977#define EVENTMASK_PRESERVED(test, event)				\
2978ATF_TC(test);								\
2979ATF_TC_HEAD(test, tc)							\
2980{									\
2981	atf_tc_set_md_var(tc, "descr",					\
2982	    "Verify that eventmask " #event " is preserved");		\
2983}									\
2984									\
2985ATF_TC_BODY(test, tc)							\
2986{									\
2987									\
2988	eventmask_preserved(event);					\
2989}
2990
2991EVENTMASK_PRESERVED(eventmask_preserved_empty, 0)
2992EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK)
2993EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK)
2994EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE)
2995EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE)
2996EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT)
2997EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN)
2998
2999/// ----------------------------------------------------------------------------
3000
3001static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
3002
3003static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
3004static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER;
3005static volatile size_t lwpinfo_thread_done;
3006
3007static void *
3008lwpinfo_thread(void *arg)
3009{
3010	sigset_t s;
3011	volatile void **tcb;
3012
3013	tcb = (volatile void **)arg;
3014
3015	*tcb = _lwp_getprivate();
3016	DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self());
3017
3018	pthread_setname_np(pthread_self(), "thread %d",
3019	    (void *)(intptr_t)_lwp_self());
3020
3021	sigemptyset(&s);
3022	pthread_mutex_lock(&lwpinfo_thread_mtx);
3023	sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
3024	lwpinfo_thread_done++;
3025	pthread_sigmask(SIG_BLOCK, &s, NULL);
3026	pthread_cond_signal(&lwpinfo_thread_cnd);
3027	pthread_mutex_unlock(&lwpinfo_thread_mtx);
3028
3029	return infinite_thread(NULL);
3030}
3031
3032static void
3033traceme_lwpinfo(const size_t threads, const char *iter)
3034{
3035	const int sigval = SIGSTOP;
3036	const int sigval2 = SIGINT;
3037	pid_t child, wpid;
3038#if defined(TWAIT_HAVE_STATUS)
3039	int status;
3040#endif
3041	struct ptrace_lwpinfo lwp = {0, 0};
3042	struct ptrace_lwpstatus lwpstatus = {0};
3043	struct ptrace_siginfo info;
3044	void *private;
3045	char *name;
3046	char namebuf[PL_LNAMELEN];
3047	volatile void *tcb[4];
3048	bool found;
3049	sigset_t s;
3050
3051	/* Maximum number of supported threads in this test */
3052	pthread_t t[__arraycount(tcb) - 1];
3053	size_t n, m;
3054	int rv;
3055	size_t bytes_read;
3056
3057	struct ptrace_io_desc io;
3058	sigset_t sigmask;
3059
3060	ATF_REQUIRE(__arraycount(t) >= threads);
3061	memset(tcb, 0, sizeof(tcb));
3062
3063	DPRINTF("Before forking process PID=%d\n", getpid());
3064	SYSCALL_REQUIRE((child = fork()) != -1);
3065	if (child == 0) {
3066		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3067		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3068
3069		tcb[0] = _lwp_getprivate();
3070		DPRINTF("Storing tcb[0] = %p\n", tcb[0]);
3071
3072		pthread_setname_np(pthread_self(), "thread %d",
3073		    (void *)(intptr_t)_lwp_self());
3074
3075		sigemptyset(&s);
3076		sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
3077		pthread_sigmask(SIG_BLOCK, &s, NULL);
3078
3079		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3080		FORKEE_ASSERT(raise(sigval) == 0);
3081
3082		for (n = 0; n < threads; n++) {
3083			rv = pthread_create(&t[n], NULL, lwpinfo_thread,
3084			    &tcb[n + 1]);
3085			FORKEE_ASSERT(rv == 0);
3086		}
3087
3088		pthread_mutex_lock(&lwpinfo_thread_mtx);
3089		while (lwpinfo_thread_done < threads) {
3090			pthread_cond_wait(&lwpinfo_thread_cnd,
3091			    &lwpinfo_thread_mtx);
3092		}
3093		pthread_mutex_unlock(&lwpinfo_thread_mtx);
3094
3095		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
3096		FORKEE_ASSERT(raise(sigval2) == 0);
3097
3098		/* NOTREACHED */
3099		FORKEE_ASSERTX(0 && "Not reached");
3100	}
3101	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3102
3103	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3104	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3105
3106	validate_status_stopped(status, sigval);
3107
3108	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
3109	SYSCALL_REQUIRE(
3110	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3111
3112	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3113	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3114	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3115	    info.psi_siginfo.si_errno);
3116
3117	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3118	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3119
3120	if (strstr(iter, "LWPINFO") != NULL) {
3121		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3122		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
3123		    != -1);
3124
3125		DPRINTF("Assert that there exists a single thread only\n");
3126		ATF_REQUIRE(lwp.pl_lwpid > 0);
3127
3128		DPRINTF("Assert that lwp thread %d received event "
3129		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
3130		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
3131
3132		if (strstr(iter, "LWPSTATUS") != NULL) {
3133			DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS "
3134			    "for child\n");
3135			lwpstatus.pl_lwpid = lwp.pl_lwpid;
3136			SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus,
3137			    sizeof(lwpstatus)) != -1);
3138		}
3139
3140		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3141		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
3142		    != -1);
3143
3144		DPRINTF("Assert that there exists a single thread only\n");
3145		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
3146	} else {
3147		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
3148		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
3149		    sizeof(lwpstatus)) != -1);
3150
3151		DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid);
3152		ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
3153
3154		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
3155		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
3156		    sizeof(lwpstatus)) != -1);
3157
3158		DPRINTF("Assert that there exists a single thread only\n");
3159		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
3160	}
3161
3162	DPRINTF("Before resuming the child process where it left off and "
3163	    "without signal to be sent\n");
3164	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3165
3166	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3167	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3168
3169	validate_status_stopped(status, sigval2);
3170
3171	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
3172	SYSCALL_REQUIRE(
3173	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3174
3175	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3176	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3177	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3178	    info.psi_siginfo.si_errno);
3179
3180	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
3181	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3182
3183	memset(&lwp, 0, sizeof(lwp));
3184	memset(&lwpstatus, 0, sizeof(lwpstatus));
3185
3186	memset(&io, 0, sizeof(io));
3187
3188	bytes_read = 0;
3189	io.piod_op = PIOD_READ_D;
3190	io.piod_len = sizeof(tcb);
3191
3192	do {
3193		io.piod_addr = (char *)&tcb + bytes_read;
3194		io.piod_offs = io.piod_addr;
3195
3196		rv = ptrace(PT_IO, child, &io, sizeof(io));
3197		ATF_REQUIRE(rv != -1 && io.piod_len != 0);
3198
3199		bytes_read += io.piod_len;
3200		io.piod_len = sizeof(tcb) - bytes_read;
3201	} while (bytes_read < sizeof(tcb));
3202
3203	for (n = 0; n <= threads; n++) {
3204		if (strstr(iter, "LWPINFO") != NULL) {
3205			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3206			    "child\n");
3207			SYSCALL_REQUIRE(
3208			    ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
3209			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3210
3211			DPRINTF("Assert that the thread exists\n");
3212			ATF_REQUIRE(lwp.pl_lwpid > 0);
3213
3214			DPRINTF("Assert that lwp thread %d received expected "
3215			    "event\n", lwp.pl_lwpid);
3216			FORKEE_ASSERT_EQ(lwp.pl_event,
3217			    info.psi_lwpid == lwp.pl_lwpid ?
3218			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
3219
3220			if (strstr(iter, "LWPSTATUS") != NULL) {
3221				DPRINTF("Before calling ptrace(2) with "
3222				    "PT_LWPSTATUS for child\n");
3223				lwpstatus.pl_lwpid = lwp.pl_lwpid;
3224				SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child,
3225				    &lwpstatus, sizeof(lwpstatus)) != -1);
3226
3227				goto check_lwpstatus;
3228			}
3229		} else {
3230			DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for "
3231			    "child\n");
3232			SYSCALL_REQUIRE(
3233			    ptrace(PT_LWPNEXT, child, &lwpstatus,
3234			    sizeof(lwpstatus)) != -1);
3235			DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid);
3236
3237			DPRINTF("Assert that the thread exists\n");
3238			ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
3239
3240		check_lwpstatus:
3241
3242			if (strstr(iter, "pl_sigmask") != NULL) {
3243				sigmask = lwpstatus.pl_sigmask;
3244
3245				DPRINTF("Retrieved sigmask: "
3246				    "%02x%02x%02x%02x\n",
3247				    sigmask.__bits[0], sigmask.__bits[1],
3248				    sigmask.__bits[2], sigmask.__bits[3]);
3249
3250				found = false;
3251				for (m = 0;
3252				     m < __arraycount(lwpinfo_thread_sigmask);
3253				     m++) {
3254					if (sigismember(&sigmask,
3255					    lwpinfo_thread_sigmask[m])) {
3256						found = true;
3257						lwpinfo_thread_sigmask[m] = 0;
3258						break;
3259					}
3260				}
3261				ATF_REQUIRE(found == true);
3262			} else if (strstr(iter, "pl_name") != NULL) {
3263				name = lwpstatus.pl_name;
3264
3265				DPRINTF("Retrieved thread name: "
3266				    "%s\n", name);
3267
3268				snprintf(namebuf, sizeof namebuf, "thread %d",
3269				    lwpstatus.pl_lwpid);
3270
3271				ATF_REQUIRE(strcmp(name, namebuf) == 0);
3272			} else if (strstr(iter, "pl_private") != NULL) {
3273				private = lwpstatus.pl_private;
3274
3275				DPRINTF("Retrieved thread private pointer: "
3276				    "%p\n", private);
3277
3278				found = false;
3279				for (m = 0; m < __arraycount(tcb); m++) {
3280					DPRINTF("Comparing %p and %p\n",
3281					    private, tcb[m]);
3282					if (private == tcb[m]) {
3283						found = true;
3284						break;
3285					}
3286				}
3287				ATF_REQUIRE(found == true);
3288			}
3289		}
3290	}
3291
3292	if (strstr(iter, "LWPINFO") != NULL) {
3293		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3294		    "child\n");
3295		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
3296		    != -1);
3297		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3298
3299		DPRINTF("Assert that there are no more threads\n");
3300		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
3301	} else {
3302		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
3303		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
3304		    sizeof(lwpstatus)) != -1);
3305
3306		DPRINTF("Assert that there exists a single thread only\n");
3307		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
3308	}
3309
3310	DPRINTF("Before resuming the child process where it left off and "
3311	    "without signal to be sent\n");
3312	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
3313
3314	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3315	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3316
3317	validate_status_signaled(status, SIGKILL, 0);
3318
3319	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3320	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3321}
3322
3323#define TRACEME_LWPINFO(test, threads, iter)				\
3324ATF_TC(test);								\
3325ATF_TC_HEAD(test, tc)							\
3326{									\
3327	atf_tc_set_md_var(tc, "descr",					\
3328	    "Verify " iter " with the child with " #threads		\
3329	    " spawned extra threads");					\
3330}									\
3331									\
3332ATF_TC_BODY(test, tc)							\
3333{									\
3334									\
3335	traceme_lwpinfo(threads, iter);					\
3336}
3337
3338TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO")
3339TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO")
3340TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO")
3341TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO")
3342
3343TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS")
3344TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS")
3345TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS")
3346TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS")
3347
3348TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0,
3349    "LWPINFO+LWPSTATUS+pl_sigmask")
3350TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1,
3351    "LWPINFO+LWPSTATUS+pl_sigmask")
3352TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2,
3353    "LWPINFO+LWPSTATUS+pl_sigmask")
3354TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3,
3355    "LWPINFO+LWPSTATUS+pl_sigmask")
3356
3357TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0,
3358    "LWPINFO+LWPSTATUS+pl_name")
3359TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1,
3360    "LWPINFO+LWPSTATUS+pl_name")
3361TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2,
3362    "LWPINFO+LWPSTATUS+pl_name")
3363TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3,
3364    "LWPINFO+LWPSTATUS+pl_name")
3365
3366TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0,
3367    "LWPINFO+LWPSTATUS+pl_private")
3368TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1,
3369    "LWPINFO+LWPSTATUS+pl_private")
3370TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2,
3371    "LWPINFO+LWPSTATUS+pl_private")
3372TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3,
3373    "LWPINFO+LWPSTATUS+pl_private")
3374
3375TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT")
3376TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT")
3377TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT")
3378TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT")
3379
3380TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask")
3381TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask")
3382TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask")
3383TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask")
3384
3385TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name")
3386TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name")
3387TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name")
3388TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name")
3389
3390TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private")
3391TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private")
3392TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private")
3393TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private")
3394
3395/// ----------------------------------------------------------------------------
3396
3397#if defined(TWAIT_HAVE_PID)
3398static void
3399attach_lwpinfo(const int threads)
3400{
3401	const int sigval = SIGINT;
3402	struct msg_fds parent_tracee, parent_tracer;
3403	const int exitval_tracer = 10;
3404	pid_t tracee, tracer, wpid;
3405	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3406#if defined(TWAIT_HAVE_STATUS)
3407	int status;
3408#endif
3409	struct ptrace_lwpinfo lwp = {0, 0};
3410	struct ptrace_siginfo info;
3411
3412	/* Maximum number of supported threads in this test */
3413	pthread_t t[3];
3414	int n, rv;
3415
3416	DPRINTF("Spawn tracee\n");
3417	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3418	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3419	tracee = atf_utils_fork();
3420	if (tracee == 0) {
3421		/* Wait for message from the parent */
3422		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
3423
3424		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
3425
3426		for (n = 0; n < threads; n++) {
3427			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
3428			FORKEE_ASSERT(rv == 0);
3429		}
3430
3431		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
3432
3433		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3434		FORKEE_ASSERT(raise(sigval) == 0);
3435
3436		/* NOTREACHED */
3437		FORKEE_ASSERTX(0 && "Not reached");
3438	}
3439	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
3440
3441	DPRINTF("Spawn debugger\n");
3442	tracer = atf_utils_fork();
3443	if (tracer == 0) {
3444		/* No IPC to communicate with the child */
3445		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3446		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3447
3448		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3449		FORKEE_REQUIRE_SUCCESS(
3450		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3451
3452		forkee_status_stopped(status, SIGSTOP);
3453
3454		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
3455		    "tracee");
3456		FORKEE_ASSERT(
3457		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3458
3459		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3460		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3461		    "si_errno=%#x\n",
3462		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3463		    info.psi_siginfo.si_errno);
3464
3465		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
3466		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
3467
3468		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
3469		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
3470		    != -1);
3471
3472		DPRINTF("Assert that there exists a thread\n");
3473		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
3474
3475		DPRINTF("Assert that lwp thread %d received event "
3476		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
3477		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
3478
3479		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3480		    "tracee\n");
3481		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
3482		    != -1);
3483
3484		DPRINTF("Assert that there are no more lwp threads in "
3485		    "tracee\n");
3486		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
3487
3488		/* Resume tracee with PT_CONTINUE */
3489		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3490
3491		/* Inform parent that tracer has attached to tracee */
3492		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3493
3494		/* Wait for parent */
3495		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
3496
3497		/* Wait for tracee and assert that it raised a signal */
3498		FORKEE_REQUIRE_SUCCESS(
3499		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3500
3501		forkee_status_stopped(status, SIGINT);
3502
3503		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
3504		    "child");
3505		FORKEE_ASSERT(
3506		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3507
3508		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3509		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3510		    "si_errno=%#x\n",
3511		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3512		    info.psi_siginfo.si_errno);
3513
3514		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
3515		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
3516
3517		memset(&lwp, 0, sizeof(lwp));
3518
3519		for (n = 0; n <= threads; n++) {
3520			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3521			    "child\n");
3522			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
3523			    sizeof(lwp)) != -1);
3524			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3525
3526			DPRINTF("Assert that the thread exists\n");
3527			FORKEE_ASSERT(lwp.pl_lwpid > 0);
3528
3529			DPRINTF("Assert that lwp thread %d received expected "
3530			    "event\n", lwp.pl_lwpid);
3531			FORKEE_ASSERT_EQ(lwp.pl_event,
3532			    info.psi_lwpid == lwp.pl_lwpid ?
3533			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
3534		}
3535		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
3536		    "tracee\n");
3537		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
3538		    != -1);
3539		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
3540
3541		DPRINTF("Assert that there are no more threads\n");
3542		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
3543
3544		DPRINTF("Before resuming the child process where it left off "
3545		    "and without signal to be sent\n");
3546		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
3547		    != -1);
3548
3549		/* Wait for tracee and assert that it exited */
3550		FORKEE_REQUIRE_SUCCESS(
3551		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3552
3553		forkee_status_signaled(status, SIGKILL, 0);
3554
3555		DPRINTF("Before exiting of the tracer process\n");
3556		_exit(exitval_tracer);
3557	}
3558
3559	DPRINTF("Wait for the tracer to attach to the tracee\n");
3560	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3561
3562	DPRINTF("Resume the tracee and spawn threads\n");
3563	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
3564
3565	DPRINTF("Resume the tracee and let it exit\n");
3566	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
3567
3568	DPRINTF("Resume the tracer and let it detect multiple threads\n");
3569	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
3570
3571	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
3572	    TWAIT_FNAME);
3573	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
3574	    tracer);
3575
3576	validate_status_exited(status, exitval_tracer);
3577
3578	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3579	    TWAIT_FNAME);
3580	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
3581	    tracee);
3582
3583	validate_status_signaled(status, SIGKILL, 0);
3584
3585	msg_close(&parent_tracer);
3586	msg_close(&parent_tracee);
3587}
3588
3589#define ATTACH_LWPINFO(test, threads)					\
3590ATF_TC(test);								\
3591ATF_TC_HEAD(test, tc)							\
3592{									\
3593	atf_tc_set_md_var(tc, "descr",					\
3594	    "Verify LWPINFO with the child with " #threads		\
3595	    " spawned extra threads (tracer is not the original "	\
3596	    "parent)");							\
3597}									\
3598									\
3599ATF_TC_BODY(test, tc)							\
3600{									\
3601									\
3602	attach_lwpinfo(threads);					\
3603}
3604
3605ATTACH_LWPINFO(attach_lwpinfo0, 0)
3606ATTACH_LWPINFO(attach_lwpinfo1, 1)
3607ATTACH_LWPINFO(attach_lwpinfo2, 2)
3608ATTACH_LWPINFO(attach_lwpinfo3, 3)
3609#endif
3610
3611/// ----------------------------------------------------------------------------
3612
3613static void
3614ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
3615{
3616	const int exitval = 5;
3617	const int sigval = SIGINT;
3618	const int sigfaked = SIGTRAP;
3619	const int sicodefaked = TRAP_BRKPT;
3620	pid_t child, wpid;
3621	struct sigaction sa;
3622#if defined(TWAIT_HAVE_STATUS)
3623	int status;
3624#endif
3625	struct ptrace_siginfo info;
3626	memset(&info, 0, sizeof(info));
3627
3628	DPRINTF("Before forking process PID=%d\n", getpid());
3629	SYSCALL_REQUIRE((child = fork()) != -1);
3630	if (child == 0) {
3631		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3632		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3633
3634		sa.sa_sigaction = sah;
3635		sa.sa_flags = SA_SIGINFO;
3636		sigemptyset(&sa.sa_mask);
3637
3638		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
3639		    != -1);
3640
3641		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3642		FORKEE_ASSERT(raise(sigval) == 0);
3643
3644		FORKEE_ASSERT_EQ(*signal_caught, 1);
3645
3646		DPRINTF("Before exiting of the child process\n");
3647		_exit(exitval);
3648	}
3649	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3650
3651	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3652	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3653
3654	validate_status_stopped(status, sigval);
3655
3656	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3657	SYSCALL_REQUIRE(
3658	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3659
3660	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3661	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3662	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3663	    info.psi_siginfo.si_errno);
3664
3665	if (faked) {
3666		DPRINTF("Before setting new faked signal to signo=%d "
3667		    "si_code=%d\n", sigfaked, sicodefaked);
3668		info.psi_siginfo.si_signo = sigfaked;
3669		info.psi_siginfo.si_code = sicodefaked;
3670	}
3671
3672	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
3673	SYSCALL_REQUIRE(
3674	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
3675
3676	if (faked) {
3677		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
3678		    "child\n");
3679		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
3680		    sizeof(info)) != -1);
3681
3682		DPRINTF("Before checking siginfo_t\n");
3683		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
3684		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
3685	}
3686
3687	DPRINTF("Before resuming the child process where it left off and "
3688	    "without signal to be sent\n");
3689	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
3690	    faked ? sigfaked : sigval) != -1);
3691
3692	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3693	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3694
3695	validate_status_exited(status, exitval);
3696
3697	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3698	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3699}
3700
3701#define PTRACE_SIGINFO(test, faked)					\
3702ATF_TC(test);								\
3703ATF_TC_HEAD(test, tc)							\
3704{									\
3705	atf_tc_set_md_var(tc, "descr",					\
3706	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
3707	    "with%s setting signal to new value", faked ? "" : "out");	\
3708}									\
3709									\
3710static int test##_caught = 0;						\
3711									\
3712static void								\
3713test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
3714{									\
3715	if (faked) {							\
3716		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
3717		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
3718		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
3719	} else {							\
3720		FORKEE_ASSERT_EQ(sig, SIGINT);				\
3721		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
3722		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
3723	}								\
3724									\
3725	++ test##_caught;						\
3726}									\
3727									\
3728ATF_TC_BODY(test, tc)							\
3729{									\
3730									\
3731	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
3732}
3733
3734PTRACE_SIGINFO(siginfo_set_unmodified, false)
3735PTRACE_SIGINFO(siginfo_set_faked, true)
3736
3737/// ----------------------------------------------------------------------------
3738
3739static void
3740traceme_exec(bool masked, bool ignored)
3741{
3742	const int sigval = SIGTRAP;
3743	pid_t child, wpid;
3744#if defined(TWAIT_HAVE_STATUS)
3745	int status;
3746#endif
3747	struct sigaction sa;
3748	struct ptrace_siginfo info;
3749	sigset_t intmask;
3750	struct kinfo_proc2 kp;
3751	size_t len = sizeof(kp);
3752
3753	int name[6];
3754	const size_t namelen = __arraycount(name);
3755	ki_sigset_t kp_sigmask;
3756	ki_sigset_t kp_sigignore;
3757
3758	memset(&info, 0, sizeof(info));
3759
3760	DPRINTF("Before forking process PID=%d\n", getpid());
3761	SYSCALL_REQUIRE((child = fork()) != -1);
3762	if (child == 0) {
3763		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3764		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3765
3766		if (masked) {
3767			sigemptyset(&intmask);
3768			sigaddset(&intmask, sigval);
3769			sigprocmask(SIG_BLOCK, &intmask, NULL);
3770		}
3771
3772		if (ignored) {
3773			memset(&sa, 0, sizeof(sa));
3774			sa.sa_handler = SIG_IGN;
3775			sigemptyset(&sa.sa_mask);
3776			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
3777		}
3778
3779		DPRINTF("Before calling execve(2) from child\n");
3780		execlp("/bin/echo", "/bin/echo", NULL);
3781
3782		FORKEE_ASSERT(0 && "Not reached");
3783	}
3784	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3785
3786	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3787	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3788
3789	validate_status_stopped(status, sigval);
3790
3791	name[0] = CTL_KERN,
3792	name[1] = KERN_PROC2,
3793	name[2] = KERN_PROC_PID;
3794	name[3] = getpid();
3795	name[4] = sizeof(kp);
3796	name[5] = 1;
3797
3798	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
3799
3800	if (masked)
3801		kp_sigmask = kp.p_sigmask;
3802
3803	if (ignored)
3804		kp_sigignore = kp.p_sigignore;
3805
3806	name[3] = getpid();
3807
3808	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
3809
3810	if (masked) {
3811		DPRINTF("kp_sigmask="
3812		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
3813		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
3814		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
3815
3816		DPRINTF("kp.p_sigmask="
3817		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
3818		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
3819		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
3820
3821		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
3822		    sizeof(kp_sigmask)));
3823	}
3824
3825	if (ignored) {
3826		DPRINTF("kp_sigignore="
3827		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
3828		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
3829		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
3830
3831		DPRINTF("kp.p_sigignore="
3832		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
3833		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
3834		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
3835
3836		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
3837		    sizeof(kp_sigignore)));
3838	}
3839
3840	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3841	SYSCALL_REQUIRE(
3842	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3843
3844	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3845	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3846	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3847	    info.psi_siginfo.si_errno);
3848
3849	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3850	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
3851
3852	DPRINTF("Before resuming the child process where it left off and "
3853	    "without signal to be sent\n");
3854	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3855
3856	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3857	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3858
3859	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3860	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3861}
3862
3863#define TRACEME_EXEC(test, masked, ignored)				\
3864ATF_TC(test);								\
3865ATF_TC_HEAD(test, tc)							\
3866{									\
3867       atf_tc_set_md_var(tc, "descr",					\
3868           "Detect SIGTRAP TRAP_EXEC from "				\
3869           "child%s%s", masked ? " with masked signal" : "",		\
3870           masked ? " with ignored signal" : "");			\
3871}									\
3872									\
3873ATF_TC_BODY(test, tc)							\
3874{									\
3875									\
3876       traceme_exec(masked, ignored);					\
3877}
3878
3879TRACEME_EXEC(traceme_exec, false, false)
3880TRACEME_EXEC(traceme_signalmasked_exec, true, false)
3881TRACEME_EXEC(traceme_signalignored_exec, false, true)
3882
3883/// ----------------------------------------------------------------------------
3884
3885#define TRACE_THREADS_NUM 100
3886
3887static volatile int done;
3888pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
3889
3890static void *
3891trace_threads_cb(void *arg __unused)
3892{
3893
3894	pthread_mutex_lock(&trace_threads_mtx);
3895	done++;
3896	pthread_mutex_unlock(&trace_threads_mtx);
3897
3898	while (done < TRACE_THREADS_NUM)
3899		sched_yield();
3900
3901	return NULL;
3902}
3903
3904static void
3905trace_threads(bool trace_create, bool trace_exit, bool masked)
3906{
3907	const int sigval = SIGSTOP;
3908	pid_t child, wpid;
3909#if defined(TWAIT_HAVE_STATUS)
3910	int status;
3911#endif
3912	ptrace_state_t state;
3913	const int slen = sizeof(state);
3914	ptrace_event_t event;
3915	const int elen = sizeof(event);
3916	struct ptrace_siginfo info;
3917
3918	sigset_t intmask;
3919
3920	pthread_t t[TRACE_THREADS_NUM];
3921	int rv;
3922	size_t n;
3923	lwpid_t lid;
3924
3925	/* Track created and exited threads */
3926	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
3927
3928	DPRINTF("Before forking process PID=%d\n", getpid());
3929	SYSCALL_REQUIRE((child = fork()) != -1);
3930	if (child == 0) {
3931		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3932		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3933
3934		if (masked) {
3935			sigemptyset(&intmask);
3936			sigaddset(&intmask, SIGTRAP);
3937			sigprocmask(SIG_BLOCK, &intmask, NULL);
3938		}
3939
3940		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3941		FORKEE_ASSERT(raise(sigval) == 0);
3942
3943		for (n = 0; n < __arraycount(t); n++) {
3944			rv = pthread_create(&t[n], NULL, trace_threads_cb,
3945			    NULL);
3946			FORKEE_ASSERT(rv == 0);
3947		}
3948
3949		for (n = 0; n < __arraycount(t); n++) {
3950			rv = pthread_join(t[n], NULL);
3951			FORKEE_ASSERT(rv == 0);
3952		}
3953
3954		/*
3955		 * There is race between _exit() and pthread_join() detaching
3956		 * a thread. For simplicity kill the process after detecting
3957		 * LWP events.
3958		 */
3959		while (true)
3960			continue;
3961
3962		FORKEE_ASSERT(0 && "Not reached");
3963	}
3964	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3965
3966	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3967	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3968
3969	validate_status_stopped(status, sigval);
3970
3971	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
3972	SYSCALL_REQUIRE(
3973	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
3974
3975	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3976	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
3977	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
3978	    info.psi_siginfo.si_errno);
3979
3980	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
3981	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
3982
3983	DPRINTF("Set LWP event mask for the child %d\n", child);
3984	memset(&event, 0, sizeof(event));
3985	if (trace_create)
3986		event.pe_set_event |= PTRACE_LWP_CREATE;
3987	if (trace_exit)
3988		event.pe_set_event |= PTRACE_LWP_EXIT;
3989	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
3990
3991	DPRINTF("Before resuming the child process where it left off and "
3992	    "without signal to be sent\n");
3993	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3994
3995	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
3996		DPRINTF("Before calling %s() for the child - expected stopped "
3997		    "SIGTRAP\n", TWAIT_FNAME);
3998		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3999		    child);
4000
4001		validate_status_stopped(status, SIGTRAP);
4002
4003		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4004		    "child\n");
4005		SYSCALL_REQUIRE(
4006		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4007
4008		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4009		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4010		    "si_errno=%#x\n",
4011		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4012		    info.psi_siginfo.si_errno);
4013
4014		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4015		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4016
4017		SYSCALL_REQUIRE(
4018		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4019
4020		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
4021		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
4022
4023		lid = state.pe_lwp;
4024		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
4025
4026		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
4027
4028		DPRINTF("Before resuming the child process where it left off "
4029		    "and without signal to be sent\n");
4030		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4031	}
4032
4033	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
4034		DPRINTF("Before calling %s() for the child - expected stopped "
4035		    "SIGTRAP\n", TWAIT_FNAME);
4036		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4037		    child);
4038
4039		validate_status_stopped(status, SIGTRAP);
4040
4041		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4042		    "child\n");
4043		SYSCALL_REQUIRE(
4044		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4045
4046		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4047		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4048		    "si_errno=%#x\n",
4049		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4050		    info.psi_siginfo.si_errno);
4051
4052		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4053		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4054
4055		SYSCALL_REQUIRE(
4056		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4057
4058		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
4059		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
4060
4061		lid = state.pe_lwp;
4062		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
4063
4064		if (trace_create) {
4065			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
4066			ATF_REQUIRE_EQ(*count, 1);
4067			*count = 0;
4068		}
4069
4070		DPRINTF("Before resuming the child process where it left off "
4071		    "and without signal to be sent\n");
4072		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4073	}
4074
4075	kill(child, SIGKILL);
4076
4077	DPRINTF("Before calling %s() for the child - expected exited\n",
4078	    TWAIT_FNAME);
4079	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4080
4081	validate_status_signaled(status, SIGKILL, 0);
4082
4083	DPRINTF("Before calling %s() for the child - expected no process\n",
4084	    TWAIT_FNAME);
4085	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4086}
4087
4088#define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
4089ATF_TC(test);								\
4090ATF_TC_HEAD(test, tc)							\
4091{									\
4092        atf_tc_set_md_var(tc, "descr",					\
4093            "Verify spawning threads with%s tracing LWP create and"	\
4094	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
4095	    trace_exit ? "" : "out");					\
4096}									\
4097									\
4098ATF_TC_BODY(test, tc)							\
4099{									\
4100									\
4101        trace_threads(trace_create, trace_exit, mask);			\
4102}
4103
4104TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
4105TRACE_THREADS(trace_thread_lwpexit, false, true, false)
4106TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
4107TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
4108
4109TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
4110TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
4111TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
4112
4113/// ----------------------------------------------------------------------------
4114
4115ATF_TC(signal_mask_unrelated);
4116ATF_TC_HEAD(signal_mask_unrelated, tc)
4117{
4118	atf_tc_set_md_var(tc, "descr",
4119	    "Verify that masking single unrelated signal does not stop tracer "
4120	    "from catching other signals");
4121}
4122
4123ATF_TC_BODY(signal_mask_unrelated, tc)
4124{
4125	const int exitval = 5;
4126	const int sigval = SIGSTOP;
4127	const int sigmasked = SIGTRAP;
4128	const int signotmasked = SIGINT;
4129	pid_t child, wpid;
4130#if defined(TWAIT_HAVE_STATUS)
4131	int status;
4132#endif
4133	sigset_t intmask;
4134
4135	DPRINTF("Before forking process PID=%d\n", getpid());
4136	SYSCALL_REQUIRE((child = fork()) != -1);
4137	if (child == 0) {
4138		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4139		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4140
4141		sigemptyset(&intmask);
4142		sigaddset(&intmask, sigmasked);
4143		sigprocmask(SIG_BLOCK, &intmask, NULL);
4144
4145		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4146		FORKEE_ASSERT(raise(sigval) == 0);
4147
4148		DPRINTF("Before raising %s from child\n",
4149		    strsignal(signotmasked));
4150		FORKEE_ASSERT(raise(signotmasked) == 0);
4151
4152		DPRINTF("Before exiting of the child process\n");
4153		_exit(exitval);
4154	}
4155	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4156
4157	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4158	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4159
4160	validate_status_stopped(status, sigval);
4161
4162	DPRINTF("Before resuming the child process where it left off and "
4163	    "without signal to be sent\n");
4164	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4165
4166	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4167	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4168
4169	validate_status_stopped(status, signotmasked);
4170
4171	DPRINTF("Before resuming the child process where it left off and "
4172	    "without signal to be sent\n");
4173	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4174
4175	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4176	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4177
4178	validate_status_exited(status, exitval);
4179
4180	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4181	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4182}
4183
4184/// ----------------------------------------------------------------------------
4185
4186static void *
4187thread_and_exec_thread_cb(void *arg __unused)
4188{
4189
4190	execlp("/bin/echo", "/bin/echo", NULL);
4191
4192	abort();
4193}
4194
4195static void
4196threads_and_exec(void)
4197{
4198	const int sigval = SIGSTOP;
4199	pid_t child, wpid;
4200#if defined(TWAIT_HAVE_STATUS)
4201	int status;
4202#endif
4203	ptrace_state_t state;
4204	const int slen = sizeof(state);
4205	ptrace_event_t event;
4206	const int elen = sizeof(event);
4207	struct ptrace_siginfo info;
4208
4209	pthread_t t;
4210	lwpid_t lid;
4211
4212	DPRINTF("Before forking process PID=%d\n", getpid());
4213	SYSCALL_REQUIRE((child = fork()) != -1);
4214	if (child == 0) {
4215		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4216		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4217
4218		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4219		FORKEE_ASSERT(raise(sigval) == 0);
4220
4221		FORKEE_ASSERT(pthread_create(&t, NULL,
4222		    thread_and_exec_thread_cb, NULL) == 0);
4223
4224		for (;;)
4225			continue;
4226
4227		FORKEE_ASSERT(0 && "Not reached");
4228	}
4229	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4230
4231	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4232	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4233
4234	validate_status_stopped(status, sigval);
4235
4236	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4237	SYSCALL_REQUIRE(
4238	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4239
4240	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4241	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
4242	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4243	    info.psi_siginfo.si_errno);
4244
4245	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4246	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4247
4248	DPRINTF("Set LWP event mask for the child %d\n", child);
4249	memset(&event, 0, sizeof(event));
4250	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
4251	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
4252
4253	DPRINTF("Before resuming the child process where it left off and "
4254	    "without signal to be sent\n");
4255	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4256
4257	DPRINTF("Before calling %s() for the child - expected stopped "
4258	    "SIGTRAP\n", TWAIT_FNAME);
4259	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4260	    child);
4261
4262	validate_status_stopped(status, SIGTRAP);
4263
4264	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4265	    "child\n");
4266	SYSCALL_REQUIRE(
4267	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4268
4269	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4270	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4271	    "si_errno=%#x\n",
4272	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4273	    info.psi_siginfo.si_errno);
4274
4275	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4276	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4277
4278	SYSCALL_REQUIRE(
4279	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4280
4281	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
4282	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
4283
4284	lid = state.pe_lwp;
4285	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
4286
4287	DPRINTF("Before resuming the child process where it left off "
4288	    "and without signal to be sent\n");
4289	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4290
4291	DPRINTF("Before calling %s() for the child - expected stopped "
4292	    "SIGTRAP\n", TWAIT_FNAME);
4293	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4294	    child);
4295
4296	validate_status_stopped(status, SIGTRAP);
4297
4298	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4299	    "child\n");
4300	SYSCALL_REQUIRE(
4301	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4302
4303	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4304	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4305	    "si_errno=%#x\n",
4306	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4307	    info.psi_siginfo.si_errno);
4308
4309	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4310	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
4311
4312	SYSCALL_REQUIRE(
4313	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
4314
4315	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
4316	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
4317
4318	lid = state.pe_lwp;
4319	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
4320
4321	DPRINTF("Before resuming the child process where it left off "
4322	    "and without signal to be sent\n");
4323	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4324
4325	DPRINTF("Before calling %s() for the child - expected stopped "
4326	    "SIGTRAP\n", TWAIT_FNAME);
4327	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4328	    child);
4329
4330	validate_status_stopped(status, SIGTRAP);
4331
4332	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4333	    "child\n");
4334	SYSCALL_REQUIRE(
4335	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
4336
4337	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4338	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4339	    "si_errno=%#x\n",
4340	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4341	    info.psi_siginfo.si_errno);
4342
4343	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
4344	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
4345
4346	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
4347
4348	DPRINTF("Before calling %s() for the child - expected exited\n",
4349	    TWAIT_FNAME);
4350	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4351
4352	validate_status_signaled(status, SIGKILL, 0);
4353
4354	DPRINTF("Before calling %s() for the child - expected no process\n",
4355	    TWAIT_FNAME);
4356	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4357}
4358
4359ATF_TC(threads_and_exec);
4360ATF_TC_HEAD(threads_and_exec, tc)
4361{
4362        atf_tc_set_md_var(tc, "descr",
4363            "Verify that multithreaded application on exec() will report "
4364	    "LWP_EXIT events");
4365}
4366
4367ATF_TC_BODY(threads_and_exec, tc)
4368{
4369
4370        threads_and_exec();
4371}
4372
4373/// ----------------------------------------------------------------------------
4374
4375ATF_TC(suspend_no_deadlock);
4376ATF_TC_HEAD(suspend_no_deadlock, tc)
4377{
4378	atf_tc_set_md_var(tc, "descr",
4379	    "Verify that the while the only thread within a process is "
4380	    "suspended, the whole process cannot be unstopped");
4381}
4382
4383ATF_TC_BODY(suspend_no_deadlock, tc)
4384{
4385	const int exitval = 5;
4386	const int sigval = SIGSTOP;
4387	pid_t child, wpid;
4388#if defined(TWAIT_HAVE_STATUS)
4389	int status;
4390#endif
4391	struct ptrace_siginfo psi;
4392
4393	DPRINTF("Before forking process PID=%d\n", getpid());
4394	SYSCALL_REQUIRE((child = fork()) != -1);
4395	if (child == 0) {
4396		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4397		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4398
4399		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4400		FORKEE_ASSERT(raise(sigval) == 0);
4401
4402		DPRINTF("Before exiting of the child process\n");
4403		_exit(exitval);
4404	}
4405	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4406
4407	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4408	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4409
4410	validate_status_stopped(status, sigval);
4411
4412	DPRINTF("Before reading siginfo and lwpid_t\n");
4413	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
4414
4415	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
4416	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
4417
4418	DPRINTF("Before resuming the child process where it left off and "
4419	    "without signal to be sent\n");
4420	ATF_REQUIRE_ERRNO(EDEADLK,
4421	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
4422
4423	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
4424	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
4425
4426	DPRINTF("Before resuming the child process where it left off and "
4427	    "without signal to be sent\n");
4428	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4429
4430	DPRINTF("Before calling %s() for the child - expected exited\n",
4431	    TWAIT_FNAME);
4432	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4433
4434	validate_status_exited(status, exitval);
4435
4436	DPRINTF("Before calling %s() for the child - expected no process\n",
4437	    TWAIT_FNAME);
4438	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4439}
4440
4441/// ----------------------------------------------------------------------------
4442
4443static pthread_barrier_t barrier1_resume;
4444static pthread_barrier_t barrier2_resume;
4445
4446static void *
4447resume_thread(void *arg)
4448{
4449
4450	raise(SIGUSR1);
4451
4452	pthread_barrier_wait(&barrier1_resume);
4453
4454	/* Debugger will suspend the process here */
4455
4456	pthread_barrier_wait(&barrier2_resume);
4457
4458	raise(SIGUSR2);
4459
4460	return infinite_thread(arg);
4461}
4462
4463ATF_TC(resume);
4464ATF_TC_HEAD(resume, tc)
4465{
4466	atf_tc_set_md_var(tc, "descr",
4467	    "Verify that a thread can be suspended by a debugger and later "
4468	    "resumed by the debugger");
4469}
4470
4471ATF_TC_BODY(resume, tc)
4472{
4473	const int sigval = SIGSTOP;
4474	pid_t child, wpid;
4475#if defined(TWAIT_HAVE_STATUS)
4476	int status;
4477#endif
4478	lwpid_t lid;
4479	struct ptrace_siginfo psi;
4480	pthread_t t;
4481
4482	DPRINTF("Before forking process PID=%d\n", getpid());
4483	SYSCALL_REQUIRE((child = fork()) != -1);
4484	if (child == 0) {
4485		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4486		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4487
4488		pthread_barrier_init(&barrier1_resume, NULL, 2);
4489		pthread_barrier_init(&barrier2_resume, NULL, 2);
4490
4491		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4492		FORKEE_ASSERT(raise(sigval) == 0);
4493
4494		DPRINTF("Before creating new thread in child\n");
4495		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
4496
4497		pthread_barrier_wait(&barrier1_resume);
4498
4499		pthread_barrier_wait(&barrier2_resume);
4500
4501		infinite_thread(NULL);
4502	}
4503	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4504
4505	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4506	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4507
4508	validate_status_stopped(status, sigval);
4509
4510	DPRINTF("Before resuming the child process where it left off and "
4511	    "without signal to be sent\n");
4512	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4513
4514	DPRINTF("Before calling %s() for the child - expected stopped "
4515	    "SIGUSR1\n", TWAIT_FNAME);
4516	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4517
4518	validate_status_stopped(status, SIGUSR1);
4519
4520	DPRINTF("Before reading siginfo and lwpid_t\n");
4521	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
4522
4523	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
4524	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
4525
4526	lid = psi.psi_lwpid;
4527
4528	DPRINTF("Before resuming the child process where it left off and "
4529	    "without signal to be sent\n");
4530	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4531
4532	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
4533	SYSCALL_REQUIRE(sleep(1) == 0);
4534
4535#if defined(TWAIT_HAVE_OPTIONS)
4536	DPRINTF("Before calling %s() for the child - expected no status\n",
4537	    TWAIT_FNAME);
4538	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
4539#endif
4540
4541	DPRINTF("Before resuming the child process where it left off and "
4542	    "without signal to be sent\n");
4543	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
4544
4545	DPRINTF("Before calling %s() for the child - expected stopped "
4546	    "SIGSTOP\n", TWAIT_FNAME);
4547	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4548
4549	validate_status_stopped(status, SIGSTOP);
4550
4551	DPRINTF("Before resuming LWP %d\n", lid);
4552	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
4553
4554	DPRINTF("Before resuming the child process where it left off and "
4555	    "without signal to be sent\n");
4556	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4557
4558	DPRINTF("Before calling %s() for the child - expected stopped "
4559	    "SIGUSR2\n", TWAIT_FNAME);
4560	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4561
4562	validate_status_stopped(status, SIGUSR2);
4563
4564	DPRINTF("Before resuming the child process where it left off and "
4565	    "without signal to be sent\n");
4566	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
4567
4568	DPRINTF("Before calling %s() for the child - expected exited\n",
4569	    TWAIT_FNAME);
4570	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4571
4572	validate_status_signaled(status, SIGKILL, 0);
4573
4574	DPRINTF("Before calling %s() for the child - expected no process\n",
4575	    TWAIT_FNAME);
4576	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4577}
4578
4579/// ----------------------------------------------------------------------------
4580
4581static void
4582user_va0_disable(int operation)
4583{
4584	pid_t child, wpid;
4585#if defined(TWAIT_HAVE_STATUS)
4586	int status;
4587#endif
4588	const int sigval = SIGSTOP;
4589	int rv;
4590
4591	struct ptrace_siginfo info;
4592
4593	if (get_user_va0_disable() == 0)
4594		atf_tc_skip("vm.user_va0_disable is set to 0");
4595
4596	memset(&info, 0, sizeof(info));
4597
4598	DPRINTF("Before forking process PID=%d\n", getpid());
4599	SYSCALL_REQUIRE((child = fork()) != -1);
4600	if (child == 0) {
4601		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4602		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4603
4604		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4605		FORKEE_ASSERT(raise(sigval) == 0);
4606
4607		/* NOTREACHED */
4608		FORKEE_ASSERTX(0 && "This shall not be reached");
4609		__unreachable();
4610	}
4611	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4612
4613	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4614	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4615
4616	validate_status_stopped(status, sigval);
4617
4618	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
4619		"child\n");
4620	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
4621		sizeof(info)) != -1);
4622
4623	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4624	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4625		"si_errno=%#x\n",
4626		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4627		info.psi_siginfo.si_errno);
4628
4629	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4630	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4631
4632	DPRINTF("Before resuming the child process in PC=0x0 "
4633	    "and without signal to be sent\n");
4634	errno = 0;
4635	rv = ptrace(operation, child, (void *)0, 0);
4636	ATF_REQUIRE_EQ(errno, EINVAL);
4637	ATF_REQUIRE_EQ(rv, -1);
4638
4639	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
4640
4641	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4642	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4643	validate_status_signaled(status, SIGKILL, 0);
4644
4645	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4646	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4647}
4648
4649#define USER_VA0_DISABLE(test, operation)				\
4650ATF_TC(test);								\
4651ATF_TC_HEAD(test, tc)							\
4652{									\
4653	atf_tc_set_md_var(tc, "descr",					\
4654	    "Verify behavior of " #operation " with PC set to 0x0");	\
4655}									\
4656									\
4657ATF_TC_BODY(test, tc)							\
4658{									\
4659									\
4660	user_va0_disable(operation);					\
4661}
4662
4663USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
4664USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
4665USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
4666
4667/// ----------------------------------------------------------------------------
4668
4669/*
4670 * Parse the core file and find the requested note.  If the reading or parsing
4671 * fails, the test is failed.  If the note is found, it is read onto buf, up to
4672 * buf_len.  The actual length of the note is returned (which can be greater
4673 * than buf_len, indicating that it has been truncated).  If the note is not
4674 * found, -1 is returned.
4675 *
4676 * If the note_name ends in '*', then we find the first note that matches
4677 * the note_name prefix up to the '*' character, e.g.:
4678 *
4679 *	NetBSD-CORE@*
4680 *
4681 * finds the first note whose name prefix matches "NetBSD-CORE@".
4682 */
4683static ssize_t core_find_note(const char *core_path,
4684    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
4685{
4686	int core_fd;
4687	Elf *core_elf;
4688	size_t core_numhdr, i;
4689	ssize_t ret = -1;
4690	size_t name_len = strlen(note_name);
4691	bool prefix_match = false;
4692
4693	if (note_name[name_len - 1] == '*') {
4694		prefix_match = true;
4695		name_len--;
4696	} else {
4697		/* note: we assume note name will be null-terminated */
4698		name_len++;
4699	}
4700
4701	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
4702	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
4703	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
4704
4705	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
4706	for (i = 0; i < core_numhdr && ret == -1; i++) {
4707		GElf_Phdr core_hdr;
4708		size_t offset;
4709		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
4710		if (core_hdr.p_type != PT_NOTE)
4711		    continue;
4712
4713		for (offset = core_hdr.p_offset;
4714		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
4715			Elf64_Nhdr note_hdr;
4716			char name_buf[64];
4717
4718			switch (gelf_getclass(core_elf)) {
4719			case ELFCLASS64:
4720				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
4721				    sizeof(note_hdr), offset)
4722				    == sizeof(note_hdr));
4723				offset += sizeof(note_hdr);
4724				break;
4725			case ELFCLASS32:
4726				{
4727				Elf32_Nhdr tmp_hdr;
4728				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
4729				    sizeof(tmp_hdr), offset)
4730				    == sizeof(tmp_hdr));
4731				offset += sizeof(tmp_hdr);
4732				note_hdr.n_namesz = tmp_hdr.n_namesz;
4733				note_hdr.n_descsz = tmp_hdr.n_descsz;
4734				note_hdr.n_type = tmp_hdr.n_type;
4735				}
4736				break;
4737			}
4738
4739			/* indicates end of notes */
4740			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
4741				break;
4742			if (((prefix_match &&
4743			      note_hdr.n_namesz > name_len) ||
4744			     (!prefix_match &&
4745			      note_hdr.n_namesz == name_len)) &&
4746			    note_hdr.n_namesz <= sizeof(name_buf)) {
4747				SYSCALL_REQUIRE(pread(core_fd, name_buf,
4748				    note_hdr.n_namesz, offset)
4749				    == (ssize_t)(size_t)note_hdr.n_namesz);
4750
4751				if (!strncmp(note_name, name_buf, name_len) &&
4752				    note_hdr.n_type == note_type)
4753					ret = note_hdr.n_descsz;
4754			}
4755
4756			offset += note_hdr.n_namesz;
4757			/* fix to alignment */
4758			offset = roundup(offset, core_hdr.p_align);
4759
4760			/* if name & type matched above */
4761			if (ret != -1) {
4762				ssize_t read_len = MIN(buf_len,
4763				    note_hdr.n_descsz);
4764				SYSCALL_REQUIRE(pread(core_fd, buf,
4765				    read_len, offset) == read_len);
4766				break;
4767			}
4768
4769			offset += note_hdr.n_descsz;
4770			/* fix to alignment */
4771			offset = roundup(offset, core_hdr.p_align);
4772		}
4773	}
4774
4775	elf_end(core_elf);
4776	close(core_fd);
4777
4778	return ret;
4779}
4780
4781ATF_TC(core_dump_procinfo);
4782ATF_TC_HEAD(core_dump_procinfo, tc)
4783{
4784	atf_tc_set_md_var(tc, "descr",
4785		"Trigger a core dump and verify its contents.");
4786}
4787
4788ATF_TC_BODY(core_dump_procinfo, tc)
4789{
4790	const int exitval = 5;
4791	pid_t child, wpid;
4792#if defined(TWAIT_HAVE_STATUS)
4793	const int sigval = SIGTRAP;
4794	int status;
4795#endif
4796	char core_path[] = "/tmp/core.XXXXXX";
4797	int core_fd;
4798	struct netbsd_elfcore_procinfo procinfo;
4799
4800	DPRINTF("Before forking process PID=%d\n", getpid());
4801	SYSCALL_REQUIRE((child = fork()) != -1);
4802	if (child == 0) {
4803		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4804		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4805
4806		DPRINTF("Before triggering SIGTRAP\n");
4807		trigger_trap();
4808
4809		DPRINTF("Before exiting of the child process\n");
4810		_exit(exitval);
4811	}
4812	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4813
4814	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4815	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4816
4817	validate_status_stopped(status, sigval);
4818
4819	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
4820	close(core_fd);
4821
4822	DPRINTF("Call DUMPCORE for the child process\n");
4823	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
4824	    != -1);
4825
4826	DPRINTF("Read core file\n");
4827	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
4828	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
4829	    sizeof(procinfo));
4830
4831	ATF_CHECK_EQ(procinfo.cpi_version, 1);
4832	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
4833	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
4834	ATF_CHECK_EQ(procinfo.cpi_pid, child);
4835	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
4836	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
4837	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
4838	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
4839	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
4840	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
4841	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
4842	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
4843	ATF_CHECK(procinfo.cpi_siglwp > 0);
4844
4845	unlink(core_path);
4846
4847	DPRINTF("Before resuming the child process where it left off and "
4848	    "without signal to be sent\n");
4849	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4850
4851	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4852	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4853
4854	validate_status_exited(status, exitval);
4855
4856	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4857	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4858}
4859
4860/// ----------------------------------------------------------------------------
4861
4862#if defined(TWAIT_HAVE_STATUS)
4863
4864#define THREAD_CONCURRENT_BREAKPOINT_NUM 50
4865#define THREAD_CONCURRENT_SIGNALS_NUM 50
4866#define THREAD_CONCURRENT_WATCHPOINT_NUM 50
4867
4868/* List of signals to use for the test */
4869const int thread_concurrent_signals_list[] = {
4870	SIGIO,
4871	SIGXCPU,
4872	SIGXFSZ,
4873	SIGVTALRM,
4874	SIGPROF,
4875	SIGWINCH,
4876	SIGINFO,
4877	SIGUSR1,
4878	SIGUSR2
4879};
4880
4881enum thread_concurrent_signal_handling {
4882	/* the signal is discarded by debugger */
4883	TCSH_DISCARD,
4884	/* the handler is set to SIG_IGN */
4885	TCSH_SIG_IGN,
4886	/* an actual handler is used */
4887	TCSH_HANDLER
4888};
4889
4890static pthread_barrier_t thread_concurrent_barrier;
4891static pthread_key_t thread_concurrent_key;
4892static uint32_t thread_concurrent_watchpoint_var = 0;
4893
4894static void *
4895thread_concurrent_breakpoint_thread(void *arg)
4896{
4897	static volatile int watchme = 1;
4898	pthread_barrier_wait(&thread_concurrent_barrier);
4899	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
4900	check_happy(watchme);
4901	return NULL;
4902}
4903
4904static void
4905thread_concurrent_sig_handler(int sig)
4906{
4907	void *tls_val = pthread_getspecific(thread_concurrent_key);
4908	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
4909	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
4910	    (void*)((uintptr_t)tls_val + 1)) == 0);
4911}
4912
4913static void *
4914thread_concurrent_signals_thread(void *arg)
4915{
4916	int sigval = thread_concurrent_signals_list[
4917	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
4918	enum thread_concurrent_signal_handling *signal_handle = arg;
4919	void *tls_val;
4920
4921	pthread_barrier_wait(&thread_concurrent_barrier);
4922	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
4923		_lwp_self());
4924	pthread_kill(pthread_self(), sigval);
4925	if (*signal_handle == TCSH_HANDLER) {
4926	    tls_val = pthread_getspecific(thread_concurrent_key);
4927	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
4928	    FORKEE_ASSERT(tls_val == (void*)1);
4929	}
4930	return NULL;
4931}
4932
4933static void *
4934thread_concurrent_watchpoint_thread(void *arg)
4935{
4936	pthread_barrier_wait(&thread_concurrent_barrier);
4937	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
4938	thread_concurrent_watchpoint_var = 1;
4939	return NULL;
4940}
4941
4942#if defined(__i386__) || defined(__x86_64__)
4943enum thread_concurrent_sigtrap_event {
4944	TCSE_UNKNOWN,
4945	TCSE_BREAKPOINT,
4946	TCSE_WATCHPOINT
4947};
4948
4949static void
4950thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
4951static enum thread_concurrent_sigtrap_event
4952thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
4953#endif
4954
4955static void
4956thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
4957    int breakpoint_threads, int signal_threads, int watchpoint_threads)
4958{
4959	const int exitval = 5;
4960	const int sigval = SIGSTOP;
4961	pid_t child, wpid;
4962	int status;
4963	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
4964	    = {{0, 0}};
4965	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
4966	    = {{0, 0}};
4967	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
4968	    = {{0, 0}};
4969	ptrace_event_t event;
4970	int i;
4971
4972#if defined(HAVE_DBREGS)
4973	if (!can_we_set_dbregs()) {
4974		atf_tc_skip("Either run this test as root or set sysctl(3) "
4975		            "security.models.extensions.user_set_dbregs to 1");
4976        }
4977#endif
4978
4979	atf_tc_skip("PR kern/54960");
4980
4981	/* Protect against out-of-bounds array access. */
4982	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
4983	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
4984	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
4985
4986	DPRINTF("Before forking process PID=%d\n", getpid());
4987	SYSCALL_REQUIRE((child = fork()) != -1);
4988	if (child == 0) {
4989		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
4990		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
4991		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
4992
4993		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4994		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4995
4996		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4997		FORKEE_ASSERT(raise(sigval) == 0);
4998
4999		if (signal_handle != TCSH_DISCARD) {
5000			struct sigaction sa;
5001			unsigned int j;
5002
5003			memset(&sa, 0, sizeof(sa));
5004			if (signal_handle == TCSH_SIG_IGN)
5005				sa.sa_handler = SIG_IGN;
5006			else
5007				sa.sa_handler = thread_concurrent_sig_handler;
5008			sigemptyset(&sa.sa_mask);
5009
5010			for (j = 0;
5011			    j < __arraycount(thread_concurrent_signals_list);
5012			    j++)
5013				FORKEE_ASSERT(sigaction(
5014				    thread_concurrent_signals_list[j], &sa, NULL)
5015				    != -1);
5016		}
5017
5018		DPRINTF("Before starting threads from the child\n");
5019		FORKEE_ASSERT(pthread_barrier_init(
5020		    &thread_concurrent_barrier, NULL,
5021		    breakpoint_threads + signal_threads + watchpoint_threads)
5022		    == 0);
5023		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
5024		    == 0);
5025
5026		for (i = 0; i < signal_threads; i++) {
5027			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
5028			    thread_concurrent_signals_thread,
5029			    &signal_handle) == 0);
5030		}
5031		for (i = 0; i < breakpoint_threads; i++) {
5032			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
5033			    thread_concurrent_breakpoint_thread, NULL) == 0);
5034		}
5035		for (i = 0; i < watchpoint_threads; i++) {
5036			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
5037			    thread_concurrent_watchpoint_thread, NULL) == 0);
5038		}
5039
5040		DPRINTF("Before joining threads from the child\n");
5041		for (i = 0; i < watchpoint_threads; i++) {
5042			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
5043		}
5044		for (i = 0; i < breakpoint_threads; i++) {
5045			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
5046		}
5047		for (i = 0; i < signal_threads; i++) {
5048			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
5049		}
5050
5051		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
5052		FORKEE_ASSERT(pthread_barrier_destroy(
5053		    &thread_concurrent_barrier) == 0);
5054
5055		DPRINTF("Before exiting of the child process\n");
5056		_exit(exitval);
5057	}
5058	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5059
5060	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5061	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5062
5063	validate_status_stopped(status, sigval);
5064
5065	DPRINTF("Set LWP event mask for the child process\n");
5066	memset(&event, 0, sizeof(event));
5067	event.pe_set_event |= PTRACE_LWP_CREATE;
5068	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
5069	    != -1);
5070
5071	DPRINTF("Before resuming the child process where it left off\n");
5072	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5073
5074	DPRINTF("Before entering signal collection loop\n");
5075	while (1) {
5076		ptrace_siginfo_t info;
5077
5078		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5079		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
5080		    child);
5081		if (WIFEXITED(status))
5082			break;
5083		/* Note: we use validate_status_stopped() to get nice error
5084		 * message.  Signal is irrelevant since it won't be reached.
5085		 */
5086		else if (!WIFSTOPPED(status))
5087			validate_status_stopped(status, 0);
5088
5089		DPRINTF("Before calling PT_GET_SIGINFO\n");
5090		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
5091		    sizeof(info)) != -1);
5092
5093		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
5094		    info.psi_siginfo.si_signo, info.psi_lwpid,
5095		    WSTOPSIG(status));
5096
5097		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
5098		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
5099		    WSTOPSIG(status), info.psi_siginfo.si_signo);
5100
5101		if (WSTOPSIG(status) != SIGTRAP) {
5102			int expected_sig =
5103			    thread_concurrent_signals_list[info.psi_lwpid %
5104			    __arraycount(thread_concurrent_signals_list)];
5105			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
5106				"lwp=%d, expected %d, got %d", info.psi_lwpid,
5107				expected_sig, WSTOPSIG(status));
5108
5109			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
5110		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
5111#if defined(__i386__) || defined(__x86_64__)
5112			thread_concurrent_lwp_setup(child, info.psi_lwpid);
5113#endif
5114		} else {
5115#if defined(__i386__) || defined(__x86_64__)
5116			switch (thread_concurrent_handle_sigtrap(child, &info)) {
5117				case TCSE_UNKNOWN:
5118					/* already reported inside the function */
5119					break;
5120				case TCSE_BREAKPOINT:
5121					*FIND_EVENT_COUNT(bp_counts,
5122					    info.psi_lwpid) += 1;
5123					break;
5124				case TCSE_WATCHPOINT:
5125					*FIND_EVENT_COUNT(wp_counts,
5126					    info.psi_lwpid) += 1;
5127					break;
5128			}
5129#else
5130			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
5131			    info.psi_siginfo.si_code);
5132#endif
5133		}
5134
5135		DPRINTF("Before resuming the child process\n");
5136		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
5137		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
5138		     ? WSTOPSIG(status) : 0) != -1);
5139	}
5140
5141	for (i = 0; i < signal_threads; i++)
5142		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
5143		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
5144		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
5145	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
5146		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
5147		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
5148		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
5149
5150	for (i = 0; i < breakpoint_threads; i++)
5151		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
5152		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
5153		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
5154	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
5155		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
5156		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
5157		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
5158
5159	for (i = 0; i < watchpoint_threads; i++)
5160		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
5161		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
5162		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
5163	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
5164		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
5165		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
5166		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
5167
5168	validate_status_exited(status, exitval);
5169}
5170
5171#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
5172ATF_TC(test);								\
5173ATF_TC_HEAD(test, tc)							\
5174{									\
5175	atf_tc_set_md_var(tc, "descr", descr);				\
5176}									\
5177									\
5178ATF_TC_BODY(test, tc)							\
5179{									\
5180	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
5181}
5182
5183THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
5184    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5185    "Verify that concurrent signals issued to a single thread are reported "
5186    "correctly");
5187THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
5188    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5189    "Verify that concurrent signals issued to a single thread are reported "
5190    "correctly and passed back to SIG_IGN handler");
5191THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
5192    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5193    "Verify that concurrent signals issued to a single thread are reported "
5194    "correctly and passed back to a handler function");
5195
5196#if defined(__i386__) || defined(__x86_64__)
5197THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
5198    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
5199    "Verify that concurrent breakpoints are reported correctly");
5200THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
5201    0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
5202    "Verify that concurrent breakpoints are reported correctly");
5203THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
5204    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
5205    "Verify that concurrent breakpoints and watchpoints are reported "
5206    "correctly");
5207
5208THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
5209    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5210    "Verify that concurrent breakpoints and signals are reported correctly");
5211THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
5212    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5213    "Verify that concurrent breakpoints and signals are reported correctly "
5214    "and passed back to SIG_IGN handler");
5215THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
5216    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
5217    "Verify that concurrent breakpoints and signals are reported correctly "
5218    "and passed back to a handler function");
5219
5220THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
5221    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
5222    "Verify that concurrent watchpoints and signals are reported correctly");
5223THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
5224    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
5225    "Verify that concurrent watchpoints and signals are reported correctly "
5226    "and passed back to SIG_IGN handler");
5227THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
5228    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
5229    "Verify that concurrent watchpoints and signals are reported correctly "
5230    "and passed back to a handler function");
5231
5232THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
5233    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
5234    THREAD_CONCURRENT_WATCHPOINT_NUM,
5235    "Verify that concurrent breakpoints, watchpoints and signals are reported "
5236    "correctly");
5237THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
5238    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
5239    THREAD_CONCURRENT_WATCHPOINT_NUM,
5240    "Verify that concurrent breakpoints, watchpoints and signals are reported "
5241    "correctly and passed back to SIG_IGN handler");
5242THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
5243    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
5244    THREAD_CONCURRENT_WATCHPOINT_NUM,
5245    "Verify that concurrent breakpoints, watchpoints and signals are reported "
5246    "correctly and passed back to a handler function");
5247#endif
5248
5249#endif /*defined(TWAIT_HAVE_STATUS)*/
5250
5251/// ----------------------------------------------------------------------------
5252
5253#include "t_ptrace_register_wait.h"
5254#include "t_ptrace_syscall_wait.h"
5255#include "t_ptrace_step_wait.h"
5256#include "t_ptrace_kill_wait.h"
5257#include "t_ptrace_bytetransfer_wait.h"
5258#include "t_ptrace_clone_wait.h"
5259#include "t_ptrace_fork_wait.h"
5260
5261/// ----------------------------------------------------------------------------
5262
5263#include "t_ptrace_amd64_wait.h"
5264#include "t_ptrace_i386_wait.h"
5265#include "t_ptrace_x86_wait.h"
5266
5267/// ----------------------------------------------------------------------------
5268
5269#else
5270ATF_TC(dummy);
5271ATF_TC_HEAD(dummy, tc)
5272{
5273	atf_tc_set_md_var(tc, "descr", "A dummy test");
5274}
5275
5276ATF_TC_BODY(dummy, tc)
5277{
5278
5279	// Dummy, skipped
5280	// The ATF framework requires at least a single defined test.
5281}
5282#endif
5283
5284ATF_TP_ADD_TCS(tp)
5285{
5286	setvbuf(stdout, NULL, _IONBF, 0);
5287	setvbuf(stderr, NULL, _IONBF, 0);
5288
5289#ifdef ENABLE_TESTS
5290	ATF_TP_ADD_TC(tp, traceme_raise1);
5291	ATF_TP_ADD_TC(tp, traceme_raise2);
5292	ATF_TP_ADD_TC(tp, traceme_raise3);
5293	ATF_TP_ADD_TC(tp, traceme_raise4);
5294	ATF_TP_ADD_TC(tp, traceme_raise5);
5295	ATF_TP_ADD_TC(tp, traceme_raise6);
5296	ATF_TP_ADD_TC(tp, traceme_raise7);
5297	ATF_TP_ADD_TC(tp, traceme_raise8);
5298	ATF_TP_ADD_TC(tp, traceme_raise9);
5299	ATF_TP_ADD_TC(tp, traceme_raise10);
5300
5301	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
5302	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
5303	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
5304	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
5305	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
5306	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
5307	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
5308	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
5309
5310	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
5311	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
5312	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
5313	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
5314	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
5315	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
5316	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
5317	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
5318
5319	ATF_TP_ADD_TC(tp, traceme_crash_trap);
5320	ATF_TP_ADD_TC(tp, traceme_crash_segv);
5321	ATF_TP_ADD_TC(tp, traceme_crash_ill);
5322	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
5323	ATF_TP_ADD_TC(tp, traceme_crash_bus);
5324
5325	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
5326	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
5327	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
5328	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
5329	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
5330
5331	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
5332	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
5333	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
5334	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
5335	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
5336
5337	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
5338	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
5339	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
5340	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
5341	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
5342	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
5343	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
5344	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
5345
5346	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
5347	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
5348	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
5349	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
5350	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
5351	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
5352	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
5353	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
5354
5355	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
5356	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
5357	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
5358	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
5359	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
5360	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
5361	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
5362	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
5363
5364	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
5365	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
5366	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
5367	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
5368	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
5369	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
5370	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
5371	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
5372	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
5373	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
5374
5375	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
5376
5377	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
5378	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
5379	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
5380	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
5381	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
5382	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
5383	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
5384	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
5385	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
5386	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
5387	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
5388	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
5389	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
5390
5391	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
5392	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
5393	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
5394	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
5395	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
5396
5397	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
5398	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
5399	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
5400	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
5401	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
5402
5403	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
5404	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
5405	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
5406	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
5407	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
5408
5409	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
5410	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
5411	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
5412
5413	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
5414	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
5415	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
5416	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
5417	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
5418
5419	ATF_TP_ADD_TC_HAVE_PID(tp,
5420	    unrelated_tracer_sees_signalmasked_crash_trap);
5421	ATF_TP_ADD_TC_HAVE_PID(tp,
5422	    unrelated_tracer_sees_signalmasked_crash_segv);
5423	ATF_TP_ADD_TC_HAVE_PID(tp,
5424	    unrelated_tracer_sees_signalmasked_crash_ill);
5425	ATF_TP_ADD_TC_HAVE_PID(tp,
5426	    unrelated_tracer_sees_signalmasked_crash_fpe);
5427	ATF_TP_ADD_TC_HAVE_PID(tp,
5428	    unrelated_tracer_sees_signalmasked_crash_bus);
5429
5430	ATF_TP_ADD_TC_HAVE_PID(tp,
5431	    unrelated_tracer_sees_signalignored_crash_trap);
5432	ATF_TP_ADD_TC_HAVE_PID(tp,
5433	    unrelated_tracer_sees_signalignored_crash_segv);
5434	ATF_TP_ADD_TC_HAVE_PID(tp,
5435	    unrelated_tracer_sees_signalignored_crash_ill);
5436	ATF_TP_ADD_TC_HAVE_PID(tp,
5437	    unrelated_tracer_sees_signalignored_crash_fpe);
5438	ATF_TP_ADD_TC_HAVE_PID(tp,
5439	    unrelated_tracer_sees_signalignored_crash_bus);
5440
5441	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
5442	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
5443	ATF_TP_ADD_TC_HAVE_PID(tp,
5444		unrelated_tracer_sees_terminaton_before_the_parent);
5445	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
5446
5447	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
5448	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
5449
5450	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
5451	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
5452
5453	ATF_TP_ADD_TC_HAVE_PID(tp,
5454		tracee_sees_its_original_parent_getppid);
5455	ATF_TP_ADD_TC_HAVE_PID(tp,
5456		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
5457	ATF_TP_ADD_TC_HAVE_PID(tp,
5458		tracee_sees_its_original_parent_procfs_status);
5459
5460	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
5461	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
5462	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
5463	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
5464	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
5465	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
5466	ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn);
5467
5468	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
5469	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
5470	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
5471	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
5472
5473	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
5474	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
5475	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
5476	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
5477
5478	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
5479	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
5480	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
5481	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
5482
5483	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
5484	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
5485	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
5486	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
5487
5488	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
5489	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
5490	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
5491	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
5492
5493	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
5494	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
5495	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
5496	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
5497
5498	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
5499	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
5500	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
5501	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
5502
5503	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
5504	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
5505	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
5506	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
5507
5508	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
5509	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
5510	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
5511	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
5512
5513	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
5514	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
5515	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
5516	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
5517
5518	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
5519
5520	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i);
5521	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d);
5522	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i);
5523	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d);
5524
5525	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i);
5526	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d);
5527	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i);
5528	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d);
5529
5530	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv);
5531
5532	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i);
5533	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d);
5534	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i);
5535	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d);
5536
5537	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i);
5538	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d);
5539	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i);
5540	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);
5541
5542	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
5543	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
5544	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
5545	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
5546
5547	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus);
5548	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus);
5549	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus);
5550	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus);
5551
5552	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask);
5553	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask);
5554	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask);
5555	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask);
5556
5557	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name);
5558	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name);
5559	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name);
5560	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name);
5561
5562	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private);
5563	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private);
5564	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private);
5565	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private);
5566
5567	ATF_TP_ADD_TC(tp, traceme_lwpnext0);
5568	ATF_TP_ADD_TC(tp, traceme_lwpnext1);
5569	ATF_TP_ADD_TC(tp, traceme_lwpnext2);
5570	ATF_TP_ADD_TC(tp, traceme_lwpnext3);
5571
5572	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask);
5573	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask);
5574	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask);
5575	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask);
5576
5577	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name);
5578	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name);
5579	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name);
5580	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name);
5581
5582	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private);
5583	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private);
5584	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private);
5585	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private);
5586
5587	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
5588	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
5589	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
5590	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
5591
5592	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
5593	ATF_TP_ADD_TC(tp, siginfo_set_faked);
5594
5595	ATF_TP_ADD_TC(tp, traceme_exec);
5596	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
5597	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
5598
5599	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
5600	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
5601	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
5602	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
5603
5604	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap);
5605	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap);
5606	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap);
5607
5608	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
5609
5610	ATF_TP_ADD_TC(tp, threads_and_exec);
5611
5612	ATF_TP_ADD_TC(tp, suspend_no_deadlock);
5613
5614	ATF_TP_ADD_TC(tp, resume);
5615
5616	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
5617	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
5618	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
5619
5620	ATF_TP_ADD_TC(tp, core_dump_procinfo);
5621
5622#if defined(TWAIT_HAVE_STATUS)
5623	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
5624	ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign);
5625	ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler);
5626#if defined(__i386__) || defined(__x86_64__)
5627	ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints);
5628	ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints);
5629	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp);
5630	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig);
5631	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign);
5632	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler);
5633	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig);
5634	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign);
5635	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler);
5636	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig);
5637	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign);
5638	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler);
5639#endif
5640#endif
5641
5642	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
5643	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
5644	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
5645	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
5646	ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
5647	ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE();
5648	ATF_TP_ADD_TCS_PTRACE_WAIT_FORK();
5649
5650	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
5651	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
5652	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
5653
5654#else
5655	ATF_TP_ADD_TC(tp, dummy);
5656#endif
5657
5658	return atf_no_error();
5659}
5660