t_ptrace_wait.c revision 1.176
1/*	$NetBSD: t_ptrace_wait.c,v 1.176 2020/05/04 21:33:20 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.176 2020/05/04 21:33:20 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 void
3002fork_body(const char *fn, bool trackspawn, bool trackfork, bool trackvfork,
3003    bool trackvforkdone)
3004{
3005	const int exitval = 5;
3006	const int exitval2 = 0; /* This matched exit status from /bin/echo */
3007	const int sigval = SIGSTOP;
3008	pid_t child, child2 = 0, wpid;
3009#if defined(TWAIT_HAVE_STATUS)
3010	int status;
3011#endif
3012	ptrace_state_t state;
3013	const int slen = sizeof(state);
3014	ptrace_event_t event;
3015	const int elen = sizeof(event);
3016
3017	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3018
3019	DPRINTF("Before forking process PID=%d\n", getpid());
3020	SYSCALL_REQUIRE((child = fork()) != -1);
3021	if (child == 0) {
3022		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3023		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3024
3025		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3026		FORKEE_ASSERT(raise(sigval) == 0);
3027
3028		if (strcmp(fn, "spawn") == 0) {
3029			FORKEE_ASSERT_EQ(posix_spawn(&child2,
3030			    arg[0], NULL, NULL, arg, NULL), 0);
3031		} else {
3032			if (strcmp(fn, "fork") == 0) {
3033				FORKEE_ASSERT((child2 = fork()) != -1);
3034			} else if (strcmp(fn, "vfork") == 0) {
3035				FORKEE_ASSERT((child2 = vfork()) != -1);
3036			}
3037
3038			if (child2 == 0)
3039				_exit(exitval2);
3040		}
3041		FORKEE_REQUIRE_SUCCESS
3042		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3043
3044		forkee_status_exited(status, exitval2);
3045
3046		DPRINTF("Before exiting of the child process\n");
3047		_exit(exitval);
3048	}
3049	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3050
3051	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3052	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3053
3054	validate_status_stopped(status, sigval);
3055
3056	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
3057	    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
3058	    trackfork ? "|PTRACE_FORK" : "",
3059	    trackvfork ? "|PTRACE_VFORK" : "",
3060	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
3061	event.pe_set_event = 0;
3062	if (trackspawn)
3063		event.pe_set_event |= PTRACE_POSIX_SPAWN;
3064	if (trackfork)
3065		event.pe_set_event |= PTRACE_FORK;
3066	if (trackvfork)
3067		event.pe_set_event |= PTRACE_VFORK;
3068	if (trackvforkdone)
3069		event.pe_set_event |= PTRACE_VFORK_DONE;
3070	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
3071
3072	DPRINTF("Before resuming the child process where it left off and "
3073	    "without signal to be sent\n");
3074	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3075
3076#if defined(TWAIT_HAVE_PID)
3077	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3078	    (trackfork && strcmp(fn, "fork") == 0) ||
3079	    (trackvfork && strcmp(fn, "vfork") == 0)) {
3080		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3081		    child);
3082		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3083		    child);
3084
3085		validate_status_stopped(status, SIGTRAP);
3086
3087		SYSCALL_REQUIRE(
3088		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3089		if (trackspawn && strcmp(fn, "spawn") == 0) {
3090			ATF_REQUIRE_EQ(
3091			    state.pe_report_event & PTRACE_POSIX_SPAWN,
3092			       PTRACE_POSIX_SPAWN);
3093		}
3094		if (trackfork && strcmp(fn, "fork") == 0) {
3095			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3096			       PTRACE_FORK);
3097		}
3098		if (trackvfork && strcmp(fn, "vfork") == 0) {
3099			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3100			       PTRACE_VFORK);
3101		}
3102
3103		child2 = state.pe_other_pid;
3104		DPRINTF("Reported ptrace event with forkee %d\n", child2);
3105
3106		DPRINTF("Before calling %s() for the forkee %d of the child "
3107		    "%d\n", TWAIT_FNAME, child2, child);
3108		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
3109		    child2);
3110
3111		validate_status_stopped(status, SIGTRAP);
3112
3113		SYSCALL_REQUIRE(
3114		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
3115		if (trackspawn && strcmp(fn, "spawn") == 0) {
3116			ATF_REQUIRE_EQ(
3117			    state.pe_report_event & PTRACE_POSIX_SPAWN,
3118			       PTRACE_POSIX_SPAWN);
3119		}
3120		if (trackfork && strcmp(fn, "fork") == 0) {
3121			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3122			       PTRACE_FORK);
3123		}
3124		if (trackvfork && strcmp(fn, "vfork") == 0) {
3125			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3126			       PTRACE_VFORK);
3127		}
3128
3129		ATF_REQUIRE_EQ(state.pe_other_pid, child);
3130
3131		DPRINTF("Before resuming the forkee process where it left off "
3132		    "and without signal to be sent\n");
3133		SYSCALL_REQUIRE(
3134		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
3135
3136		DPRINTF("Before resuming the child process where it left off "
3137		    "and without signal to be sent\n");
3138		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3139	}
3140#endif
3141
3142	if (trackvforkdone && strcmp(fn, "vfork") == 0) {
3143		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3144		    child);
3145		TWAIT_REQUIRE_SUCCESS(
3146		    wpid = TWAIT_GENERIC(child, &status, 0), child);
3147
3148		validate_status_stopped(status, SIGTRAP);
3149
3150		SYSCALL_REQUIRE(
3151		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3152		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
3153
3154		child2 = state.pe_other_pid;
3155		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3156		    child2);
3157
3158		DPRINTF("Before resuming the child process where it left off "
3159		    "and without signal to be sent\n");
3160		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3161	}
3162
3163#if defined(TWAIT_HAVE_PID)
3164	if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3165	    (trackfork && strcmp(fn, "fork") == 0) ||
3166	    (trackvfork && strcmp(fn, "vfork") == 0)) {
3167		DPRINTF("Before calling %s() for the forkee - expected exited"
3168		    "\n", TWAIT_FNAME);
3169		TWAIT_REQUIRE_SUCCESS(
3170		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3171
3172		validate_status_exited(status, exitval2);
3173
3174		DPRINTF("Before calling %s() for the forkee - expected no "
3175		    "process\n", TWAIT_FNAME);
3176		TWAIT_REQUIRE_FAILURE(ECHILD,
3177		    wpid = TWAIT_GENERIC(child2, &status, 0));
3178	}
3179#endif
3180
3181	DPRINTF("Before calling %s() for the child - expected stopped "
3182	    "SIGCHLD\n", TWAIT_FNAME);
3183	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3184
3185	validate_status_stopped(status, SIGCHLD);
3186
3187	DPRINTF("Before resuming the child process where it left off and "
3188	    "without signal to be sent\n");
3189	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3190
3191	DPRINTF("Before calling %s() for the child - expected exited\n",
3192	    TWAIT_FNAME);
3193	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3194
3195	validate_status_exited(status, exitval);
3196
3197	DPRINTF("Before calling %s() for the child - expected no process\n",
3198	    TWAIT_FNAME);
3199	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3200}
3201
3202#define FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)		\
3203ATF_TC(name);								\
3204ATF_TC_HEAD(name, tc)							\
3205{									\
3206	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
3207	    "called with 0%s%s%s%s in EVENT_MASK",			\
3208	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
3209	    tfork ? "|PTRACE_FORK" : "",				\
3210	    tvfork ? "|PTRACE_VFORK" : "",				\
3211	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
3212}									\
3213									\
3214ATF_TC_BODY(name, tc)							\
3215{									\
3216									\
3217	fork_body(fun, tspawn, tfork, tvfork, tvforkdone);		\
3218}
3219
3220FORK_TEST(fork1, "fork", false, false, false, false)
3221#if defined(TWAIT_HAVE_PID)
3222FORK_TEST(fork2, "fork", false, true, false, false)
3223FORK_TEST(fork3, "fork", false, false, true, false)
3224FORK_TEST(fork4, "fork", false, true, true, false)
3225#endif
3226FORK_TEST(fork5, "fork", false, false, false, true)
3227#if defined(TWAIT_HAVE_PID)
3228FORK_TEST(fork6, "fork", false, true, false, true)
3229FORK_TEST(fork7, "fork", false, false, true, true)
3230FORK_TEST(fork8, "fork", false, true, true, true)
3231#endif
3232FORK_TEST(fork9, "fork", true, false, false, false)
3233#if defined(TWAIT_HAVE_PID)
3234FORK_TEST(fork10, "fork", true, true, false, false)
3235FORK_TEST(fork11, "fork", true, false, true, false)
3236FORK_TEST(fork12, "fork", true, true, true, false)
3237#endif
3238FORK_TEST(fork13, "fork", true, false, false, true)
3239#if defined(TWAIT_HAVE_PID)
3240FORK_TEST(fork14, "fork", true, true, false, true)
3241FORK_TEST(fork15, "fork", true, false, true, true)
3242FORK_TEST(fork16, "fork", true, true, true, true)
3243#endif
3244
3245FORK_TEST(vfork1, "vfork", false, false, false, false)
3246#if defined(TWAIT_HAVE_PID)
3247FORK_TEST(vfork2, "vfork", false, true, false, false)
3248FORK_TEST(vfork3, "vfork", false, false, true, false)
3249FORK_TEST(vfork4, "vfork", false, true, true, false)
3250#endif
3251FORK_TEST(vfork5, "vfork", false, false, false, true)
3252#if defined(TWAIT_HAVE_PID)
3253FORK_TEST(vfork6, "vfork", false, true, false, true)
3254FORK_TEST(vfork7, "vfork", false, false, true, true)
3255FORK_TEST(vfork8, "vfork", false, true, true, true)
3256#endif
3257FORK_TEST(vfork9, "vfork", true, false, false, false)
3258#if defined(TWAIT_HAVE_PID)
3259FORK_TEST(vfork10, "vfork", true, true, false, false)
3260FORK_TEST(vfork11, "vfork", true, false, true, false)
3261FORK_TEST(vfork12, "vfork", true, true, true, false)
3262#endif
3263FORK_TEST(vfork13, "vfork", true, false, false, true)
3264#if defined(TWAIT_HAVE_PID)
3265FORK_TEST(vfork14, "vfork", true, true, false, true)
3266FORK_TEST(vfork15, "vfork", true, false, true, true)
3267FORK_TEST(vfork16, "vfork", true, true, true, true)
3268#endif
3269
3270FORK_TEST(posix_spawn1, "spawn", false, false, false, false)
3271FORK_TEST(posix_spawn2, "spawn", false, true, false, false)
3272FORK_TEST(posix_spawn3, "spawn", false, false, true, false)
3273FORK_TEST(posix_spawn4, "spawn", false, true, true, false)
3274FORK_TEST(posix_spawn5, "spawn", false, false, false, true)
3275FORK_TEST(posix_spawn6, "spawn", false, true, false, true)
3276FORK_TEST(posix_spawn7, "spawn", false, false, true, true)
3277FORK_TEST(posix_spawn8, "spawn", false, true, true, true)
3278#if defined(TWAIT_HAVE_PID)
3279FORK_TEST(posix_spawn9, "spawn", true, false, false, false)
3280FORK_TEST(posix_spawn10, "spawn", true, true, false, false)
3281FORK_TEST(posix_spawn11, "spawn", true, false, true, false)
3282FORK_TEST(posix_spawn12, "spawn", true, true, true, false)
3283FORK_TEST(posix_spawn13, "spawn", true, false, false, true)
3284FORK_TEST(posix_spawn14, "spawn", true, true, false, true)
3285FORK_TEST(posix_spawn15, "spawn", true, false, true, true)
3286FORK_TEST(posix_spawn16, "spawn", true, true, true, true)
3287#endif
3288
3289/// ----------------------------------------------------------------------------
3290
3291#if defined(TWAIT_HAVE_PID)
3292static void
3293unrelated_tracer_fork_body(const char *fn, bool trackspawn, bool trackfork,
3294    bool trackvfork, bool trackvforkdone)
3295{
3296	const int sigval = SIGSTOP;
3297	struct msg_fds parent_tracee, parent_tracer;
3298	const int exitval = 10;
3299	const int exitval2 = 0; /* This matched exit status from /bin/echo */
3300	pid_t tracee, tracer, wpid;
3301	pid_t tracee2 = 0;
3302	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3303#if defined(TWAIT_HAVE_STATUS)
3304	int status;
3305#endif
3306
3307	struct ptrace_siginfo info;
3308	ptrace_state_t state;
3309	const int slen = sizeof(state);
3310	ptrace_event_t event;
3311	const int elen = sizeof(event);
3312
3313	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3314
3315	DPRINTF("Spawn tracee\n");
3316	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3317	tracee = atf_utils_fork();
3318	if (tracee == 0) {
3319		// Wait for parent to let us crash
3320		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3321
3322		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3323		FORKEE_ASSERT(raise(sigval) == 0);
3324
3325		if (strcmp(fn, "spawn") == 0) {
3326			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
3327			    arg[0], NULL, NULL, arg, NULL), 0);
3328		} else {
3329			if (strcmp(fn, "fork") == 0) {
3330				FORKEE_ASSERT((tracee2 = fork()) != -1);
3331			} else if (strcmp(fn, "vfork") == 0) {
3332				FORKEE_ASSERT((tracee2 = vfork()) != -1);
3333			}
3334
3335			if (tracee2 == 0)
3336				_exit(exitval2);
3337		}
3338		FORKEE_REQUIRE_SUCCESS
3339		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
3340
3341		forkee_status_exited(status, exitval2);
3342
3343		DPRINTF("Before exiting of the child process\n");
3344		_exit(exitval);
3345	}
3346
3347	DPRINTF("Spawn debugger\n");
3348	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3349	tracer = atf_utils_fork();
3350	if (tracer == 0) {
3351		/* Fork again and drop parent to reattach to PID 1 */
3352		tracer = atf_utils_fork();
3353		if (tracer != 0)
3354			_exit(exitval);
3355
3356		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3357		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3358
3359		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3360		FORKEE_REQUIRE_SUCCESS(
3361		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3362
3363		forkee_status_stopped(status, SIGSTOP);
3364
3365		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
3366		    "traced process\n");
3367		SYSCALL_REQUIRE(
3368		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3369
3370		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3371		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3372		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
3373		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
3374
3375		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
3376		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
3377
3378		/* Resume tracee with PT_CONTINUE */
3379		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3380
3381		/* Inform parent that tracer has attached to tracee */
3382		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3383
3384		/* Wait for parent to tell use that tracee should have exited */
3385		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3386
3387		/* Wait for tracee and assert that it exited */
3388		FORKEE_REQUIRE_SUCCESS(
3389		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3390
3391		forkee_status_stopped(status, sigval);
3392
3393		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
3394		    "traced process\n");
3395		SYSCALL_REQUIRE(
3396		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3397
3398		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3399		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3400		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
3401		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
3402
3403		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
3404		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
3405
3406		DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
3407		    trackspawn ? "|PTRACE_POSIX_SPAWN" : "",
3408		    trackfork ? "|PTRACE_FORK" : "",
3409		    trackvfork ? "|PTRACE_VFORK" : "",
3410		    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", tracee);
3411		event.pe_set_event = 0;
3412		if (trackspawn)
3413			event.pe_set_event |= PTRACE_POSIX_SPAWN;
3414		if (trackfork)
3415			event.pe_set_event |= PTRACE_FORK;
3416		if (trackvfork)
3417			event.pe_set_event |= PTRACE_VFORK;
3418		if (trackvforkdone)
3419			event.pe_set_event |= PTRACE_VFORK_DONE;
3420		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen)
3421		    != -1);
3422
3423		DPRINTF("Before resuming the child process where it left off "
3424		    "and without signal to be sent\n");
3425		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3426
3427		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3428		    (trackfork && strcmp(fn, "fork") == 0) ||
3429		    (trackvfork && strcmp(fn, "vfork") == 0)) {
3430			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
3431			    tracee);
3432			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0),
3433			    tracee);
3434
3435			validate_status_stopped(status, SIGTRAP);
3436
3437			SYSCALL_REQUIRE(
3438			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
3439			if (trackspawn && strcmp(fn, "spawn") == 0) {
3440				ATF_REQUIRE_EQ(
3441				    state.pe_report_event & PTRACE_POSIX_SPAWN,
3442				       PTRACE_POSIX_SPAWN);
3443			}
3444			if (trackfork && strcmp(fn, "fork") == 0) {
3445				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3446				       PTRACE_FORK);
3447			}
3448			if (trackvfork && strcmp(fn, "vfork") == 0) {
3449				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3450				       PTRACE_VFORK);
3451			}
3452
3453			tracee2 = state.pe_other_pid;
3454			DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
3455
3456			DPRINTF("Before calling %s() for the forkee %d of the tracee "
3457			    "%d\n", TWAIT_FNAME, tracee2, tracee);
3458			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0),
3459			    tracee2);
3460
3461			validate_status_stopped(status, SIGTRAP);
3462
3463			SYSCALL_REQUIRE(
3464			    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
3465			if (trackspawn && strcmp(fn, "spawn") == 0) {
3466				ATF_REQUIRE_EQ(
3467				    state.pe_report_event & PTRACE_POSIX_SPAWN,
3468				       PTRACE_POSIX_SPAWN);
3469			}
3470			if (trackfork && strcmp(fn, "fork") == 0) {
3471				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
3472				       PTRACE_FORK);
3473			}
3474			if (trackvfork && strcmp(fn, "vfork") == 0) {
3475				ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
3476				       PTRACE_VFORK);
3477			}
3478
3479			ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
3480
3481			DPRINTF("Before resuming the forkee process where it left off "
3482			    "and without signal to be sent\n");
3483			SYSCALL_REQUIRE(
3484			    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
3485
3486			DPRINTF("Before resuming the tracee process where it left off "
3487			    "and without signal to be sent\n");
3488			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3489		}
3490
3491		if (trackvforkdone && strcmp(fn, "vfork") == 0) {
3492			DPRINTF("Before calling %s() for the tracee %d\n", TWAIT_FNAME,
3493			    tracee);
3494			TWAIT_REQUIRE_SUCCESS(
3495			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3496
3497			validate_status_stopped(status, SIGTRAP);
3498
3499			SYSCALL_REQUIRE(
3500			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
3501			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
3502
3503			tracee2 = state.pe_other_pid;
3504			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3505			    tracee2);
3506
3507			DPRINTF("Before resuming the tracee process where it left off "
3508			    "and without signal to be sent\n");
3509			SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3510		}
3511
3512
3513		if ((trackspawn && strcmp(fn, "spawn") == 0) ||
3514		    (trackfork && strcmp(fn, "fork") == 0) ||
3515		    (trackvfork && strcmp(fn, "vfork") == 0)) {
3516			DPRINTF("Before calling %s() for the forkee - expected exited"
3517			    "\n", TWAIT_FNAME);
3518			TWAIT_REQUIRE_SUCCESS(
3519			    wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
3520
3521			validate_status_exited(status, exitval2);
3522
3523			DPRINTF("Before calling %s() for the forkee - expected no "
3524			    "process\n", TWAIT_FNAME);
3525			TWAIT_REQUIRE_FAILURE(ECHILD,
3526			    wpid = TWAIT_GENERIC(tracee2, &status, 0));
3527		}
3528
3529		DPRINTF("Before calling %s() for the tracee - expected stopped "
3530		    "SIGCHLD\n", TWAIT_FNAME);
3531		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3532
3533		validate_status_stopped(status, SIGCHLD);
3534
3535		DPRINTF("Before resuming the tracee process where it left off and "
3536		    "without signal to be sent\n");
3537		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3538
3539		DPRINTF("Before calling %s() for the tracee - expected exited\n",
3540		    TWAIT_FNAME);
3541		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3542
3543		validate_status_exited(status, exitval);
3544
3545		/* Inform parent that tracer is exiting normally */
3546		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
3547
3548		DPRINTF("Before exiting of the tracer process\n");
3549		_exit(0 /* collect by initproc */);
3550	}
3551
3552	DPRINTF("Wait for the tracer process (direct child) to exit "
3553	    "calling %s()\n", TWAIT_FNAME);
3554	TWAIT_REQUIRE_SUCCESS(
3555	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
3556
3557	validate_status_exited(status, exitval);
3558
3559	DPRINTF("Wait for the non-exited tracee process with %s()\n",
3560	    TWAIT_FNAME);
3561	TWAIT_REQUIRE_SUCCESS(
3562	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
3563
3564	DPRINTF("Wait for the tracer to attach to the tracee\n");
3565	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
3566
3567	DPRINTF("Resume the tracee and let it crash\n");
3568	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
3569
3570	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
3571	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
3572
3573	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
3574	    TWAIT_FNAME);
3575	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3576
3577	validate_status_exited(status, exitval);
3578
3579	DPRINTF("Await normal exit of tracer\n");
3580	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
3581
3582	msg_close(&parent_tracer);
3583	msg_close(&parent_tracee);
3584}
3585
3586#define UNRELATED_TRACER_FORK_TEST(name,fun,tspawn,tfork,tvfork,tvforkdone)\
3587ATF_TC(name);								\
3588ATF_TC_HEAD(name, tc)							\
3589{									\
3590	atf_tc_set_md_var(tc, "descr", "Verify " fun "() "		\
3591	    "called with 0%s%s%s%s in EVENT_MASK",			\
3592	    tspawn ? "|PTRACE_POSIX_SPAWN" : "",			\
3593	    tfork ? "|PTRACE_FORK" : "",				\
3594	    tvfork ? "|PTRACE_VFORK" : "",				\
3595	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
3596}									\
3597									\
3598ATF_TC_BODY(name, tc)							\
3599{									\
3600									\
3601	unrelated_tracer_fork_body(fun, tspawn, tfork, tvfork,		\
3602	    tvforkdone);						\
3603}
3604
3605UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork1, "fork", false, false, false, false)
3606UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork2, "fork", false, true, false, false)
3607UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork3, "fork", false, false, true, false)
3608UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork4, "fork", false, true, true, false)
3609UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork5, "fork", false, false, false, true)
3610UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork6, "fork", false, true, false, true)
3611UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork7, "fork", false, false, true, true)
3612UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork8, "fork", false, true, true, true)
3613UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork9, "fork", true, false, false, false)
3614UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork10, "fork", true, true, false, false)
3615UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork11, "fork", true, false, true, false)
3616UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork12, "fork", true, true, true, false)
3617UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork13, "fork", true, false, false, true)
3618UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork14, "fork", true, true, false, true)
3619UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork15, "fork", true, false, true, true)
3620UNRELATED_TRACER_FORK_TEST(unrelated_tracer_fork16, "fork", true, true, true, true)
3621
3622UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork1, "vfork", false, false, false, false)
3623UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork2, "vfork", false, true, false, false)
3624UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork3, "vfork", false, false, true, false)
3625UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork4, "vfork", false, true, true, false)
3626UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork5, "vfork", false, false, false, true)
3627UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork6, "vfork", false, true, false, true)
3628UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork7, "vfork", false, false, true, true)
3629UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork8, "vfork", false, true, true, true)
3630UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork9, "vfork", true, false, false, false)
3631UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork10, "vfork", true, true, false, false)
3632UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork11, "vfork", true, false, true, false)
3633UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork12, "vfork", true, true, true, false)
3634UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork13, "vfork", true, false, false, true)
3635UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork14, "vfork", true, true, false, true)
3636UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork15, "vfork", true, false, true, true)
3637UNRELATED_TRACER_FORK_TEST(unrelated_tracer_vfork16, "vfork", true, true, true, true)
3638
3639UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn1, "spawn", false, false, false, false)
3640UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn2, "spawn", false, true, false, false)
3641UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn3, "spawn", false, false, true, false)
3642UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn4, "spawn", false, true, true, false)
3643UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn5, "spawn", false, false, false, true)
3644UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn6, "spawn", false, true, false, true)
3645UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn7, "spawn", false, false, true, true)
3646UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn8, "spawn", false, true, true, true)
3647UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn9, "spawn", true, false, false, false)
3648UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn10, "spawn", true, true, false, false)
3649UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn11, "spawn", true, false, true, false)
3650UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn12, "spawn", true, true, true, false)
3651UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn13, "spawn", true, false, false, true)
3652UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn14, "spawn", true, true, false, true)
3653UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn15, "spawn", true, false, true, true)
3654UNRELATED_TRACER_FORK_TEST(unrelated_tracer_posix_spawn16, "spawn", true, true, true, true)
3655#endif
3656
3657/// ----------------------------------------------------------------------------
3658
3659#if defined(TWAIT_HAVE_PID)
3660static void
3661fork_detach_forker_body(const char *fn, bool kill_process)
3662{
3663	const int exitval = 5;
3664	const int exitval2 = 0; /* Matches exit value from /bin/echo */
3665	const int sigval = SIGSTOP;
3666	pid_t child, child2 = 0, wpid;
3667#if defined(TWAIT_HAVE_STATUS)
3668	int status;
3669#endif
3670	ptrace_state_t state;
3671	const int slen = sizeof(state);
3672	ptrace_event_t event;
3673	const int elen = sizeof(event);
3674
3675	int op;
3676
3677	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3678
3679	DPRINTF("Before forking process PID=%d\n", getpid());
3680	SYSCALL_REQUIRE((child = fork()) != -1);
3681	if (child == 0) {
3682		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
3683		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
3684
3685		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3686		FORKEE_ASSERT(raise(sigval) == 0);
3687
3688		if (strcmp(fn, "spawn") == 0) {
3689			FORKEE_ASSERT_EQ(posix_spawn(&child2,
3690			    arg[0], NULL, NULL, arg, NULL), 0);
3691		} else  {
3692			if (strcmp(fn, "fork") == 0) {
3693				FORKEE_ASSERT((child2 = fork()) != -1);
3694			} else {
3695				FORKEE_ASSERT((child2 = vfork()) != -1);
3696			}
3697
3698			if (child2 == 0)
3699				_exit(exitval2);
3700		}
3701
3702		FORKEE_REQUIRE_SUCCESS
3703		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3704
3705		forkee_status_exited(status, exitval2);
3706
3707		DPRINTF("Before exiting of the child process\n");
3708		_exit(exitval);
3709	}
3710	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
3711
3712	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3713	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3714
3715	validate_status_stopped(status, sigval);
3716
3717	DPRINTF("Set EVENT_MASK for the child %d\n", child);
3718	event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
3719		| PTRACE_VFORK_DONE;
3720	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
3721
3722	DPRINTF("Before resuming the child process where it left off and "
3723	    "without signal to be sent\n");
3724	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3725
3726	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
3727	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3728
3729	validate_status_stopped(status, SIGTRAP);
3730
3731	SYSCALL_REQUIRE(
3732	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3733
3734	if (strcmp(fn, "spawn") == 0)
3735		op = PTRACE_POSIX_SPAWN;
3736	else if (strcmp(fn, "fork") == 0)
3737		op = PTRACE_FORK;
3738	else
3739		op = PTRACE_VFORK;
3740
3741	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
3742
3743	child2 = state.pe_other_pid;
3744	DPRINTF("Reported ptrace event with forkee %d\n", child2);
3745
3746	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
3747	    strcmp(fn, "vfork") == 0)
3748		op = kill_process ? PT_KILL : PT_DETACH;
3749	else
3750		op = PT_CONTINUE;
3751	SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
3752
3753	DPRINTF("Before calling %s() for the forkee %d of the child %d\n",
3754	    TWAIT_FNAME, child2, child);
3755	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3756
3757	validate_status_stopped(status, SIGTRAP);
3758
3759	SYSCALL_REQUIRE(
3760	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
3761	if (strcmp(fn, "spawn") == 0)
3762		op = PTRACE_POSIX_SPAWN;
3763	else if (strcmp(fn, "fork") == 0)
3764		op = PTRACE_FORK;
3765	else
3766		op = PTRACE_VFORK;
3767
3768	ATF_REQUIRE_EQ(state.pe_report_event & op, op);
3769	ATF_REQUIRE_EQ(state.pe_other_pid, child);
3770
3771	DPRINTF("Before resuming the forkee process where it left off "
3772	    "and without signal to be sent\n");
3773 	SYSCALL_REQUIRE(
3774	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
3775
3776	if (strcmp(fn, "vforkdone") == 0) {
3777		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
3778		    child);
3779		TWAIT_REQUIRE_SUCCESS(
3780		    wpid = TWAIT_GENERIC(child, &status, 0), child);
3781
3782		validate_status_stopped(status, SIGTRAP);
3783
3784		SYSCALL_REQUIRE(
3785		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
3786		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
3787
3788		child2 = state.pe_other_pid;
3789		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
3790		    child2);
3791
3792		op = kill_process ? PT_KILL : PT_DETACH;
3793		DPRINTF("Before resuming the child process where it left off "
3794		    "and without signal to be sent\n");
3795		SYSCALL_REQUIRE(ptrace(op, child, (void *)1, 0) != -1);
3796	}
3797
3798	DPRINTF("Before calling %s() for the forkee - expected exited\n",
3799	    TWAIT_FNAME);
3800	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), child2);
3801
3802	validate_status_exited(status, exitval2);
3803
3804	DPRINTF("Before calling %s() for the forkee - expected no process\n",
3805	    TWAIT_FNAME);
3806	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child2, &status, 0));
3807
3808	DPRINTF("Before calling %s() for the forkee - expected exited\n",
3809	    TWAIT_FNAME);
3810	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
3811
3812	if (kill_process) {
3813		validate_status_signaled(status, SIGKILL, 0);
3814	} else {
3815		validate_status_exited(status, exitval);
3816	}
3817
3818	DPRINTF("Before calling %s() for the child - expected no process\n",
3819	    TWAIT_FNAME);
3820	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
3821}
3822
3823#define FORK_DETACH_FORKER(name,event,kprocess)				\
3824ATF_TC(name);								\
3825ATF_TC_HEAD(name, tc)							\
3826{									\
3827	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
3828	    kprocess ? "killed" : "detached");				\
3829}									\
3830									\
3831ATF_TC_BODY(name, tc)							\
3832{									\
3833									\
3834	fork_detach_forker_body(event, kprocess);			\
3835}
3836
3837FORK_DETACH_FORKER(posix_spawn_detach_spawner, "spawn", false)
3838FORK_DETACH_FORKER(fork_detach_forker, "fork", false)
3839FORK_DETACH_FORKER(vfork_detach_vforker, "vfork", false)
3840FORK_DETACH_FORKER(vfork_detach_vforkerdone, "vforkdone", false)
3841
3842FORK_DETACH_FORKER(posix_spawn_kill_spawner, "spawn", true)
3843FORK_DETACH_FORKER(fork_kill_forker, "fork", true)
3844FORK_DETACH_FORKER(vfork_kill_vforker, "vfork", true)
3845FORK_DETACH_FORKER(vfork_kill_vforkerdone, "vforkdone", true)
3846#endif
3847
3848/// ----------------------------------------------------------------------------
3849
3850#if defined(TWAIT_HAVE_PID)
3851static void
3852unrelated_tracer_fork_detach_forker_body(const char *fn, bool kill_process)
3853{
3854	const int sigval = SIGSTOP;
3855	struct msg_fds parent_tracee, parent_tracer;
3856	const int exitval = 10;
3857	const int exitval2 = 0; /* This matched exit status from /bin/echo */
3858	pid_t tracee, tracer, wpid;
3859	pid_t tracee2 = 0;
3860	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
3861#if defined(TWAIT_HAVE_STATUS)
3862	int status;
3863#endif
3864	int op;
3865
3866	struct ptrace_siginfo info;
3867	ptrace_state_t state;
3868	const int slen = sizeof(state);
3869	ptrace_event_t event;
3870	const int elen = sizeof(event);
3871
3872	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
3873
3874	DPRINTF("Spawn tracee\n");
3875	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
3876	tracee = atf_utils_fork();
3877	if (tracee == 0) {
3878		// Wait for parent to let us crash
3879		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
3880
3881		DPRINTF("Before raising %s from child\n", strsignal(sigval));
3882		FORKEE_ASSERT(raise(sigval) == 0);
3883
3884		if (strcmp(fn, "spawn") == 0) {
3885			FORKEE_ASSERT_EQ(posix_spawn(&tracee2,
3886			    arg[0], NULL, NULL, arg, NULL), 0);
3887		} else  {
3888			if (strcmp(fn, "fork") == 0) {
3889				FORKEE_ASSERT((tracee2 = fork()) != -1);
3890			} else {
3891				FORKEE_ASSERT((tracee2 = vfork()) != -1);
3892			}
3893
3894			if (tracee2 == 0)
3895				_exit(exitval2);
3896		}
3897
3898		FORKEE_REQUIRE_SUCCESS
3899		    (wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
3900
3901		forkee_status_exited(status, exitval2);
3902
3903		DPRINTF("Before exiting of the child process\n");
3904		_exit(exitval);
3905	}
3906
3907	DPRINTF("Spawn debugger\n");
3908	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
3909	tracer = atf_utils_fork();
3910	if (tracer == 0) {
3911		/* Fork again and drop parent to reattach to PID 1 */
3912		tracer = atf_utils_fork();
3913		if (tracer != 0)
3914			_exit(exitval);
3915
3916		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
3917		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
3918
3919		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
3920		FORKEE_REQUIRE_SUCCESS(
3921		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3922
3923		forkee_status_stopped(status, SIGSTOP);
3924
3925		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
3926		    "traced process\n");
3927		SYSCALL_REQUIRE(
3928		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3929
3930		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3931		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3932		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
3933		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
3934
3935		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
3936		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
3937
3938		/* Resume tracee with PT_CONTINUE */
3939		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3940
3941		/* Inform parent that tracer has attached to tracee */
3942		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
3943
3944		/* Wait for parent to tell use that tracee should have exited */
3945		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
3946
3947		/* Wait for tracee and assert that it exited */
3948		FORKEE_REQUIRE_SUCCESS(
3949		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3950
3951		forkee_status_stopped(status, sigval);
3952
3953		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for the "
3954		    "traced process\n");
3955		SYSCALL_REQUIRE(
3956		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
3957
3958		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
3959		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
3960		    "si_errno=%#x\n", info.psi_siginfo.si_signo,
3961		    info.psi_siginfo.si_code, info.psi_siginfo.si_errno);
3962
3963		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
3964		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
3965
3966		DPRINTF("Set EVENT_MASK for the child %d\n", tracee);
3967		event.pe_set_event = PTRACE_POSIX_SPAWN | PTRACE_FORK | PTRACE_VFORK
3968			| PTRACE_VFORK_DONE;
3969		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen) != -1);
3970
3971		DPRINTF("Before resuming the child process where it left off and "
3972		    "without signal to be sent\n");
3973		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
3974
3975		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME, tracee);
3976		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
3977
3978		validate_status_stopped(status, SIGTRAP);
3979
3980		SYSCALL_REQUIRE(
3981		    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
3982
3983		if (strcmp(fn, "spawn") == 0)
3984			op = PTRACE_POSIX_SPAWN;
3985		else if (strcmp(fn, "fork") == 0)
3986			op = PTRACE_FORK;
3987		else
3988			op = PTRACE_VFORK;
3989
3990		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
3991
3992		tracee2 = state.pe_other_pid;
3993		DPRINTF("Reported ptrace event with forkee %d\n", tracee2);
3994		if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
3995		    strcmp(fn, "vfork") == 0)
3996			op = kill_process ? PT_KILL : PT_DETACH;
3997		else
3998			op = PT_CONTINUE;
3999		SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
4000
4001		DPRINTF("Before calling %s() for the forkee %d of the tracee %d\n",
4002		    TWAIT_FNAME, tracee2, tracee);
4003		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
4004
4005		validate_status_stopped(status, SIGTRAP);
4006
4007		SYSCALL_REQUIRE(
4008		    ptrace(PT_GET_PROCESS_STATE, tracee2, &state, slen) != -1);
4009		if (strcmp(fn, "spawn") == 0)
4010			op = PTRACE_POSIX_SPAWN;
4011		else if (strcmp(fn, "fork") == 0)
4012			op = PTRACE_FORK;
4013		else
4014			op = PTRACE_VFORK;
4015
4016		ATF_REQUIRE_EQ(state.pe_report_event & op, op);
4017		ATF_REQUIRE_EQ(state.pe_other_pid, tracee);
4018
4019		DPRINTF("Before resuming the forkee process where it left off "
4020		    "and without signal to be sent\n");
4021		SYSCALL_REQUIRE(
4022		    ptrace(PT_CONTINUE, tracee2, (void *)1, 0) != -1);
4023
4024		if (strcmp(fn, "vforkdone") == 0) {
4025			DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
4026			    tracee);
4027			TWAIT_REQUIRE_SUCCESS(
4028			    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4029
4030			validate_status_stopped(status, SIGTRAP);
4031
4032			SYSCALL_REQUIRE(
4033			    ptrace(PT_GET_PROCESS_STATE, tracee, &state, slen) != -1);
4034			ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
4035
4036			tracee2 = state.pe_other_pid;
4037			DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
4038			    tracee2);
4039
4040			op = kill_process ? PT_KILL : PT_DETACH;
4041			DPRINTF("Before resuming the child process where it left off "
4042			    "and without signal to be sent\n");
4043			SYSCALL_REQUIRE(ptrace(op, tracee, (void *)1, 0) != -1);
4044		}
4045
4046		DPRINTF("Before calling %s() for the forkee - expected exited\n",
4047		    TWAIT_FNAME);
4048		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee2, &status, 0), tracee2);
4049
4050		validate_status_exited(status, exitval2);
4051
4052		DPRINTF("Before calling %s() for the forkee - expected no process\n",
4053		    TWAIT_FNAME);
4054		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(tracee2, &status, 0));
4055
4056		if (kill_process) {
4057			DPRINTF("Before calling %s() for the forkee - expected signaled\n",
4058			    TWAIT_FNAME);
4059			TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4060
4061			validate_status_signaled(status, SIGKILL, 0);
4062		}
4063
4064		/* Inform parent that tracer is exiting normally */
4065		CHILD_TO_PARENT("tracer done", parent_tracer, msg);
4066
4067		DPRINTF("Before exiting of the tracer process\n");
4068		_exit(0 /* collect by initproc */);
4069	}
4070
4071	DPRINTF("Wait for the tracer process (direct child) to exit "
4072	    "calling %s()\n", TWAIT_FNAME);
4073	TWAIT_REQUIRE_SUCCESS(
4074	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
4075
4076	validate_status_exited(status, exitval);
4077
4078	DPRINTF("Wait for the non-exited tracee process with %s()\n",
4079	    TWAIT_FNAME);
4080	TWAIT_REQUIRE_SUCCESS(
4081	    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
4082
4083	DPRINTF("Wait for the tracer to attach to the tracee\n");
4084	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
4085
4086	DPRINTF("Resume the tracee and let it crash\n");
4087	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
4088
4089	DPRINTF("Resume the tracer and let it detect crashed tracee\n");
4090	PARENT_TO_CHILD("Message 2", parent_tracer, msg);
4091
4092	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
4093	    TWAIT_FNAME);
4094	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
4095
4096	if (kill_process) {
4097		validate_status_signaled(status, SIGKILL, 0);
4098	} else {
4099		validate_status_exited(status, exitval);
4100	}
4101
4102	DPRINTF("Await normal exit of tracer\n");
4103	PARENT_FROM_CHILD("tracer done", parent_tracer, msg);
4104
4105	msg_close(&parent_tracer);
4106	msg_close(&parent_tracee);
4107}
4108
4109#define UNRELATED_TRACER_FORK_DETACH_FORKER(name,event,kprocess)	\
4110ATF_TC(name);								\
4111ATF_TC_HEAD(name, tc)							\
4112{									\
4113	atf_tc_set_md_var(tc, "descr", "Verify %s " event,		\
4114	    kprocess ? "killed" : "detached");				\
4115}									\
4116									\
4117ATF_TC_BODY(name, tc)							\
4118{									\
4119									\
4120	unrelated_tracer_fork_detach_forker_body(event, kprocess);	\
4121}
4122
4123UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_detach_spawner, "spawn", false)
4124UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_detach_forker, "fork", false)
4125UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforker, "vfork", false)
4126UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_detach_vforkerdone, "vforkdone", false)
4127
4128UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_posix_spawn_kill_spawner, "spawn", true)
4129UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_fork_kill_forker, "fork", true)
4130UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforker, "vfork", true)
4131UNRELATED_TRACER_FORK_DETACH_FORKER(unrelated_tracer_vfork_kill_vforkerdone, "vforkdone", true)
4132#endif
4133
4134/// ----------------------------------------------------------------------------
4135
4136static void
4137traceme_vfork_fork_body(pid_t (*fn)(void))
4138{
4139	const int exitval = 5;
4140	const int exitval2 = 15;
4141	pid_t child, child2 = 0, wpid;
4142#if defined(TWAIT_HAVE_STATUS)
4143	int status;
4144#endif
4145
4146	DPRINTF("Before forking process PID=%d\n", getpid());
4147	SYSCALL_REQUIRE((child = vfork()) != -1);
4148	if (child == 0) {
4149		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4150		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4151
4152		FORKEE_ASSERT((child2 = (fn)()) != -1);
4153
4154		if (child2 == 0)
4155			_exit(exitval2);
4156
4157		FORKEE_REQUIRE_SUCCESS
4158		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
4159
4160		forkee_status_exited(status, exitval2);
4161
4162		DPRINTF("Before exiting of the child process\n");
4163		_exit(exitval);
4164	}
4165	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4166
4167	DPRINTF("Before calling %s() for the child - expected exited\n",
4168	    TWAIT_FNAME);
4169	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4170
4171	validate_status_exited(status, exitval);
4172
4173	DPRINTF("Before calling %s() for the child - expected no process\n",
4174	    TWAIT_FNAME);
4175	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4176}
4177
4178#define TRACEME_VFORK_FORK_TEST(name,fun)				\
4179ATF_TC(name);								\
4180ATF_TC_HEAD(name, tc)							\
4181{									\
4182	atf_tc_set_md_var(tc, "descr", "Verify " #fun "(2) "		\
4183	    "called from vfork(2)ed child");				\
4184}									\
4185									\
4186ATF_TC_BODY(name, tc)							\
4187{									\
4188									\
4189	traceme_vfork_fork_body(fun);					\
4190}
4191
4192TRACEME_VFORK_FORK_TEST(traceme_vfork_fork, fork)
4193TRACEME_VFORK_FORK_TEST(traceme_vfork_vfork, vfork)
4194
4195/// ----------------------------------------------------------------------------
4196
4197enum bytes_transfer_type {
4198	BYTES_TRANSFER_DATA,
4199	BYTES_TRANSFER_DATAIO,
4200	BYTES_TRANSFER_TEXT,
4201	BYTES_TRANSFER_TEXTIO,
4202	BYTES_TRANSFER_AUXV
4203};
4204
4205static int __used
4206bytes_transfer_dummy(int a, int b, int c, int d)
4207{
4208	int e, f, g, h;
4209
4210	a *= 4;
4211	b += 3;
4212	c -= 2;
4213	d /= 1;
4214
4215	e = strtol("10", NULL, 10);
4216	f = strtol("20", NULL, 10);
4217	g = strtol("30", NULL, 10);
4218	h = strtol("40", NULL, 10);
4219
4220	return (a + b * c - d) + (e * f - g / h);
4221}
4222
4223static void
4224bytes_transfer(int operation, size_t size, enum bytes_transfer_type type)
4225{
4226	const int exitval = 5;
4227	const int sigval = SIGSTOP;
4228	pid_t child, wpid;
4229	bool skip = false;
4230
4231	int lookup_me = 0;
4232	uint8_t lookup_me8 = 0;
4233	uint16_t lookup_me16 = 0;
4234	uint32_t lookup_me32 = 0;
4235	uint64_t lookup_me64 = 0;
4236
4237	int magic = 0x13579246;
4238	uint8_t magic8 = 0xab;
4239	uint16_t magic16 = 0x1234;
4240	uint32_t magic32 = 0x98765432;
4241	uint64_t magic64 = 0xabcdef0123456789;
4242
4243	struct ptrace_io_desc io;
4244#if defined(TWAIT_HAVE_STATUS)
4245	int status;
4246#endif
4247	/* 513 is just enough, for the purposes of ATF it's good enough */
4248	AuxInfo ai[513], *aip;
4249
4250	ATF_REQUIRE(size < sizeof(ai));
4251
4252	/* Prepare variables for .TEXT transfers */
4253	switch (type) {
4254	case BYTES_TRANSFER_TEXT:
4255		memcpy(&magic, bytes_transfer_dummy, sizeof(magic));
4256		break;
4257	case BYTES_TRANSFER_TEXTIO:
4258		switch (size) {
4259		case 8:
4260			memcpy(&magic8, bytes_transfer_dummy, sizeof(magic8));
4261			break;
4262		case 16:
4263			memcpy(&magic16, bytes_transfer_dummy, sizeof(magic16));
4264			break;
4265		case 32:
4266			memcpy(&magic32, bytes_transfer_dummy, sizeof(magic32));
4267			break;
4268		case 64:
4269			memcpy(&magic64, bytes_transfer_dummy, sizeof(magic64));
4270			break;
4271		}
4272		break;
4273	default:
4274		break;
4275	}
4276
4277	/* Prepare variables for PIOD and AUXV transfers */
4278	switch (type) {
4279	case BYTES_TRANSFER_TEXTIO:
4280	case BYTES_TRANSFER_DATAIO:
4281		io.piod_op = operation;
4282		switch (size) {
4283		case 8:
4284			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
4285			               (void *)bytes_transfer_dummy :
4286			               &lookup_me8;
4287			io.piod_addr = &lookup_me8;
4288			io.piod_len = sizeof(lookup_me8);
4289			break;
4290		case 16:
4291			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
4292			               (void *)bytes_transfer_dummy :
4293			               &lookup_me16;
4294			io.piod_addr = &lookup_me16;
4295			io.piod_len = sizeof(lookup_me16);
4296			break;
4297		case 32:
4298			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
4299			               (void *)bytes_transfer_dummy :
4300			               &lookup_me32;
4301			io.piod_addr = &lookup_me32;
4302			io.piod_len = sizeof(lookup_me32);
4303			break;
4304		case 64:
4305			io.piod_offs = (type == BYTES_TRANSFER_TEXTIO) ?
4306			               (void *)bytes_transfer_dummy :
4307			               &lookup_me64;
4308			io.piod_addr = &lookup_me64;
4309			io.piod_len = sizeof(lookup_me64);
4310			break;
4311		default:
4312			break;
4313		}
4314		break;
4315	case BYTES_TRANSFER_AUXV:
4316		io.piod_op = operation;
4317		io.piod_offs = 0;
4318		io.piod_addr = ai;
4319		io.piod_len = size;
4320		break;
4321	default:
4322		break;
4323	}
4324
4325	DPRINTF("Before forking process PID=%d\n", getpid());
4326	SYSCALL_REQUIRE((child = fork()) != -1);
4327	if (child == 0) {
4328		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4329		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4330
4331		switch (type) {
4332		case BYTES_TRANSFER_DATA:
4333			switch (operation) {
4334			case PT_READ_D:
4335			case PT_READ_I:
4336				lookup_me = magic;
4337				break;
4338			default:
4339				break;
4340			}
4341			break;
4342		case BYTES_TRANSFER_DATAIO:
4343			switch (operation) {
4344			case PIOD_READ_D:
4345			case PIOD_READ_I:
4346				switch (size) {
4347				case 8:
4348					lookup_me8 = magic8;
4349					break;
4350				case 16:
4351					lookup_me16 = magic16;
4352					break;
4353				case 32:
4354					lookup_me32 = magic32;
4355					break;
4356				case 64:
4357					lookup_me64 = magic64;
4358					break;
4359				default:
4360					break;
4361				}
4362				break;
4363			default:
4364				break;
4365			}
4366		default:
4367			break;
4368		}
4369
4370		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4371		FORKEE_ASSERT(raise(sigval) == 0);
4372
4373		/* Handle PIOD and PT separately as operation values overlap */
4374		switch (type) {
4375		case BYTES_TRANSFER_DATA:
4376			switch (operation) {
4377			case PT_WRITE_D:
4378			case PT_WRITE_I:
4379				FORKEE_ASSERT_EQ(lookup_me, magic);
4380				break;
4381			default:
4382				break;
4383			}
4384			break;
4385		case BYTES_TRANSFER_DATAIO:
4386			switch (operation) {
4387			case PIOD_WRITE_D:
4388			case PIOD_WRITE_I:
4389				switch (size) {
4390				case 8:
4391					FORKEE_ASSERT_EQ(lookup_me8, magic8);
4392					break;
4393				case 16:
4394					FORKEE_ASSERT_EQ(lookup_me16, magic16);
4395					break;
4396				case 32:
4397					FORKEE_ASSERT_EQ(lookup_me32, magic32);
4398					break;
4399				case 64:
4400					FORKEE_ASSERT_EQ(lookup_me64, magic64);
4401					break;
4402				default:
4403					break;
4404				}
4405				break;
4406			default:
4407				break;
4408			}
4409			break;
4410		case BYTES_TRANSFER_TEXT:
4411			FORKEE_ASSERT(memcmp(&magic, bytes_transfer_dummy,
4412			                     sizeof(magic)) == 0);
4413			break;
4414		case BYTES_TRANSFER_TEXTIO:
4415			switch (size) {
4416			case 8:
4417				FORKEE_ASSERT(memcmp(&magic8,
4418				                     bytes_transfer_dummy,
4419				                     sizeof(magic8)) == 0);
4420				break;
4421			case 16:
4422				FORKEE_ASSERT(memcmp(&magic16,
4423				                     bytes_transfer_dummy,
4424				                     sizeof(magic16)) == 0);
4425				break;
4426			case 32:
4427				FORKEE_ASSERT(memcmp(&magic32,
4428				                     bytes_transfer_dummy,
4429				                     sizeof(magic32)) == 0);
4430				break;
4431			case 64:
4432				FORKEE_ASSERT(memcmp(&magic64,
4433				                     bytes_transfer_dummy,
4434				                     sizeof(magic64)) == 0);
4435				break;
4436			}
4437			break;
4438		default:
4439			break;
4440		}
4441
4442		DPRINTF("Before exiting of the child process\n");
4443		_exit(exitval);
4444	}
4445	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4446
4447	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4448	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4449
4450	validate_status_stopped(status, sigval);
4451
4452	/* Check PaX MPROTECT */
4453	if (!can_we_write_to_text(child)) {
4454		switch (type) {
4455		case BYTES_TRANSFER_TEXTIO:
4456			switch (operation) {
4457			case PIOD_WRITE_D:
4458			case PIOD_WRITE_I:
4459				skip = true;
4460				break;
4461			default:
4462				break;
4463			}
4464			break;
4465		case BYTES_TRANSFER_TEXT:
4466			switch (operation) {
4467			case PT_WRITE_D:
4468			case PT_WRITE_I:
4469				skip = true;
4470				break;
4471			default:
4472				break;
4473			}
4474			break;
4475		default:
4476			break;
4477		}
4478	}
4479
4480	/* Bailout cleanly killing the child process */
4481	if (skip) {
4482		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
4483		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4484		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4485		                      child);
4486
4487		validate_status_signaled(status, SIGKILL, 0);
4488
4489		atf_tc_skip("PaX MPROTECT setup prevents writes to .text");
4490	}
4491
4492	DPRINTF("Calling operation to transfer bytes between child=%d and "
4493	       "parent=%d\n", child, getpid());
4494
4495	switch (type) {
4496	case BYTES_TRANSFER_TEXTIO:
4497	case BYTES_TRANSFER_DATAIO:
4498	case BYTES_TRANSFER_AUXV:
4499		switch (operation) {
4500		case PIOD_WRITE_D:
4501		case PIOD_WRITE_I:
4502			switch (size) {
4503			case 8:
4504				lookup_me8 = magic8;
4505				break;
4506			case 16:
4507				lookup_me16 = magic16;
4508				break;
4509			case 32:
4510				lookup_me32 = magic32;
4511				break;
4512			case 64:
4513				lookup_me64 = magic64;
4514				break;
4515			default:
4516				break;
4517			}
4518			break;
4519		default:
4520			break;
4521		}
4522		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1);
4523		switch (operation) {
4524		case PIOD_READ_D:
4525		case PIOD_READ_I:
4526			switch (size) {
4527			case 8:
4528				ATF_REQUIRE_EQ(lookup_me8, magic8);
4529				break;
4530			case 16:
4531				ATF_REQUIRE_EQ(lookup_me16, magic16);
4532				break;
4533			case 32:
4534				ATF_REQUIRE_EQ(lookup_me32, magic32);
4535				break;
4536			case 64:
4537				ATF_REQUIRE_EQ(lookup_me64, magic64);
4538				break;
4539			default:
4540				break;
4541			}
4542			break;
4543		case PIOD_READ_AUXV:
4544			DPRINTF("Asserting that AUXV length (%zu) is > 0\n",
4545			        io.piod_len);
4546			ATF_REQUIRE(io.piod_len > 0);
4547			for (aip = ai; aip->a_type != AT_NULL; aip++)
4548				DPRINTF("a_type=%#llx a_v=%#llx\n",
4549				    (long long int)aip->a_type,
4550				    (long long int)aip->a_v);
4551			break;
4552		default:
4553			break;
4554		}
4555		break;
4556	case BYTES_TRANSFER_TEXT:
4557		switch (operation) {
4558		case PT_READ_D:
4559		case PT_READ_I:
4560			errno = 0;
4561			lookup_me = ptrace(operation, child,
4562			                   bytes_transfer_dummy, 0);
4563			ATF_REQUIRE_EQ(lookup_me, magic);
4564			SYSCALL_REQUIRE_ERRNO(errno, 0);
4565			break;
4566		case PT_WRITE_D:
4567		case PT_WRITE_I:
4568			SYSCALL_REQUIRE(ptrace(operation, child,
4569			                       bytes_transfer_dummy, magic)
4570			                != -1);
4571			break;
4572		default:
4573			break;
4574		}
4575		break;
4576	case BYTES_TRANSFER_DATA:
4577		switch (operation) {
4578		case PT_READ_D:
4579		case PT_READ_I:
4580			errno = 0;
4581			lookup_me = ptrace(operation, child, &lookup_me, 0);
4582			ATF_REQUIRE_EQ(lookup_me, magic);
4583			SYSCALL_REQUIRE_ERRNO(errno, 0);
4584			break;
4585		case PT_WRITE_D:
4586		case PT_WRITE_I:
4587			lookup_me = magic;
4588			SYSCALL_REQUIRE(ptrace(operation, child, &lookup_me,
4589			                       magic) != -1);
4590			break;
4591		default:
4592			break;
4593		}
4594		break;
4595	default:
4596		break;
4597	}
4598
4599	DPRINTF("Before resuming the child process where it left off and "
4600	    "without signal to be sent\n");
4601	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4602
4603	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4604	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4605
4606	validate_status_exited(status, exitval);
4607
4608	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4609	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4610}
4611
4612#define BYTES_TRANSFER(test, operation, size, type)			\
4613ATF_TC(test);								\
4614ATF_TC_HEAD(test, tc)							\
4615{									\
4616	atf_tc_set_md_var(tc, "descr",					\
4617	    "Verify bytes transfer operation" #operation " and size " #size \
4618	    " of type " #type);						\
4619}									\
4620									\
4621ATF_TC_BODY(test, tc)							\
4622{									\
4623									\
4624	bytes_transfer(operation, size, BYTES_TRANSFER_##type);		\
4625}
4626
4627// DATA
4628
4629BYTES_TRANSFER(bytes_transfer_piod_read_d_8, PIOD_READ_D, 8, DATAIO)
4630BYTES_TRANSFER(bytes_transfer_piod_read_d_16, PIOD_READ_D, 16, DATAIO)
4631BYTES_TRANSFER(bytes_transfer_piod_read_d_32, PIOD_READ_D, 32, DATAIO)
4632BYTES_TRANSFER(bytes_transfer_piod_read_d_64, PIOD_READ_D, 64, DATAIO)
4633
4634BYTES_TRANSFER(bytes_transfer_piod_read_i_8, PIOD_READ_I, 8, DATAIO)
4635BYTES_TRANSFER(bytes_transfer_piod_read_i_16, PIOD_READ_I, 16, DATAIO)
4636BYTES_TRANSFER(bytes_transfer_piod_read_i_32, PIOD_READ_I, 32, DATAIO)
4637BYTES_TRANSFER(bytes_transfer_piod_read_i_64, PIOD_READ_I, 64, DATAIO)
4638
4639BYTES_TRANSFER(bytes_transfer_piod_write_d_8, PIOD_WRITE_D, 8, DATAIO)
4640BYTES_TRANSFER(bytes_transfer_piod_write_d_16, PIOD_WRITE_D, 16, DATAIO)
4641BYTES_TRANSFER(bytes_transfer_piod_write_d_32, PIOD_WRITE_D, 32, DATAIO)
4642BYTES_TRANSFER(bytes_transfer_piod_write_d_64, PIOD_WRITE_D, 64, DATAIO)
4643
4644BYTES_TRANSFER(bytes_transfer_piod_write_i_8, PIOD_WRITE_I, 8, DATAIO)
4645BYTES_TRANSFER(bytes_transfer_piod_write_i_16, PIOD_WRITE_I, 16, DATAIO)
4646BYTES_TRANSFER(bytes_transfer_piod_write_i_32, PIOD_WRITE_I, 32, DATAIO)
4647BYTES_TRANSFER(bytes_transfer_piod_write_i_64, PIOD_WRITE_I, 64, DATAIO)
4648
4649BYTES_TRANSFER(bytes_transfer_read_d, PT_READ_D, 32, DATA)
4650BYTES_TRANSFER(bytes_transfer_read_i, PT_READ_I, 32, DATA)
4651BYTES_TRANSFER(bytes_transfer_write_d, PT_WRITE_D, 32, DATA)
4652BYTES_TRANSFER(bytes_transfer_write_i, PT_WRITE_I, 32, DATA)
4653
4654// TEXT
4655
4656BYTES_TRANSFER(bytes_transfer_piod_read_d_8_text, PIOD_READ_D, 8, TEXTIO)
4657BYTES_TRANSFER(bytes_transfer_piod_read_d_16_text, PIOD_READ_D, 16, TEXTIO)
4658BYTES_TRANSFER(bytes_transfer_piod_read_d_32_text, PIOD_READ_D, 32, TEXTIO)
4659BYTES_TRANSFER(bytes_transfer_piod_read_d_64_text, PIOD_READ_D, 64, TEXTIO)
4660
4661BYTES_TRANSFER(bytes_transfer_piod_read_i_8_text, PIOD_READ_I, 8, TEXTIO)
4662BYTES_TRANSFER(bytes_transfer_piod_read_i_16_text, PIOD_READ_I, 16, TEXTIO)
4663BYTES_TRANSFER(bytes_transfer_piod_read_i_32_text, PIOD_READ_I, 32, TEXTIO)
4664BYTES_TRANSFER(bytes_transfer_piod_read_i_64_text, PIOD_READ_I, 64, TEXTIO)
4665
4666BYTES_TRANSFER(bytes_transfer_piod_write_d_8_text, PIOD_WRITE_D, 8, TEXTIO)
4667BYTES_TRANSFER(bytes_transfer_piod_write_d_16_text, PIOD_WRITE_D, 16, TEXTIO)
4668BYTES_TRANSFER(bytes_transfer_piod_write_d_32_text, PIOD_WRITE_D, 32, TEXTIO)
4669BYTES_TRANSFER(bytes_transfer_piod_write_d_64_text, PIOD_WRITE_D, 64, TEXTIO)
4670
4671BYTES_TRANSFER(bytes_transfer_piod_write_i_8_text, PIOD_WRITE_I, 8, TEXTIO)
4672BYTES_TRANSFER(bytes_transfer_piod_write_i_16_text, PIOD_WRITE_I, 16, TEXTIO)
4673BYTES_TRANSFER(bytes_transfer_piod_write_i_32_text, PIOD_WRITE_I, 32, TEXTIO)
4674BYTES_TRANSFER(bytes_transfer_piod_write_i_64_text, PIOD_WRITE_I, 64, TEXTIO)
4675
4676BYTES_TRANSFER(bytes_transfer_read_d_text, PT_READ_D, 32, TEXT)
4677BYTES_TRANSFER(bytes_transfer_read_i_text, PT_READ_I, 32, TEXT)
4678BYTES_TRANSFER(bytes_transfer_write_d_text, PT_WRITE_D, 32, TEXT)
4679BYTES_TRANSFER(bytes_transfer_write_i_text, PT_WRITE_I, 32, TEXT)
4680
4681// AUXV
4682
4683BYTES_TRANSFER(bytes_transfer_piod_read_auxv, PIOD_READ_AUXV, 4096, AUXV)
4684
4685/// ----------------------------------------------------------------------------
4686
4687static void
4688bytes_transfer_alignment(const char *operation)
4689{
4690	const int exitval = 5;
4691	const int sigval = SIGSTOP;
4692	pid_t child, wpid;
4693#if defined(TWAIT_HAVE_STATUS)
4694	int status;
4695#endif
4696	char *buffer;
4697	int vector;
4698	size_t len;
4699	size_t i;
4700	int op;
4701
4702	struct ptrace_io_desc io;
4703	struct ptrace_siginfo info;
4704
4705	memset(&io, 0, sizeof(io));
4706	memset(&info, 0, sizeof(info));
4707
4708	/* Testing misaligned byte transfer crossing page boundaries */
4709	len = sysconf(_SC_PAGESIZE) * 2;
4710	buffer = malloc(len);
4711	ATF_REQUIRE(buffer != NULL);
4712
4713	/* Initialize the buffer with random data */
4714	for (i = 0; i < len; i++)
4715		buffer[i] = i & 0xff;
4716
4717	DPRINTF("Before forking process PID=%d\n", getpid());
4718	SYSCALL_REQUIRE((child = fork()) != -1);
4719	if (child == 0) {
4720		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4721		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4722
4723		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4724		FORKEE_ASSERT(raise(sigval) == 0);
4725
4726		DPRINTF("Before exiting of the child process\n");
4727		_exit(exitval);
4728	}
4729	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4730
4731	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4732	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4733
4734	validate_status_stopped(status, sigval);
4735
4736	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4737	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
4738		!= -1);
4739
4740	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4741	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4742		"si_errno=%#x\n",
4743		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4744		info.psi_siginfo.si_errno);
4745
4746	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4747	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4748
4749	if (strcmp(operation, "PT_READ_I") == 0 ||
4750	    strcmp(operation, "PT_READ_D") == 0) {
4751		if (strcmp(operation, "PT_READ_I"))
4752			op = PT_READ_I;
4753		else
4754			op = PT_READ_D;
4755
4756		for (i = 0; i <= (len - sizeof(int)); i++) {
4757			errno = 0;
4758			vector = ptrace(op, child, buffer + i, 0);
4759			ATF_REQUIRE_EQ(errno, 0);
4760			ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
4761		}
4762	} else if (strcmp(operation, "PT_WRITE_I") == 0 ||
4763	           strcmp(operation, "PT_WRITE_D") == 0) {
4764		if (strcmp(operation, "PT_WRITE_I"))
4765			op = PT_WRITE_I;
4766		else
4767			op = PT_WRITE_D;
4768
4769		for (i = 0; i <= (len - sizeof(int)); i++) {
4770			memcpy(&vector, buffer + i, sizeof(int));
4771			SYSCALL_REQUIRE(ptrace(op, child, buffer + 1, vector)
4772			    != -1);
4773		}
4774	} else if (strcmp(operation, "PIOD_READ_I") == 0 ||
4775	           strcmp(operation, "PIOD_READ_D") == 0) {
4776		if (strcmp(operation, "PIOD_READ_I"))
4777			op = PIOD_READ_I;
4778		else
4779			op = PIOD_READ_D;
4780
4781		io.piod_op = op;
4782		io.piod_addr = &vector;
4783		io.piod_len = sizeof(int);
4784
4785		for (i = 0; i <= (len - sizeof(int)); i++) {
4786			io.piod_offs = buffer + i;
4787
4788			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4789			                != -1);
4790			ATF_REQUIRE(!memcmp(&vector, buffer + i, sizeof(int)));
4791		}
4792	} else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
4793	           strcmp(operation, "PIOD_WRITE_D") == 0) {
4794		if (strcmp(operation, "PIOD_WRITE_I"))
4795			op = PIOD_WRITE_I;
4796		else
4797			op = PIOD_WRITE_D;
4798
4799		io.piod_op = op;
4800		io.piod_addr = &vector;
4801		io.piod_len = sizeof(int);
4802
4803		for (i = 0; i <= (len - sizeof(int)); i++) {
4804			io.piod_offs = buffer + i;
4805
4806			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4807			                != -1);
4808		}
4809	} else if (strcmp(operation, "PIOD_READ_AUXV") == 0) {
4810		io.piod_op = PIOD_READ_AUXV;
4811		io.piod_addr = &vector;
4812		io.piod_len = sizeof(int);
4813
4814		errno = 0;
4815		i = 0;
4816		/* Read the whole AUXV vector, it has no clear length */
4817		while (io.piod_len > 0) {
4818			io.piod_offs = (void *)(intptr_t)i;
4819			SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io))
4820			                != -1 || (io.piod_len == 0 && i > 0));
4821			++i;
4822		}
4823	}
4824
4825	DPRINTF("Before resuming the child process where it left off "
4826	    "and without signal to be sent\n");
4827	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4828
4829	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4830	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4831	    child);
4832
4833	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4834	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4835}
4836
4837#define BYTES_TRANSFER_ALIGNMENT(test, operation)			\
4838ATF_TC(test);								\
4839ATF_TC_HEAD(test, tc)							\
4840{									\
4841	atf_tc_set_md_var(tc, "descr",					\
4842	    "Verify bytes transfer for potentially misaligned "		\
4843	    "operation " operation);					\
4844}									\
4845									\
4846ATF_TC_BODY(test, tc)							\
4847{									\
4848									\
4849	bytes_transfer_alignment(operation);				\
4850}
4851
4852BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_i, "PT_READ_I")
4853BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_read_d, "PT_READ_D")
4854BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_i, "PT_WRITE_I")
4855BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_pt_write_d, "PT_WRITE_D")
4856
4857BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_i, "PIOD_READ_I")
4858BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_d, "PIOD_READ_D")
4859BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_i, "PIOD_WRITE_I")
4860BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_write_d, "PIOD_WRITE_D")
4861
4862BYTES_TRANSFER_ALIGNMENT(bytes_transfer_alignment_piod_read_auxv, "PIOD_READ_AUXV")
4863
4864/// ----------------------------------------------------------------------------
4865
4866static void
4867bytes_transfer_eof(const char *operation)
4868{
4869	const int exitval = 5;
4870	const int sigval = SIGSTOP;
4871	pid_t child, wpid;
4872#if defined(TWAIT_HAVE_STATUS)
4873	int status;
4874#endif
4875	FILE *fp;
4876	char *p;
4877	int vector;
4878	int op;
4879
4880	struct ptrace_io_desc io;
4881	struct ptrace_siginfo info;
4882
4883	memset(&io, 0, sizeof(io));
4884	memset(&info, 0, sizeof(info));
4885
4886	vector = 0;
4887
4888	fp = tmpfile();
4889	ATF_REQUIRE(fp != NULL);
4890
4891	p = mmap(0, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fileno(fp), 0);
4892	ATF_REQUIRE(p != MAP_FAILED);
4893
4894	DPRINTF("Before forking process PID=%d\n", getpid());
4895	SYSCALL_REQUIRE((child = fork()) != -1);
4896	if (child == 0) {
4897		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
4898		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
4899
4900		DPRINTF("Before raising %s from child\n", strsignal(sigval));
4901		FORKEE_ASSERT(raise(sigval) == 0);
4902
4903		DPRINTF("Before exiting of the child process\n");
4904		_exit(exitval);
4905	}
4906	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
4907
4908	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4909	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
4910
4911	validate_status_stopped(status, sigval);
4912
4913	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
4914	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info))
4915		!= -1);
4916
4917	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
4918	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
4919		"si_errno=%#x\n",
4920		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
4921		info.psi_siginfo.si_errno);
4922
4923	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
4924	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
4925
4926	if (strcmp(operation, "PT_READ_I") == 0 ||
4927	    strcmp(operation, "PT_READ_D") == 0) {
4928		if (strcmp(operation, "PT_READ_I"))
4929			op = PT_READ_I;
4930		else
4931			op = PT_READ_D;
4932
4933		errno = 0;
4934		SYSCALL_REQUIRE(ptrace(op, child, p, 0) == -1);
4935		ATF_REQUIRE_EQ(errno, EINVAL);
4936	} else if (strcmp(operation, "PT_WRITE_I") == 0 ||
4937	           strcmp(operation, "PT_WRITE_D") == 0) {
4938		if (strcmp(operation, "PT_WRITE_I"))
4939			op = PT_WRITE_I;
4940		else
4941			op = PT_WRITE_D;
4942
4943		errno = 0;
4944		SYSCALL_REQUIRE(ptrace(op, child, p, vector) == -1);
4945		ATF_REQUIRE_EQ(errno, EINVAL);
4946	} else if (strcmp(operation, "PIOD_READ_I") == 0 ||
4947	           strcmp(operation, "PIOD_READ_D") == 0) {
4948		if (strcmp(operation, "PIOD_READ_I"))
4949			op = PIOD_READ_I;
4950		else
4951			op = PIOD_READ_D;
4952
4953		io.piod_op = op;
4954		io.piod_addr = &vector;
4955		io.piod_len = sizeof(int);
4956		io.piod_offs = p;
4957
4958		errno = 0;
4959		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
4960		ATF_REQUIRE_EQ(errno, EINVAL);
4961	} else if (strcmp(operation, "PIOD_WRITE_I") == 0 ||
4962	           strcmp(operation, "PIOD_WRITE_D") == 0) {
4963		if (strcmp(operation, "PIOD_WRITE_I"))
4964			op = PIOD_WRITE_I;
4965		else
4966			op = PIOD_WRITE_D;
4967
4968		io.piod_op = op;
4969		io.piod_addr = &vector;
4970		io.piod_len = sizeof(int);
4971		io.piod_offs = p;
4972
4973		errno = 0;
4974		SYSCALL_REQUIRE(ptrace(PT_IO, child, &io, sizeof(io)) == -1);
4975		ATF_REQUIRE_EQ(errno, EINVAL);
4976	}
4977
4978	DPRINTF("Before resuming the child process where it left off "
4979	    "and without signal to be sent\n");
4980	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
4981
4982	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4983	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
4984	    child);
4985
4986	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
4987	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
4988}
4989
4990#define BYTES_TRANSFER_EOF(test, operation)				\
4991ATF_TC(test);								\
4992ATF_TC_HEAD(test, tc)							\
4993{									\
4994	atf_tc_set_md_var(tc, "descr",					\
4995	    "Verify bytes EOF byte transfer for the " operation		\
4996	    " operation");						\
4997}									\
4998									\
4999ATF_TC_BODY(test, tc)							\
5000{									\
5001									\
5002	bytes_transfer_eof(operation);					\
5003}
5004
5005BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_i, "PT_READ_I")
5006BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_read_d, "PT_READ_D")
5007BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_i, "PT_WRITE_I")
5008BYTES_TRANSFER_EOF(bytes_transfer_eof_pt_write_d, "PT_WRITE_D")
5009
5010BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_i, "PIOD_READ_I")
5011BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_read_d, "PIOD_READ_D")
5012BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_i, "PIOD_WRITE_I")
5013BYTES_TRANSFER_EOF(bytes_transfer_eof_piod_write_d, "PIOD_WRITE_D")
5014
5015/// ----------------------------------------------------------------------------
5016
5017static void
5018ptrace_kill(const char *type)
5019{
5020	const int sigval = SIGSTOP;
5021	pid_t child, wpid;
5022#if defined(TWAIT_HAVE_STATUS)
5023	int status;
5024#endif
5025
5026	DPRINTF("Before forking process PID=%d\n", getpid());
5027	SYSCALL_REQUIRE((child = fork()) != -1);
5028	if (child == 0) {
5029		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5030		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5031
5032		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5033		FORKEE_ASSERT(raise(sigval) == 0);
5034
5035		/* NOTREACHED */
5036		FORKEE_ASSERTX(0 &&
5037		    "Child should be terminated by a signal from its parent");
5038	}
5039	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5040
5041	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5042	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5043
5044	validate_status_stopped(status, sigval);
5045
5046	DPRINTF("Before killing the child process with %s\n", type);
5047	if (strcmp(type, "ptrace(PT_KILL)") == 0) {
5048		SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1);
5049	} else if (strcmp(type, "kill(SIGKILL)") == 0) {
5050		kill(child, SIGKILL);
5051	} else if (strcmp(type, "killpg(SIGKILL)") == 0) {
5052		setpgid(child, 0);
5053		killpg(getpgid(child), SIGKILL);
5054	}
5055
5056	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5057	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5058
5059	validate_status_signaled(status, SIGKILL, 0);
5060
5061	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5062	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5063}
5064
5065#define PTRACE_KILL(test, type)						\
5066ATF_TC(test);								\
5067ATF_TC_HEAD(test, tc)							\
5068{									\
5069        atf_tc_set_md_var(tc, "descr",					\
5070            "Verify killing the child with " type);			\
5071}									\
5072									\
5073ATF_TC_BODY(test, tc)							\
5074{									\
5075									\
5076        ptrace_kill(type);						\
5077}
5078
5079// PT_CONTINUE with SIGKILL is covered by traceme_sendsignal_simple1
5080PTRACE_KILL(kill1, "ptrace(PT_KILL)")
5081PTRACE_KILL(kill2, "kill(SIGKILL)")
5082PTRACE_KILL(kill3, "killpg(SIGKILL)")
5083
5084/// ----------------------------------------------------------------------------
5085
5086static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
5087
5088static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
5089static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER;
5090static volatile size_t lwpinfo_thread_done;
5091
5092static void *
5093lwpinfo_thread(void *arg)
5094{
5095	sigset_t s;
5096	volatile void **tcb;
5097
5098	tcb = (volatile void **)arg;
5099
5100	*tcb = _lwp_getprivate();
5101	DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self());
5102
5103	pthread_setname_np(pthread_self(), "thread %d",
5104	    (void *)(intptr_t)_lwp_self());
5105
5106	sigemptyset(&s);
5107	pthread_mutex_lock(&lwpinfo_thread_mtx);
5108	sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
5109	lwpinfo_thread_done++;
5110	pthread_sigmask(SIG_BLOCK, &s, NULL);
5111	pthread_cond_signal(&lwpinfo_thread_cnd);
5112	pthread_mutex_unlock(&lwpinfo_thread_mtx);
5113
5114	return infinite_thread(NULL);
5115}
5116
5117static void
5118traceme_lwpinfo(const size_t threads, const char *iter)
5119{
5120	const int sigval = SIGSTOP;
5121	const int sigval2 = SIGINT;
5122	pid_t child, wpid;
5123#if defined(TWAIT_HAVE_STATUS)
5124	int status;
5125#endif
5126	struct ptrace_lwpinfo lwp = {0, 0};
5127	struct ptrace_lwpstatus lwpstatus = {0};
5128	struct ptrace_siginfo info;
5129	void *private;
5130	char *name;
5131	char namebuf[PL_LNAMELEN];
5132	volatile void *tcb[4];
5133	bool found;
5134	sigset_t s;
5135
5136	/* Maximum number of supported threads in this test */
5137	pthread_t t[__arraycount(tcb) - 1];
5138	size_t n, m;
5139	int rv;
5140	size_t bytes_read;
5141
5142	struct ptrace_io_desc io;
5143	sigset_t sigmask;
5144
5145	ATF_REQUIRE(__arraycount(t) >= threads);
5146	memset(tcb, 0, sizeof(tcb));
5147
5148	DPRINTF("Before forking process PID=%d\n", getpid());
5149	SYSCALL_REQUIRE((child = fork()) != -1);
5150	if (child == 0) {
5151		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5152		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5153
5154		tcb[0] = _lwp_getprivate();
5155		DPRINTF("Storing tcb[0] = %p\n", tcb[0]);
5156
5157		pthread_setname_np(pthread_self(), "thread %d",
5158		    (void *)(intptr_t)_lwp_self());
5159
5160		sigemptyset(&s);
5161		sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
5162		pthread_sigmask(SIG_BLOCK, &s, NULL);
5163
5164		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5165		FORKEE_ASSERT(raise(sigval) == 0);
5166
5167		for (n = 0; n < threads; n++) {
5168			rv = pthread_create(&t[n], NULL, lwpinfo_thread,
5169			    &tcb[n + 1]);
5170			FORKEE_ASSERT(rv == 0);
5171		}
5172
5173		pthread_mutex_lock(&lwpinfo_thread_mtx);
5174		while (lwpinfo_thread_done < threads) {
5175			pthread_cond_wait(&lwpinfo_thread_cnd,
5176			    &lwpinfo_thread_mtx);
5177		}
5178		pthread_mutex_unlock(&lwpinfo_thread_mtx);
5179
5180		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
5181		FORKEE_ASSERT(raise(sigval2) == 0);
5182
5183		/* NOTREACHED */
5184		FORKEE_ASSERTX(0 && "Not reached");
5185	}
5186	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5187
5188	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5189	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5190
5191	validate_status_stopped(status, sigval);
5192
5193	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
5194	SYSCALL_REQUIRE(
5195	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5196
5197	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5198	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5199	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5200	    info.psi_siginfo.si_errno);
5201
5202	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5203	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5204
5205	if (strstr(iter, "LWPINFO") != NULL) {
5206		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5207		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5208		    != -1);
5209
5210		DPRINTF("Assert that there exists a single thread only\n");
5211		ATF_REQUIRE(lwp.pl_lwpid > 0);
5212
5213		DPRINTF("Assert that lwp thread %d received event "
5214		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
5215		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
5216
5217		if (strstr(iter, "LWPSTATUS") != NULL) {
5218			DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS "
5219			    "for child\n");
5220			lwpstatus.pl_lwpid = lwp.pl_lwpid;
5221			SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus,
5222			    sizeof(lwpstatus)) != -1);
5223		}
5224
5225		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5226		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5227		    != -1);
5228
5229		DPRINTF("Assert that there exists a single thread only\n");
5230		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
5231	} else {
5232		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5233		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5234		    sizeof(lwpstatus)) != -1);
5235
5236		DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid);
5237		ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
5238
5239		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5240		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5241		    sizeof(lwpstatus)) != -1);
5242
5243		DPRINTF("Assert that there exists a single thread only\n");
5244		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
5245	}
5246
5247	DPRINTF("Before resuming the child process where it left off and "
5248	    "without signal to be sent\n");
5249	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5250
5251	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5252	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5253
5254	validate_status_stopped(status, sigval2);
5255
5256	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
5257	SYSCALL_REQUIRE(
5258	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5259
5260	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5261	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5262	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5263	    info.psi_siginfo.si_errno);
5264
5265	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
5266	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5267
5268	memset(&lwp, 0, sizeof(lwp));
5269	memset(&lwpstatus, 0, sizeof(lwpstatus));
5270
5271	memset(&io, 0, sizeof(io));
5272
5273	bytes_read = 0;
5274	io.piod_op = PIOD_READ_D;
5275	io.piod_len = sizeof(tcb);
5276
5277	do {
5278		io.piod_addr = (char *)&tcb + bytes_read;
5279		io.piod_offs = io.piod_addr;
5280
5281		rv = ptrace(PT_IO, child, &io, sizeof(io));
5282		ATF_REQUIRE(rv != -1 && io.piod_len != 0);
5283
5284		bytes_read += io.piod_len;
5285		io.piod_len = sizeof(tcb) - bytes_read;
5286	} while (bytes_read < sizeof(tcb));
5287
5288	for (n = 0; n <= threads; n++) {
5289		if (strstr(iter, "LWPINFO") != NULL) {
5290			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5291			    "child\n");
5292			SYSCALL_REQUIRE(
5293			    ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
5294			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5295
5296			DPRINTF("Assert that the thread exists\n");
5297			ATF_REQUIRE(lwp.pl_lwpid > 0);
5298
5299			DPRINTF("Assert that lwp thread %d received expected "
5300			    "event\n", lwp.pl_lwpid);
5301			FORKEE_ASSERT_EQ(lwp.pl_event,
5302			    info.psi_lwpid == lwp.pl_lwpid ?
5303			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
5304
5305			if (strstr(iter, "LWPSTATUS") != NULL) {
5306				DPRINTF("Before calling ptrace(2) with "
5307				    "PT_LWPSTATUS for child\n");
5308				lwpstatus.pl_lwpid = lwp.pl_lwpid;
5309				SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child,
5310				    &lwpstatus, sizeof(lwpstatus)) != -1);
5311
5312				goto check_lwpstatus;
5313			}
5314		} else {
5315			DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for "
5316			    "child\n");
5317			SYSCALL_REQUIRE(
5318			    ptrace(PT_LWPNEXT, child, &lwpstatus,
5319			    sizeof(lwpstatus)) != -1);
5320			DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid);
5321
5322			DPRINTF("Assert that the thread exists\n");
5323			ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
5324
5325		check_lwpstatus:
5326
5327			if (strstr(iter, "pl_sigmask") != NULL) {
5328				sigmask = lwpstatus.pl_sigmask;
5329
5330				DPRINTF("Retrieved sigmask: "
5331				    "%02x%02x%02x%02x\n",
5332				    sigmask.__bits[0], sigmask.__bits[1],
5333				    sigmask.__bits[2], sigmask.__bits[3]);
5334
5335				found = false;
5336				for (m = 0;
5337				     m < __arraycount(lwpinfo_thread_sigmask);
5338				     m++) {
5339					if (sigismember(&sigmask,
5340					    lwpinfo_thread_sigmask[m])) {
5341						found = true;
5342						lwpinfo_thread_sigmask[m] = 0;
5343						break;
5344					}
5345				}
5346				ATF_REQUIRE(found == true);
5347			} else if (strstr(iter, "pl_name") != NULL) {
5348				name = lwpstatus.pl_name;
5349
5350				DPRINTF("Retrieved thread name: "
5351				    "%s\n", name);
5352
5353				snprintf(namebuf, sizeof namebuf, "thread %d",
5354				    lwpstatus.pl_lwpid);
5355
5356				ATF_REQUIRE(strcmp(name, namebuf) == 0);
5357			} else if (strstr(iter, "pl_private") != NULL) {
5358				private = lwpstatus.pl_private;
5359
5360				DPRINTF("Retrieved thread private pointer: "
5361				    "%p\n", private);
5362
5363				found = false;
5364				for (m = 0; m < __arraycount(tcb); m++) {
5365					DPRINTF("Comparing %p and %p\n",
5366					    private, tcb[m]);
5367					if (private == tcb[m]) {
5368						found = true;
5369						break;
5370					}
5371				}
5372				ATF_REQUIRE(found == true);
5373			}
5374		}
5375	}
5376
5377	if (strstr(iter, "LWPINFO") != NULL) {
5378		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5379		    "child\n");
5380		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5381		    != -1);
5382		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5383
5384		DPRINTF("Assert that there are no more threads\n");
5385		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
5386	} else {
5387		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5388		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5389		    sizeof(lwpstatus)) != -1);
5390
5391		DPRINTF("Assert that there exists a single thread only\n");
5392		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
5393	}
5394
5395	DPRINTF("Before resuming the child process where it left off and "
5396	    "without signal to be sent\n");
5397	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
5398
5399	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5400	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5401
5402	validate_status_signaled(status, SIGKILL, 0);
5403
5404	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5405	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5406}
5407
5408#define TRACEME_LWPINFO(test, threads, iter)				\
5409ATF_TC(test);								\
5410ATF_TC_HEAD(test, tc)							\
5411{									\
5412	atf_tc_set_md_var(tc, "descr",					\
5413	    "Verify " iter " with the child with " #threads		\
5414	    " spawned extra threads");					\
5415}									\
5416									\
5417ATF_TC_BODY(test, tc)							\
5418{									\
5419									\
5420	traceme_lwpinfo(threads, iter);					\
5421}
5422
5423TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO")
5424TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO")
5425TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO")
5426TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO")
5427
5428TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS")
5429TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS")
5430TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS")
5431TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS")
5432
5433TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0,
5434    "LWPINFO+LWPSTATUS+pl_sigmask")
5435TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1,
5436    "LWPINFO+LWPSTATUS+pl_sigmask")
5437TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2,
5438    "LWPINFO+LWPSTATUS+pl_sigmask")
5439TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3,
5440    "LWPINFO+LWPSTATUS+pl_sigmask")
5441
5442TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0,
5443    "LWPINFO+LWPSTATUS+pl_name")
5444TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1,
5445    "LWPINFO+LWPSTATUS+pl_name")
5446TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2,
5447    "LWPINFO+LWPSTATUS+pl_name")
5448TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3,
5449    "LWPINFO+LWPSTATUS+pl_name")
5450
5451TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0,
5452    "LWPINFO+LWPSTATUS+pl_private")
5453TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1,
5454    "LWPINFO+LWPSTATUS+pl_private")
5455TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2,
5456    "LWPINFO+LWPSTATUS+pl_private")
5457TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3,
5458    "LWPINFO+LWPSTATUS+pl_private")
5459
5460TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT")
5461TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT")
5462TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT")
5463TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT")
5464
5465TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask")
5466TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask")
5467TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask")
5468TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask")
5469
5470TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name")
5471TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name")
5472TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name")
5473TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name")
5474
5475TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private")
5476TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private")
5477TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private")
5478TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private")
5479
5480/// ----------------------------------------------------------------------------
5481
5482#if defined(TWAIT_HAVE_PID)
5483static void
5484attach_lwpinfo(const int threads)
5485{
5486	const int sigval = SIGINT;
5487	struct msg_fds parent_tracee, parent_tracer;
5488	const int exitval_tracer = 10;
5489	pid_t tracee, tracer, wpid;
5490	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5491#if defined(TWAIT_HAVE_STATUS)
5492	int status;
5493#endif
5494	struct ptrace_lwpinfo lwp = {0, 0};
5495	struct ptrace_siginfo info;
5496
5497	/* Maximum number of supported threads in this test */
5498	pthread_t t[3];
5499	int n, rv;
5500
5501	DPRINTF("Spawn tracee\n");
5502	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5503	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
5504	tracee = atf_utils_fork();
5505	if (tracee == 0) {
5506		/* Wait for message from the parent */
5507		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
5508
5509		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
5510
5511		for (n = 0; n < threads; n++) {
5512			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
5513			FORKEE_ASSERT(rv == 0);
5514		}
5515
5516		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
5517
5518		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5519		FORKEE_ASSERT(raise(sigval) == 0);
5520
5521		/* NOTREACHED */
5522		FORKEE_ASSERTX(0 && "Not reached");
5523	}
5524	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
5525
5526	DPRINTF("Spawn debugger\n");
5527	tracer = atf_utils_fork();
5528	if (tracer == 0) {
5529		/* No IPC to communicate with the child */
5530		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
5531		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5532
5533		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
5534		FORKEE_REQUIRE_SUCCESS(
5535		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5536
5537		forkee_status_stopped(status, SIGSTOP);
5538
5539		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5540		    "tracee");
5541		FORKEE_ASSERT(
5542		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
5543
5544		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5545		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5546		    "si_errno=%#x\n",
5547		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5548		    info.psi_siginfo.si_errno);
5549
5550		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
5551		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
5552
5553		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5554		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5555		    != -1);
5556
5557		DPRINTF("Assert that there exists a thread\n");
5558		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
5559
5560		DPRINTF("Assert that lwp thread %d received event "
5561		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
5562		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
5563
5564		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5565		    "tracee\n");
5566		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5567		    != -1);
5568
5569		DPRINTF("Assert that there are no more lwp threads in "
5570		    "tracee\n");
5571		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5572
5573		/* Resume tracee with PT_CONTINUE */
5574		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5575
5576		/* Inform parent that tracer has attached to tracee */
5577		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
5578
5579		/* Wait for parent */
5580		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
5581
5582		/* Wait for tracee and assert that it raised a signal */
5583		FORKEE_REQUIRE_SUCCESS(
5584		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5585
5586		forkee_status_stopped(status, SIGINT);
5587
5588		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5589		    "child");
5590		FORKEE_ASSERT(
5591		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
5592
5593		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5594		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5595		    "si_errno=%#x\n",
5596		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5597		    info.psi_siginfo.si_errno);
5598
5599		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
5600		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
5601
5602		memset(&lwp, 0, sizeof(lwp));
5603
5604		for (n = 0; n <= threads; n++) {
5605			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5606			    "child\n");
5607			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
5608			    sizeof(lwp)) != -1);
5609			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5610
5611			DPRINTF("Assert that the thread exists\n");
5612			FORKEE_ASSERT(lwp.pl_lwpid > 0);
5613
5614			DPRINTF("Assert that lwp thread %d received expected "
5615			    "event\n", lwp.pl_lwpid);
5616			FORKEE_ASSERT_EQ(lwp.pl_event,
5617			    info.psi_lwpid == lwp.pl_lwpid ?
5618			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
5619		}
5620		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5621		    "tracee\n");
5622		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5623		    != -1);
5624		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5625
5626		DPRINTF("Assert that there are no more threads\n");
5627		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5628
5629		DPRINTF("Before resuming the child process where it left off "
5630		    "and without signal to be sent\n");
5631		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
5632		    != -1);
5633
5634		/* Wait for tracee and assert that it exited */
5635		FORKEE_REQUIRE_SUCCESS(
5636		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5637
5638		forkee_status_signaled(status, SIGKILL, 0);
5639
5640		DPRINTF("Before exiting of the tracer process\n");
5641		_exit(exitval_tracer);
5642	}
5643
5644	DPRINTF("Wait for the tracer to attach to the tracee\n");
5645	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
5646
5647	DPRINTF("Resume the tracee and spawn threads\n");
5648	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
5649
5650	DPRINTF("Resume the tracee and let it exit\n");
5651	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
5652
5653	DPRINTF("Resume the tracer and let it detect multiple threads\n");
5654	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
5655
5656	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
5657	    TWAIT_FNAME);
5658	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
5659	    tracer);
5660
5661	validate_status_exited(status, exitval_tracer);
5662
5663	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5664	    TWAIT_FNAME);
5665	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
5666	    tracee);
5667
5668	validate_status_signaled(status, SIGKILL, 0);
5669
5670	msg_close(&parent_tracer);
5671	msg_close(&parent_tracee);
5672}
5673
5674#define ATTACH_LWPINFO(test, threads)					\
5675ATF_TC(test);								\
5676ATF_TC_HEAD(test, tc)							\
5677{									\
5678	atf_tc_set_md_var(tc, "descr",					\
5679	    "Verify LWPINFO with the child with " #threads		\
5680	    " spawned extra threads (tracer is not the original "	\
5681	    "parent)");							\
5682}									\
5683									\
5684ATF_TC_BODY(test, tc)							\
5685{									\
5686									\
5687	attach_lwpinfo(threads);					\
5688}
5689
5690ATTACH_LWPINFO(attach_lwpinfo0, 0)
5691ATTACH_LWPINFO(attach_lwpinfo1, 1)
5692ATTACH_LWPINFO(attach_lwpinfo2, 2)
5693ATTACH_LWPINFO(attach_lwpinfo3, 3)
5694#endif
5695
5696/// ----------------------------------------------------------------------------
5697
5698static void
5699ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
5700{
5701	const int exitval = 5;
5702	const int sigval = SIGINT;
5703	const int sigfaked = SIGTRAP;
5704	const int sicodefaked = TRAP_BRKPT;
5705	pid_t child, wpid;
5706	struct sigaction sa;
5707#if defined(TWAIT_HAVE_STATUS)
5708	int status;
5709#endif
5710	struct ptrace_siginfo info;
5711	memset(&info, 0, sizeof(info));
5712
5713	DPRINTF("Before forking process PID=%d\n", getpid());
5714	SYSCALL_REQUIRE((child = fork()) != -1);
5715	if (child == 0) {
5716		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5717		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5718
5719		sa.sa_sigaction = sah;
5720		sa.sa_flags = SA_SIGINFO;
5721		sigemptyset(&sa.sa_mask);
5722
5723		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
5724		    != -1);
5725
5726		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5727		FORKEE_ASSERT(raise(sigval) == 0);
5728
5729		FORKEE_ASSERT_EQ(*signal_caught, 1);
5730
5731		DPRINTF("Before exiting of the child process\n");
5732		_exit(exitval);
5733	}
5734	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5735
5736	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5737	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5738
5739	validate_status_stopped(status, sigval);
5740
5741	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5742	SYSCALL_REQUIRE(
5743	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5744
5745	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5746	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5747	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5748	    info.psi_siginfo.si_errno);
5749
5750	if (faked) {
5751		DPRINTF("Before setting new faked signal to signo=%d "
5752		    "si_code=%d\n", sigfaked, sicodefaked);
5753		info.psi_siginfo.si_signo = sigfaked;
5754		info.psi_siginfo.si_code = sicodefaked;
5755	}
5756
5757	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5758	SYSCALL_REQUIRE(
5759	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5760
5761	if (faked) {
5762		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5763		    "child\n");
5764		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
5765		    sizeof(info)) != -1);
5766
5767		DPRINTF("Before checking siginfo_t\n");
5768		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
5769		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
5770	}
5771
5772	DPRINTF("Before resuming the child process where it left off and "
5773	    "without signal to be sent\n");
5774	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
5775	    faked ? sigfaked : sigval) != -1);
5776
5777	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5778	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5779
5780	validate_status_exited(status, exitval);
5781
5782	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5783	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5784}
5785
5786#define PTRACE_SIGINFO(test, faked)					\
5787ATF_TC(test);								\
5788ATF_TC_HEAD(test, tc)							\
5789{									\
5790	atf_tc_set_md_var(tc, "descr",					\
5791	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
5792	    "with%s setting signal to new value", faked ? "" : "out");	\
5793}									\
5794									\
5795static int test##_caught = 0;						\
5796									\
5797static void								\
5798test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
5799{									\
5800	if (faked) {							\
5801		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
5802		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
5803		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
5804	} else {							\
5805		FORKEE_ASSERT_EQ(sig, SIGINT);				\
5806		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
5807		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
5808	}								\
5809									\
5810	++ test##_caught;						\
5811}									\
5812									\
5813ATF_TC_BODY(test, tc)							\
5814{									\
5815									\
5816	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
5817}
5818
5819PTRACE_SIGINFO(siginfo_set_unmodified, false)
5820PTRACE_SIGINFO(siginfo_set_faked, true)
5821
5822/// ----------------------------------------------------------------------------
5823
5824static void
5825traceme_exec(bool masked, bool ignored)
5826{
5827	const int sigval = SIGTRAP;
5828	pid_t child, wpid;
5829#if defined(TWAIT_HAVE_STATUS)
5830	int status;
5831#endif
5832	struct sigaction sa;
5833	struct ptrace_siginfo info;
5834	sigset_t intmask;
5835	struct kinfo_proc2 kp;
5836	size_t len = sizeof(kp);
5837
5838	int name[6];
5839	const size_t namelen = __arraycount(name);
5840	ki_sigset_t kp_sigmask;
5841	ki_sigset_t kp_sigignore;
5842
5843	memset(&info, 0, sizeof(info));
5844
5845	DPRINTF("Before forking process PID=%d\n", getpid());
5846	SYSCALL_REQUIRE((child = fork()) != -1);
5847	if (child == 0) {
5848		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5849		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5850
5851		if (masked) {
5852			sigemptyset(&intmask);
5853			sigaddset(&intmask, sigval);
5854			sigprocmask(SIG_BLOCK, &intmask, NULL);
5855		}
5856
5857		if (ignored) {
5858			memset(&sa, 0, sizeof(sa));
5859			sa.sa_handler = SIG_IGN;
5860			sigemptyset(&sa.sa_mask);
5861			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
5862		}
5863
5864		DPRINTF("Before calling execve(2) from child\n");
5865		execlp("/bin/echo", "/bin/echo", NULL);
5866
5867		FORKEE_ASSERT(0 && "Not reached");
5868	}
5869	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5870
5871	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5872	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5873
5874	validate_status_stopped(status, sigval);
5875
5876	name[0] = CTL_KERN,
5877	name[1] = KERN_PROC2,
5878	name[2] = KERN_PROC_PID;
5879	name[3] = getpid();
5880	name[4] = sizeof(kp);
5881	name[5] = 1;
5882
5883	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5884
5885	if (masked)
5886		kp_sigmask = kp.p_sigmask;
5887
5888	if (ignored)
5889		kp_sigignore = kp.p_sigignore;
5890
5891	name[3] = getpid();
5892
5893	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5894
5895	if (masked) {
5896		DPRINTF("kp_sigmask="
5897		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5898		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5899		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5900
5901		DPRINTF("kp.p_sigmask="
5902		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5903		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5904		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5905
5906		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5907		    sizeof(kp_sigmask)));
5908	}
5909
5910	if (ignored) {
5911		DPRINTF("kp_sigignore="
5912		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5913		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
5914		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
5915
5916		DPRINTF("kp.p_sigignore="
5917		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5918		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
5919		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
5920
5921		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
5922		    sizeof(kp_sigignore)));
5923	}
5924
5925	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5926	SYSCALL_REQUIRE(
5927	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5928
5929	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5930	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5931	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5932	    info.psi_siginfo.si_errno);
5933
5934	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5935	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
5936
5937	DPRINTF("Before resuming the child process where it left off and "
5938	    "without signal to be sent\n");
5939	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5940
5941	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5942	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5943
5944	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5945	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5946}
5947
5948#define TRACEME_EXEC(test, masked, ignored)				\
5949ATF_TC(test);								\
5950ATF_TC_HEAD(test, tc)							\
5951{									\
5952       atf_tc_set_md_var(tc, "descr",					\
5953           "Detect SIGTRAP TRAP_EXEC from "				\
5954           "child%s%s", masked ? " with masked signal" : "",		\
5955           masked ? " with ignored signal" : "");			\
5956}									\
5957									\
5958ATF_TC_BODY(test, tc)							\
5959{									\
5960									\
5961       traceme_exec(masked, ignored);					\
5962}
5963
5964TRACEME_EXEC(traceme_exec, false, false)
5965TRACEME_EXEC(traceme_signalmasked_exec, true, false)
5966TRACEME_EXEC(traceme_signalignored_exec, false, true)
5967
5968/// ----------------------------------------------------------------------------
5969
5970#define TRACE_THREADS_NUM 100
5971
5972static volatile int done;
5973pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
5974
5975static void *
5976trace_threads_cb(void *arg __unused)
5977{
5978
5979	pthread_mutex_lock(&trace_threads_mtx);
5980	done++;
5981	pthread_mutex_unlock(&trace_threads_mtx);
5982
5983	while (done < TRACE_THREADS_NUM)
5984		sched_yield();
5985
5986	return NULL;
5987}
5988
5989static void
5990trace_threads(bool trace_create, bool trace_exit, bool masked)
5991{
5992	const int sigval = SIGSTOP;
5993	pid_t child, wpid;
5994#if defined(TWAIT_HAVE_STATUS)
5995	int status;
5996#endif
5997	ptrace_state_t state;
5998	const int slen = sizeof(state);
5999	ptrace_event_t event;
6000	const int elen = sizeof(event);
6001	struct ptrace_siginfo info;
6002
6003	sigset_t intmask;
6004
6005	pthread_t t[TRACE_THREADS_NUM];
6006	int rv;
6007	size_t n;
6008	lwpid_t lid;
6009
6010	/* Track created and exited threads */
6011	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
6012
6013	DPRINTF("Before forking process PID=%d\n", getpid());
6014	SYSCALL_REQUIRE((child = fork()) != -1);
6015	if (child == 0) {
6016		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6017		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6018
6019		if (masked) {
6020			sigemptyset(&intmask);
6021			sigaddset(&intmask, SIGTRAP);
6022			sigprocmask(SIG_BLOCK, &intmask, NULL);
6023		}
6024
6025		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6026		FORKEE_ASSERT(raise(sigval) == 0);
6027
6028		for (n = 0; n < __arraycount(t); n++) {
6029			rv = pthread_create(&t[n], NULL, trace_threads_cb,
6030			    NULL);
6031			FORKEE_ASSERT(rv == 0);
6032		}
6033
6034		for (n = 0; n < __arraycount(t); n++) {
6035			rv = pthread_join(t[n], NULL);
6036			FORKEE_ASSERT(rv == 0);
6037		}
6038
6039		/*
6040		 * There is race between _exit() and pthread_join() detaching
6041		 * a thread. For simplicity kill the process after detecting
6042		 * LWP events.
6043		 */
6044		while (true)
6045			continue;
6046
6047		FORKEE_ASSERT(0 && "Not reached");
6048	}
6049	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6050
6051	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6052	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6053
6054	validate_status_stopped(status, sigval);
6055
6056	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6057	SYSCALL_REQUIRE(
6058	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6059
6060	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6061	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
6062	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6063	    info.psi_siginfo.si_errno);
6064
6065	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6066	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
6067
6068	DPRINTF("Set LWP event mask for the child %d\n", child);
6069	memset(&event, 0, sizeof(event));
6070	if (trace_create)
6071		event.pe_set_event |= PTRACE_LWP_CREATE;
6072	if (trace_exit)
6073		event.pe_set_event |= PTRACE_LWP_EXIT;
6074	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6075
6076	DPRINTF("Before resuming the child process where it left off and "
6077	    "without signal to be sent\n");
6078	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6079
6080	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
6081		DPRINTF("Before calling %s() for the child - expected stopped "
6082		    "SIGTRAP\n", TWAIT_FNAME);
6083		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6084		    child);
6085
6086		validate_status_stopped(status, SIGTRAP);
6087
6088		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6089		    "child\n");
6090		SYSCALL_REQUIRE(
6091		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6092
6093		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6094		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6095		    "si_errno=%#x\n",
6096		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6097		    info.psi_siginfo.si_errno);
6098
6099		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6100		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6101
6102		SYSCALL_REQUIRE(
6103		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6104
6105		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
6106		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
6107
6108		lid = state.pe_lwp;
6109		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6110
6111		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
6112
6113		DPRINTF("Before resuming the child process where it left off "
6114		    "and without signal to be sent\n");
6115		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6116	}
6117
6118	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
6119		DPRINTF("Before calling %s() for the child - expected stopped "
6120		    "SIGTRAP\n", TWAIT_FNAME);
6121		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6122		    child);
6123
6124		validate_status_stopped(status, SIGTRAP);
6125
6126		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6127		    "child\n");
6128		SYSCALL_REQUIRE(
6129		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6130
6131		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6132		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6133		    "si_errno=%#x\n",
6134		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6135		    info.psi_siginfo.si_errno);
6136
6137		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6138		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6139
6140		SYSCALL_REQUIRE(
6141		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6142
6143		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
6144		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
6145
6146		lid = state.pe_lwp;
6147		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6148
6149		if (trace_create) {
6150			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
6151			ATF_REQUIRE_EQ(*count, 1);
6152			*count = 0;
6153		}
6154
6155		DPRINTF("Before resuming the child process where it left off "
6156		    "and without signal to be sent\n");
6157		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6158	}
6159
6160	kill(child, SIGKILL);
6161
6162	DPRINTF("Before calling %s() for the child - expected exited\n",
6163	    TWAIT_FNAME);
6164	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6165
6166	validate_status_signaled(status, SIGKILL, 0);
6167
6168	DPRINTF("Before calling %s() for the child - expected no process\n",
6169	    TWAIT_FNAME);
6170	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6171}
6172
6173#define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
6174ATF_TC(test);								\
6175ATF_TC_HEAD(test, tc)							\
6176{									\
6177        atf_tc_set_md_var(tc, "descr",					\
6178            "Verify spawning threads with%s tracing LWP create and"	\
6179	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
6180	    trace_exit ? "" : "out");					\
6181}									\
6182									\
6183ATF_TC_BODY(test, tc)							\
6184{									\
6185									\
6186        trace_threads(trace_create, trace_exit, mask);			\
6187}
6188
6189TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
6190TRACE_THREADS(trace_thread_lwpexit, false, true, false)
6191TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
6192TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
6193
6194TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
6195TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
6196TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
6197
6198/// ----------------------------------------------------------------------------
6199
6200ATF_TC(signal_mask_unrelated);
6201ATF_TC_HEAD(signal_mask_unrelated, tc)
6202{
6203	atf_tc_set_md_var(tc, "descr",
6204	    "Verify that masking single unrelated signal does not stop tracer "
6205	    "from catching other signals");
6206}
6207
6208ATF_TC_BODY(signal_mask_unrelated, tc)
6209{
6210	const int exitval = 5;
6211	const int sigval = SIGSTOP;
6212	const int sigmasked = SIGTRAP;
6213	const int signotmasked = SIGINT;
6214	pid_t child, wpid;
6215#if defined(TWAIT_HAVE_STATUS)
6216	int status;
6217#endif
6218	sigset_t intmask;
6219
6220	DPRINTF("Before forking process PID=%d\n", getpid());
6221	SYSCALL_REQUIRE((child = fork()) != -1);
6222	if (child == 0) {
6223		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6224		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6225
6226		sigemptyset(&intmask);
6227		sigaddset(&intmask, sigmasked);
6228		sigprocmask(SIG_BLOCK, &intmask, NULL);
6229
6230		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6231		FORKEE_ASSERT(raise(sigval) == 0);
6232
6233		DPRINTF("Before raising %s from child\n",
6234		    strsignal(signotmasked));
6235		FORKEE_ASSERT(raise(signotmasked) == 0);
6236
6237		DPRINTF("Before exiting of the child process\n");
6238		_exit(exitval);
6239	}
6240	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6241
6242	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6243	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6244
6245	validate_status_stopped(status, sigval);
6246
6247	DPRINTF("Before resuming the child process where it left off and "
6248	    "without signal to be sent\n");
6249	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6250
6251	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6252	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6253
6254	validate_status_stopped(status, signotmasked);
6255
6256	DPRINTF("Before resuming the child process where it left off and "
6257	    "without signal to be sent\n");
6258	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6259
6260	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6261	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6262
6263	validate_status_exited(status, exitval);
6264
6265	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6266	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6267}
6268
6269/// ----------------------------------------------------------------------------
6270
6271#if defined(TWAIT_HAVE_PID)
6272static void
6273fork2_body(const char *fn, bool masked, bool ignored)
6274{
6275	const int exitval = 5;
6276	const int exitval2 = 0; /* Match exit status from /bin/echo */
6277	const int sigval = SIGSTOP;
6278	pid_t child, child2 = 0, wpid;
6279#if defined(TWAIT_HAVE_STATUS)
6280	int status;
6281#endif
6282	ptrace_state_t state;
6283	const int slen = sizeof(state);
6284	ptrace_event_t event;
6285	const int elen = sizeof(event);
6286	struct sigaction sa;
6287	struct ptrace_siginfo info;
6288	sigset_t intmask;
6289	struct kinfo_proc2 kp;
6290	size_t len = sizeof(kp);
6291
6292	int name[6];
6293	const size_t namelen = __arraycount(name);
6294	ki_sigset_t kp_sigmask;
6295	ki_sigset_t kp_sigignore;
6296
6297	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
6298
6299	DPRINTF("Before forking process PID=%d\n", getpid());
6300	SYSCALL_REQUIRE((child = fork()) != -1);
6301	if (child == 0) {
6302		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6303		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6304
6305		if (masked) {
6306			sigemptyset(&intmask);
6307			sigaddset(&intmask, SIGTRAP);
6308			sigprocmask(SIG_BLOCK, &intmask, NULL);
6309		}
6310
6311		if (ignored) {
6312			memset(&sa, 0, sizeof(sa));
6313			sa.sa_handler = SIG_IGN;
6314			sigemptyset(&sa.sa_mask);
6315			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
6316		}
6317
6318		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6319		FORKEE_ASSERT(raise(sigval) == 0);
6320
6321		if (strcmp(fn, "spawn") == 0) {
6322			FORKEE_ASSERT_EQ(posix_spawn(&child2,
6323			    arg[0], NULL, NULL, arg, NULL), 0);
6324		} else  {
6325			if (strcmp(fn, "fork") == 0) {
6326				FORKEE_ASSERT((child2 = fork()) != -1);
6327			} else {
6328				FORKEE_ASSERT((child2 = vfork()) != -1);
6329			}
6330			if (child2 == 0)
6331				_exit(exitval2);
6332		}
6333
6334		FORKEE_REQUIRE_SUCCESS
6335		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6336
6337		forkee_status_exited(status, exitval2);
6338
6339		DPRINTF("Before exiting of the child process\n");
6340		_exit(exitval);
6341	}
6342	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6343
6344	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6345	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6346
6347	validate_status_stopped(status, sigval);
6348
6349	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6350	SYSCALL_REQUIRE(
6351	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6352
6353	DPRINTF("Before checking siginfo_t\n");
6354	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6355	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
6356
6357	name[0] = CTL_KERN,
6358	name[1] = KERN_PROC2,
6359	name[2] = KERN_PROC_PID;
6360	name[3] = child;
6361	name[4] = sizeof(kp);
6362	name[5] = 1;
6363
6364	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6365
6366	if (masked)
6367		kp_sigmask = kp.p_sigmask;
6368
6369	if (ignored)
6370		kp_sigignore = kp.p_sigignore;
6371
6372	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
6373	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
6374	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
6375	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
6376	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
6377	event.pe_set_event = 0;
6378	if (strcmp(fn, "spawn") == 0)
6379		event.pe_set_event |= PTRACE_POSIX_SPAWN;
6380	if (strcmp(fn, "fork") == 0)
6381		event.pe_set_event |= PTRACE_FORK;
6382	if (strcmp(fn, "vfork") == 0)
6383		event.pe_set_event |= PTRACE_VFORK;
6384	if (strcmp(fn, "vforkdone") == 0)
6385		event.pe_set_event |= PTRACE_VFORK_DONE;
6386	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6387
6388	DPRINTF("Before resuming the child process where it left off and "
6389	    "without signal to be sent\n");
6390	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6391
6392	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
6393	    strcmp(fn, "vfork") == 0) {
6394		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6395		    child);
6396		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6397		    child);
6398
6399		validate_status_stopped(status, SIGTRAP);
6400
6401		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6402
6403		if (masked) {
6404			DPRINTF("kp_sigmask="
6405			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6406			    PRIx32 "\n",
6407			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6408			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6409
6410			DPRINTF("kp.p_sigmask="
6411			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6412			    PRIx32 "\n",
6413			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6414			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6415
6416			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6417			    sizeof(kp_sigmask)));
6418		}
6419
6420		if (ignored) {
6421			DPRINTF("kp_sigignore="
6422			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6423			    PRIx32 "\n",
6424			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6425			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6426
6427			DPRINTF("kp.p_sigignore="
6428			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6429			    PRIx32 "\n",
6430			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6431			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6432
6433			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6434			    sizeof(kp_sigignore)));
6435		}
6436
6437		SYSCALL_REQUIRE(
6438		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6439		if (strcmp(fn, "spawn") == 0) {
6440			ATF_REQUIRE_EQ(
6441			    state.pe_report_event & PTRACE_POSIX_SPAWN,
6442			       PTRACE_POSIX_SPAWN);
6443		}
6444		if (strcmp(fn, "fork") == 0) {
6445			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6446			       PTRACE_FORK);
6447		}
6448		if (strcmp(fn, "vfork") == 0) {
6449			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6450			       PTRACE_VFORK);
6451		}
6452
6453		child2 = state.pe_other_pid;
6454		DPRINTF("Reported ptrace event with forkee %d\n", child2);
6455
6456		DPRINTF("Before calling %s() for the forkee %d of the child "
6457		    "%d\n", TWAIT_FNAME, child2, child);
6458		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6459		    child2);
6460
6461		validate_status_stopped(status, SIGTRAP);
6462
6463		name[3] = child2;
6464		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6465
6466		if (masked) {
6467			DPRINTF("kp_sigmask="
6468			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6469			    PRIx32 "\n",
6470			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6471			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6472
6473			DPRINTF("kp.p_sigmask="
6474			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6475			    PRIx32 "\n",
6476			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6477			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6478
6479			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6480			    sizeof(kp_sigmask)));
6481		}
6482
6483		if (ignored) {
6484			DPRINTF("kp_sigignore="
6485			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6486			    PRIx32 "\n",
6487			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6488			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6489
6490			DPRINTF("kp.p_sigignore="
6491			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6492			    PRIx32 "\n",
6493			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6494			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6495
6496			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6497			    sizeof(kp_sigignore)));
6498		}
6499
6500		SYSCALL_REQUIRE(
6501		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6502		if (strcmp(fn, "spawn") == 0) {
6503			ATF_REQUIRE_EQ(
6504			    state.pe_report_event & PTRACE_POSIX_SPAWN,
6505			       PTRACE_POSIX_SPAWN);
6506		}
6507		if (strcmp(fn, "fork") == 0) {
6508			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6509			       PTRACE_FORK);
6510		}
6511		if (strcmp(fn, "vfork") == 0) {
6512			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6513			       PTRACE_VFORK);
6514		}
6515
6516		ATF_REQUIRE_EQ(state.pe_other_pid, child);
6517
6518		DPRINTF("Before resuming the forkee process where it left off "
6519		    "and without signal to be sent\n");
6520		SYSCALL_REQUIRE(
6521		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6522
6523		DPRINTF("Before resuming the child process where it left off "
6524		    "and without signal to be sent\n");
6525		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6526	}
6527
6528	if (strcmp(fn, "vforkdone") == 0) {
6529		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6530		    child);
6531		TWAIT_REQUIRE_SUCCESS(
6532		    wpid = TWAIT_GENERIC(child, &status, 0), child);
6533
6534		validate_status_stopped(status, SIGTRAP);
6535
6536		name[3] = child;
6537		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6538
6539		/*
6540		 * SIGCHLD is now pending in the signal queue and
6541		 * the kernel presents it to userland as a masked signal.
6542		 */
6543		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
6544
6545		if (masked) {
6546			DPRINTF("kp_sigmask="
6547			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6548			    PRIx32 "\n",
6549			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6550			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6551
6552			DPRINTF("kp.p_sigmask="
6553			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6554			    PRIx32 "\n",
6555			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6556			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6557
6558			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6559			    sizeof(kp_sigmask)));
6560		}
6561
6562		if (ignored) {
6563			DPRINTF("kp_sigignore="
6564			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6565			    PRIx32 "\n",
6566			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6567			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6568
6569			DPRINTF("kp.p_sigignore="
6570			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6571			    PRIx32 "\n",
6572			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6573			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6574
6575			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6576			    sizeof(kp_sigignore)));
6577		}
6578
6579		SYSCALL_REQUIRE(
6580		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6581		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6582
6583		child2 = state.pe_other_pid;
6584		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
6585		    child2);
6586
6587		DPRINTF("Before resuming the child process where it left off "
6588		    "and without signal to be sent\n");
6589		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6590	}
6591
6592	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
6593	    strcmp(fn, "vfork") == 0) {
6594		DPRINTF("Before calling %s() for the forkee - expected exited"
6595		    "\n", TWAIT_FNAME);
6596		TWAIT_REQUIRE_SUCCESS(
6597		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6598
6599		validate_status_exited(status, exitval2);
6600
6601		DPRINTF("Before calling %s() for the forkee - expected no "
6602		    "process\n", TWAIT_FNAME);
6603		TWAIT_REQUIRE_FAILURE(ECHILD,
6604		    wpid = TWAIT_GENERIC(child2, &status, 0));
6605	}
6606
6607	DPRINTF("Before calling %s() for the child - expected stopped "
6608	    "SIGCHLD\n", TWAIT_FNAME);
6609	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6610
6611	validate_status_stopped(status, SIGCHLD);
6612
6613	DPRINTF("Before resuming the child process where it left off and "
6614	    "without signal to be sent\n");
6615	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6616
6617	DPRINTF("Before calling %s() for the child - expected exited\n",
6618	    TWAIT_FNAME);
6619	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6620
6621	validate_status_exited(status, exitval);
6622
6623	DPRINTF("Before calling %s() for the child - expected no process\n",
6624	    TWAIT_FNAME);
6625	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6626}
6627
6628#define FORK2_TEST(name,fn,masked,ignored)				\
6629ATF_TC(name);								\
6630ATF_TC_HEAD(name, tc)							\
6631{									\
6632	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
6633	    "regardless of signal %s%s", 				\
6634	    masked ? "masked" : "", ignored ? "ignored" : "");		\
6635}									\
6636									\
6637ATF_TC_BODY(name, tc)							\
6638{									\
6639									\
6640	fork2_body(fn, masked, ignored);				\
6641}
6642
6643FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false)
6644FORK2_TEST(posix_spawn_singalignored, "spawn", false, true)
6645FORK2_TEST(fork_singalmasked, "fork", true, false)
6646FORK2_TEST(fork_singalignored, "fork", false, true)
6647FORK2_TEST(vfork_singalmasked, "vfork", true, false)
6648FORK2_TEST(vfork_singalignored, "vfork", false, true)
6649FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false)
6650FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true)
6651#endif
6652
6653/// ----------------------------------------------------------------------------
6654
6655static void *
6656thread_and_exec_thread_cb(void *arg __unused)
6657{
6658
6659	execlp("/bin/echo", "/bin/echo", NULL);
6660
6661	abort();
6662}
6663
6664static void
6665threads_and_exec(void)
6666{
6667	const int sigval = SIGSTOP;
6668	pid_t child, wpid;
6669#if defined(TWAIT_HAVE_STATUS)
6670	int status;
6671#endif
6672	ptrace_state_t state;
6673	const int slen = sizeof(state);
6674	ptrace_event_t event;
6675	const int elen = sizeof(event);
6676	struct ptrace_siginfo info;
6677
6678	pthread_t t;
6679	lwpid_t lid;
6680
6681	DPRINTF("Before forking process PID=%d\n", getpid());
6682	SYSCALL_REQUIRE((child = fork()) != -1);
6683	if (child == 0) {
6684		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6685		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6686
6687		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6688		FORKEE_ASSERT(raise(sigval) == 0);
6689
6690		FORKEE_ASSERT(pthread_create(&t, NULL,
6691		    thread_and_exec_thread_cb, NULL) == 0);
6692
6693		for (;;)
6694			continue;
6695
6696		FORKEE_ASSERT(0 && "Not reached");
6697	}
6698	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6699
6700	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6701	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6702
6703	validate_status_stopped(status, sigval);
6704
6705	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6706	SYSCALL_REQUIRE(
6707	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6708
6709	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6710	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
6711	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6712	    info.psi_siginfo.si_errno);
6713
6714	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6715	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
6716
6717	DPRINTF("Set LWP event mask for the child %d\n", child);
6718	memset(&event, 0, sizeof(event));
6719	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
6720	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6721
6722	DPRINTF("Before resuming the child process where it left off and "
6723	    "without signal to be sent\n");
6724	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6725
6726	DPRINTF("Before calling %s() for the child - expected stopped "
6727	    "SIGTRAP\n", TWAIT_FNAME);
6728	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6729	    child);
6730
6731	validate_status_stopped(status, SIGTRAP);
6732
6733	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6734	    "child\n");
6735	SYSCALL_REQUIRE(
6736	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6737
6738	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6739	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6740	    "si_errno=%#x\n",
6741	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6742	    info.psi_siginfo.si_errno);
6743
6744	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6745	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6746
6747	SYSCALL_REQUIRE(
6748	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6749
6750	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
6751	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
6752
6753	lid = state.pe_lwp;
6754	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6755
6756	DPRINTF("Before resuming the child process where it left off "
6757	    "and without signal to be sent\n");
6758	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6759
6760	DPRINTF("Before calling %s() for the child - expected stopped "
6761	    "SIGTRAP\n", TWAIT_FNAME);
6762	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6763	    child);
6764
6765	validate_status_stopped(status, SIGTRAP);
6766
6767	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6768	    "child\n");
6769	SYSCALL_REQUIRE(
6770	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6771
6772	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6773	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6774	    "si_errno=%#x\n",
6775	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6776	    info.psi_siginfo.si_errno);
6777
6778	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6779	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6780
6781	SYSCALL_REQUIRE(
6782	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6783
6784	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
6785	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
6786
6787	lid = state.pe_lwp;
6788	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6789
6790	DPRINTF("Before resuming the child process where it left off "
6791	    "and without signal to be sent\n");
6792	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6793
6794	DPRINTF("Before calling %s() for the child - expected stopped "
6795	    "SIGTRAP\n", TWAIT_FNAME);
6796	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6797	    child);
6798
6799	validate_status_stopped(status, SIGTRAP);
6800
6801	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6802	    "child\n");
6803	SYSCALL_REQUIRE(
6804	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6805
6806	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6807	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6808	    "si_errno=%#x\n",
6809	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6810	    info.psi_siginfo.si_errno);
6811
6812	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6813	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
6814
6815	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
6816
6817	DPRINTF("Before calling %s() for the child - expected exited\n",
6818	    TWAIT_FNAME);
6819	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6820
6821	validate_status_signaled(status, SIGKILL, 0);
6822
6823	DPRINTF("Before calling %s() for the child - expected no process\n",
6824	    TWAIT_FNAME);
6825	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6826}
6827
6828ATF_TC(threads_and_exec);
6829ATF_TC_HEAD(threads_and_exec, tc)
6830{
6831        atf_tc_set_md_var(tc, "descr",
6832            "Verify that multithreaded application on exec() will report "
6833	    "LWP_EXIT events");
6834}
6835
6836ATF_TC_BODY(threads_and_exec, tc)
6837{
6838
6839        threads_and_exec();
6840}
6841
6842/// ----------------------------------------------------------------------------
6843
6844ATF_TC(suspend_no_deadlock);
6845ATF_TC_HEAD(suspend_no_deadlock, tc)
6846{
6847	atf_tc_set_md_var(tc, "descr",
6848	    "Verify that the while the only thread within a process is "
6849	    "suspended, the whole process cannot be unstopped");
6850}
6851
6852ATF_TC_BODY(suspend_no_deadlock, tc)
6853{
6854	const int exitval = 5;
6855	const int sigval = SIGSTOP;
6856	pid_t child, wpid;
6857#if defined(TWAIT_HAVE_STATUS)
6858	int status;
6859#endif
6860	struct ptrace_siginfo psi;
6861
6862	DPRINTF("Before forking process PID=%d\n", getpid());
6863	SYSCALL_REQUIRE((child = fork()) != -1);
6864	if (child == 0) {
6865		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6866		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6867
6868		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6869		FORKEE_ASSERT(raise(sigval) == 0);
6870
6871		DPRINTF("Before exiting of the child process\n");
6872		_exit(exitval);
6873	}
6874	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6875
6876	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6877	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6878
6879	validate_status_stopped(status, sigval);
6880
6881	DPRINTF("Before reading siginfo and lwpid_t\n");
6882	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6883
6884	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6885	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6886
6887	DPRINTF("Before resuming the child process where it left off and "
6888	    "without signal to be sent\n");
6889	ATF_REQUIRE_ERRNO(EDEADLK,
6890	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
6891
6892	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6893	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6894
6895	DPRINTF("Before resuming the child process where it left off and "
6896	    "without signal to be sent\n");
6897	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6898
6899	DPRINTF("Before calling %s() for the child - expected exited\n",
6900	    TWAIT_FNAME);
6901	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6902
6903	validate_status_exited(status, exitval);
6904
6905	DPRINTF("Before calling %s() for the child - expected no process\n",
6906	    TWAIT_FNAME);
6907	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6908}
6909
6910/// ----------------------------------------------------------------------------
6911
6912static pthread_barrier_t barrier1_resume;
6913static pthread_barrier_t barrier2_resume;
6914
6915static void *
6916resume_thread(void *arg)
6917{
6918
6919	raise(SIGUSR1);
6920
6921	pthread_barrier_wait(&barrier1_resume);
6922
6923	/* Debugger will suspend the process here */
6924
6925	pthread_barrier_wait(&barrier2_resume);
6926
6927	raise(SIGUSR2);
6928
6929	return infinite_thread(arg);
6930}
6931
6932ATF_TC(resume);
6933ATF_TC_HEAD(resume, tc)
6934{
6935	atf_tc_set_md_var(tc, "descr",
6936	    "Verify that a thread can be suspended by a debugger and later "
6937	    "resumed by the debugger");
6938}
6939
6940ATF_TC_BODY(resume, tc)
6941{
6942	const int sigval = SIGSTOP;
6943	pid_t child, wpid;
6944#if defined(TWAIT_HAVE_STATUS)
6945	int status;
6946#endif
6947	lwpid_t lid;
6948	struct ptrace_siginfo psi;
6949	pthread_t t;
6950
6951	DPRINTF("Before forking process PID=%d\n", getpid());
6952	SYSCALL_REQUIRE((child = fork()) != -1);
6953	if (child == 0) {
6954		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6955		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6956
6957		pthread_barrier_init(&barrier1_resume, NULL, 2);
6958		pthread_barrier_init(&barrier2_resume, NULL, 2);
6959
6960		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6961		FORKEE_ASSERT(raise(sigval) == 0);
6962
6963		DPRINTF("Before creating new thread in child\n");
6964		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
6965
6966		pthread_barrier_wait(&barrier1_resume);
6967
6968		pthread_barrier_wait(&barrier2_resume);
6969
6970		infinite_thread(NULL);
6971	}
6972	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6973
6974	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6975	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6976
6977	validate_status_stopped(status, sigval);
6978
6979	DPRINTF("Before resuming the child process where it left off and "
6980	    "without signal to be sent\n");
6981	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6982
6983	DPRINTF("Before calling %s() for the child - expected stopped "
6984	    "SIGUSR1\n", TWAIT_FNAME);
6985	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6986
6987	validate_status_stopped(status, SIGUSR1);
6988
6989	DPRINTF("Before reading siginfo and lwpid_t\n");
6990	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6991
6992	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6993	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6994
6995	lid = psi.psi_lwpid;
6996
6997	DPRINTF("Before resuming the child process where it left off and "
6998	    "without signal to be sent\n");
6999	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7000
7001	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
7002	SYSCALL_REQUIRE(sleep(1) == 0);
7003
7004#if defined(TWAIT_HAVE_OPTIONS)
7005	DPRINTF("Before calling %s() for the child - expected no status\n",
7006	    TWAIT_FNAME);
7007	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
7008#endif
7009
7010	DPRINTF("Before resuming the child process where it left off and "
7011	    "without signal to be sent\n");
7012	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
7013
7014	DPRINTF("Before calling %s() for the child - expected stopped "
7015	    "SIGSTOP\n", TWAIT_FNAME);
7016	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7017
7018	validate_status_stopped(status, SIGSTOP);
7019
7020	DPRINTF("Before resuming LWP %d\n", lid);
7021	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
7022
7023	DPRINTF("Before resuming the child process where it left off and "
7024	    "without signal to be sent\n");
7025	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7026
7027	DPRINTF("Before calling %s() for the child - expected stopped "
7028	    "SIGUSR2\n", TWAIT_FNAME);
7029	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7030
7031	validate_status_stopped(status, SIGUSR2);
7032
7033	DPRINTF("Before resuming the child process where it left off and "
7034	    "without signal to be sent\n");
7035	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
7036
7037	DPRINTF("Before calling %s() for the child - expected exited\n",
7038	    TWAIT_FNAME);
7039	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7040
7041	validate_status_signaled(status, SIGKILL, 0);
7042
7043	DPRINTF("Before calling %s() for the child - expected no process\n",
7044	    TWAIT_FNAME);
7045	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7046}
7047
7048/// ----------------------------------------------------------------------------
7049
7050static void
7051clone_body(int flags, bool trackfork, bool trackvfork,
7052    bool trackvforkdone)
7053{
7054	const int exitval = 5;
7055	const int exitval2 = 15;
7056	const int sigval = SIGSTOP;
7057	pid_t child, child2 = 0, wpid;
7058#if defined(TWAIT_HAVE_STATUS)
7059	int status;
7060#endif
7061	ptrace_state_t state;
7062	const int slen = sizeof(state);
7063	ptrace_event_t event;
7064	const int elen = sizeof(event);
7065
7066	const size_t stack_size = 1024 * 1024;
7067	void *stack, *stack_base;
7068
7069	stack = malloc(stack_size);
7070	ATF_REQUIRE(stack != NULL);
7071
7072#ifdef __MACHINE_STACK_GROWS_UP
7073	stack_base = stack;
7074#else
7075	stack_base = (char *)stack + stack_size;
7076#endif
7077
7078	DPRINTF("Before forking process PID=%d\n", getpid());
7079	SYSCALL_REQUIRE((child = fork()) != -1);
7080	if (child == 0) {
7081		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7082		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7083
7084		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7085		FORKEE_ASSERT(raise(sigval) == 0);
7086
7087		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7088		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7089
7090		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7091		    child2);
7092
7093		// XXX WALLSIG?
7094		FORKEE_REQUIRE_SUCCESS
7095		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7096
7097		forkee_status_exited(status, exitval2);
7098
7099		DPRINTF("Before exiting of the child process\n");
7100		_exit(exitval);
7101	}
7102	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7103
7104	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7105	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7106
7107	validate_status_stopped(status, sigval);
7108
7109	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
7110	    trackfork ? "|PTRACE_FORK" : "",
7111	    trackvfork ? "|PTRACE_VFORK" : "",
7112	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
7113	event.pe_set_event = 0;
7114	if (trackfork)
7115		event.pe_set_event |= PTRACE_FORK;
7116	if (trackvfork)
7117		event.pe_set_event |= PTRACE_VFORK;
7118	if (trackvforkdone)
7119		event.pe_set_event |= PTRACE_VFORK_DONE;
7120	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
7121
7122	DPRINTF("Before resuming the child process where it left off and "
7123	    "without signal to be sent\n");
7124	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7125
7126#if defined(TWAIT_HAVE_PID)
7127	if ((trackfork && !(flags & CLONE_VFORK)) ||
7128	    (trackvfork && (flags & CLONE_VFORK))) {
7129		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7130		    child);
7131		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
7132		    child);
7133
7134		validate_status_stopped(status, SIGTRAP);
7135
7136		SYSCALL_REQUIRE(
7137		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7138		if (trackfork && !(flags & CLONE_VFORK)) {
7139			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7140			       PTRACE_FORK);
7141		}
7142		if (trackvfork && (flags & CLONE_VFORK)) {
7143			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7144			       PTRACE_VFORK);
7145		}
7146
7147		child2 = state.pe_other_pid;
7148		DPRINTF("Reported ptrace event with forkee %d\n", child2);
7149
7150		DPRINTF("Before calling %s() for the forkee %d of the child "
7151		    "%d\n", TWAIT_FNAME, child2, child);
7152		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
7153		    child2);
7154
7155		validate_status_stopped(status, SIGTRAP);
7156
7157		SYSCALL_REQUIRE(
7158		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
7159		if (trackfork && !(flags & CLONE_VFORK)) {
7160			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7161			       PTRACE_FORK);
7162		}
7163		if (trackvfork && (flags & CLONE_VFORK)) {
7164			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7165			       PTRACE_VFORK);
7166		}
7167
7168		ATF_REQUIRE_EQ(state.pe_other_pid, child);
7169
7170		DPRINTF("Before resuming the forkee process where it left off "
7171		    "and without signal to be sent\n");
7172		SYSCALL_REQUIRE(
7173		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
7174
7175		DPRINTF("Before resuming the child process where it left off "
7176		    "and without signal to be sent\n");
7177		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7178	}
7179#endif
7180
7181	if (trackvforkdone && (flags & CLONE_VFORK)) {
7182		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7183		    child);
7184		TWAIT_REQUIRE_SUCCESS(
7185		    wpid = TWAIT_GENERIC(child, &status, 0), child);
7186
7187		validate_status_stopped(status, SIGTRAP);
7188
7189		SYSCALL_REQUIRE(
7190		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7191		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
7192
7193		child2 = state.pe_other_pid;
7194		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
7195		    child2);
7196
7197		DPRINTF("Before resuming the child process where it left off "
7198		    "and without signal to be sent\n");
7199		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7200	}
7201
7202#if defined(TWAIT_HAVE_PID)
7203	if ((trackfork && !(flags & CLONE_VFORK)) ||
7204	    (trackvfork && (flags & CLONE_VFORK))) {
7205		DPRINTF("Before calling %s() for the forkee - expected exited"
7206		    "\n", TWAIT_FNAME);
7207		TWAIT_REQUIRE_SUCCESS(
7208		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
7209
7210		validate_status_exited(status, exitval2);
7211
7212		DPRINTF("Before calling %s() for the forkee - expected no "
7213		    "process\n", TWAIT_FNAME);
7214		TWAIT_REQUIRE_FAILURE(ECHILD,
7215		    wpid = TWAIT_GENERIC(child2, &status, 0));
7216	}
7217#endif
7218
7219	DPRINTF("Before calling %s() for the child - expected stopped "
7220	    "SIGCHLD\n", TWAIT_FNAME);
7221	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7222
7223	validate_status_stopped(status, SIGCHLD);
7224
7225	DPRINTF("Before resuming the child process where it left off and "
7226	    "without signal to be sent\n");
7227	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7228
7229	DPRINTF("Before calling %s() for the child - expected exited\n",
7230	    TWAIT_FNAME);
7231	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7232
7233	validate_status_exited(status, exitval);
7234
7235	DPRINTF("Before calling %s() for the child - expected no process\n",
7236	    TWAIT_FNAME);
7237	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7238}
7239
7240#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone)			\
7241ATF_TC(name);								\
7242ATF_TC_HEAD(name, tc)							\
7243{									\
7244	atf_tc_set_md_var(tc, "descr", "Verify clone(%s) "		\
7245	    "called with 0%s%s%s in EVENT_MASK",			\
7246	    #flags,							\
7247	    tfork ? "|PTRACE_FORK" : "",				\
7248	    tvfork ? "|PTRACE_VFORK" : "",				\
7249	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
7250}									\
7251									\
7252ATF_TC_BODY(name, tc)							\
7253{									\
7254									\
7255	clone_body(flags, tfork, tvfork, tvforkdone);			\
7256}
7257
7258CLONE_TEST(clone1, 0, false, false, false)
7259#if defined(TWAIT_HAVE_PID)
7260CLONE_TEST(clone2, 0, true, false, false)
7261CLONE_TEST(clone3, 0, false, true, false)
7262CLONE_TEST(clone4, 0, true, true, false)
7263#endif
7264CLONE_TEST(clone5, 0, false, false, true)
7265#if defined(TWAIT_HAVE_PID)
7266CLONE_TEST(clone6, 0, true, false, true)
7267CLONE_TEST(clone7, 0, false, true, true)
7268CLONE_TEST(clone8, 0, true, true, true)
7269#endif
7270
7271CLONE_TEST(clone_vm1, CLONE_VM, false, false, false)
7272#if defined(TWAIT_HAVE_PID)
7273CLONE_TEST(clone_vm2, CLONE_VM, true, false, false)
7274CLONE_TEST(clone_vm3, CLONE_VM, false, true, false)
7275CLONE_TEST(clone_vm4, CLONE_VM, true, true, false)
7276#endif
7277CLONE_TEST(clone_vm5, CLONE_VM, false, false, true)
7278#if defined(TWAIT_HAVE_PID)
7279CLONE_TEST(clone_vm6, CLONE_VM, true, false, true)
7280CLONE_TEST(clone_vm7, CLONE_VM, false, true, true)
7281CLONE_TEST(clone_vm8, CLONE_VM, true, true, true)
7282#endif
7283
7284CLONE_TEST(clone_fs1, CLONE_FS, false, false, false)
7285#if defined(TWAIT_HAVE_PID)
7286CLONE_TEST(clone_fs2, CLONE_FS, true, false, false)
7287CLONE_TEST(clone_fs3, CLONE_FS, false, true, false)
7288CLONE_TEST(clone_fs4, CLONE_FS, true, true, false)
7289#endif
7290CLONE_TEST(clone_fs5, CLONE_FS, false, false, true)
7291#if defined(TWAIT_HAVE_PID)
7292CLONE_TEST(clone_fs6, CLONE_FS, true, false, true)
7293CLONE_TEST(clone_fs7, CLONE_FS, false, true, true)
7294CLONE_TEST(clone_fs8, CLONE_FS, true, true, true)
7295#endif
7296
7297CLONE_TEST(clone_files1, CLONE_FILES, false, false, false)
7298#if defined(TWAIT_HAVE_PID)
7299CLONE_TEST(clone_files2, CLONE_FILES, true, false, false)
7300CLONE_TEST(clone_files3, CLONE_FILES, false, true, false)
7301CLONE_TEST(clone_files4, CLONE_FILES, true, true, false)
7302#endif
7303CLONE_TEST(clone_files5, CLONE_FILES, false, false, true)
7304#if defined(TWAIT_HAVE_PID)
7305CLONE_TEST(clone_files6, CLONE_FILES, true, false, true)
7306CLONE_TEST(clone_files7, CLONE_FILES, false, true, true)
7307CLONE_TEST(clone_files8, CLONE_FILES, true, true, true)
7308#endif
7309
7310//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false)
7311#if defined(TWAIT_HAVE_PID)
7312//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false)
7313//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false)
7314//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false)
7315#endif
7316//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true)
7317#if defined(TWAIT_HAVE_PID)
7318//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true)
7319//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true)
7320//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true)
7321#endif
7322
7323CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false)
7324#if defined(TWAIT_HAVE_PID)
7325CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false)
7326CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false)
7327CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false)
7328#endif
7329CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true)
7330#if defined(TWAIT_HAVE_PID)
7331CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true)
7332CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true)
7333CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true)
7334#endif
7335
7336/// ----------------------------------------------------------------------------
7337
7338#if defined(TWAIT_HAVE_PID)
7339static void
7340clone_body2(int flags, bool masked, bool ignored)
7341{
7342	const int exitval = 5;
7343	const int exitval2 = 15;
7344	const int sigval = SIGSTOP;
7345	pid_t child, child2 = 0, wpid;
7346#if defined(TWAIT_HAVE_STATUS)
7347	int status;
7348#endif
7349	ptrace_state_t state;
7350	const int slen = sizeof(state);
7351	ptrace_event_t event;
7352	const int elen = sizeof(event);
7353	struct sigaction sa;
7354	struct ptrace_siginfo info;
7355	sigset_t intmask;
7356	struct kinfo_proc2 kp;
7357	size_t len = sizeof(kp);
7358
7359	int name[6];
7360	const size_t namelen = __arraycount(name);
7361	ki_sigset_t kp_sigmask;
7362	ki_sigset_t kp_sigignore;
7363
7364	const size_t stack_size = 1024 * 1024;
7365	void *stack, *stack_base;
7366
7367	stack = malloc(stack_size);
7368	ATF_REQUIRE(stack != NULL);
7369
7370#ifdef __MACHINE_STACK_GROWS_UP
7371	stack_base = stack;
7372#else
7373	stack_base = (char *)stack + stack_size;
7374#endif
7375
7376	SYSCALL_REQUIRE((child = fork()) != -1);
7377	if (child == 0) {
7378		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7379		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7380
7381		if (masked) {
7382			sigemptyset(&intmask);
7383			sigaddset(&intmask, SIGTRAP);
7384			sigprocmask(SIG_BLOCK, &intmask, NULL);
7385		}
7386
7387		if (ignored) {
7388			memset(&sa, 0, sizeof(sa));
7389			sa.sa_handler = SIG_IGN;
7390			sigemptyset(&sa.sa_mask);
7391			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
7392		}
7393		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7394		FORKEE_ASSERT(raise(sigval) == 0);
7395
7396		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7397		    flags);
7398		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7399		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7400
7401		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7402		    child2);
7403
7404		// XXX WALLSIG?
7405		FORKEE_REQUIRE_SUCCESS
7406		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7407
7408		forkee_status_exited(status, exitval2);
7409
7410		DPRINTF("Before exiting of the child process\n");
7411		_exit(exitval);
7412	}
7413	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7414
7415	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7416	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7417
7418	validate_status_stopped(status, sigval);
7419
7420	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
7421	SYSCALL_REQUIRE(
7422	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
7423
7424	DPRINTF("Before checking siginfo_t\n");
7425	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7426	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7427
7428	name[0] = CTL_KERN,
7429	name[1] = KERN_PROC2,
7430	name[2] = KERN_PROC_PID;
7431	name[3] = child;
7432	name[4] = sizeof(kp);
7433	name[5] = 1;
7434
7435	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7436
7437	if (masked)
7438		kp_sigmask = kp.p_sigmask;
7439
7440	if (ignored)
7441		kp_sigignore = kp.p_sigignore;
7442
7443	DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in "
7444	    "EVENT_MASK for the child %d\n", child);
7445	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE;
7446	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
7447
7448	DPRINTF("Before resuming the child process where it left off and "
7449	    "without signal to be sent\n");
7450	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7451
7452	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7453	    child);
7454	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
7455	    child);
7456
7457	validate_status_stopped(status, SIGTRAP);
7458
7459	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7460
7461	if (masked) {
7462		DPRINTF("kp_sigmask="
7463		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7464		    PRIx32 "\n",
7465		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7466		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7467
7468		DPRINTF("kp.p_sigmask="
7469		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7470		    PRIx32 "\n",
7471		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7472		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7473
7474		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7475		    sizeof(kp_sigmask)));
7476	}
7477
7478	if (ignored) {
7479		DPRINTF("kp_sigignore="
7480		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7481		    PRIx32 "\n",
7482		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7483		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7484
7485		DPRINTF("kp.p_sigignore="
7486		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7487		    PRIx32 "\n",
7488		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7489		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7490
7491		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7492		    sizeof(kp_sigignore)));
7493	}
7494
7495	SYSCALL_REQUIRE(
7496	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7497	DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event,
7498	    child2);
7499	if (!(flags & CLONE_VFORK)) {
7500		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7501		       PTRACE_FORK);
7502	} else {
7503		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7504		       PTRACE_VFORK);
7505	}
7506
7507	child2 = state.pe_other_pid;
7508	DPRINTF("Reported ptrace event with forkee %d\n", child2);
7509
7510	DPRINTF("Before calling %s() for the forkee %d of the child "
7511	    "%d\n", TWAIT_FNAME, child2, child);
7512	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
7513	    child2);
7514
7515	validate_status_stopped(status, SIGTRAP);
7516
7517	name[3] = child2;
7518	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7519
7520	if (masked) {
7521		DPRINTF("kp_sigmask="
7522		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7523		    PRIx32 "\n",
7524		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7525		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7526
7527		DPRINTF("kp.p_sigmask="
7528		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7529		    PRIx32 "\n",
7530		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7531		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7532
7533		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7534		    sizeof(kp_sigmask)));
7535	}
7536
7537	if (ignored) {
7538		DPRINTF("kp_sigignore="
7539		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7540		    PRIx32 "\n",
7541		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7542		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7543
7544		DPRINTF("kp.p_sigignore="
7545		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7546		    PRIx32 "\n",
7547		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7548		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7549
7550		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7551		    sizeof(kp_sigignore)));
7552	}
7553
7554	SYSCALL_REQUIRE(
7555	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
7556	if (!(flags & CLONE_VFORK)) {
7557		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7558		       PTRACE_FORK);
7559	} else {
7560		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7561		       PTRACE_VFORK);
7562	}
7563
7564	ATF_REQUIRE_EQ(state.pe_other_pid, child);
7565
7566	DPRINTF("Before resuming the forkee process where it left off "
7567	    "and without signal to be sent\n");
7568	SYSCALL_REQUIRE(
7569	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
7570
7571	DPRINTF("Before resuming the child process where it left off "
7572	    "and without signal to be sent\n");
7573	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7574
7575	if (flags & CLONE_VFORK) {
7576		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7577		    child);
7578		TWAIT_REQUIRE_SUCCESS(
7579		    wpid = TWAIT_GENERIC(child, &status, 0), child);
7580
7581		validate_status_stopped(status, SIGTRAP);
7582
7583		name[3] = child;
7584		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7585
7586		/*
7587		 * SIGCHLD is now pending in the signal queue and
7588		 * the kernel presents it to userland as a masked signal.
7589		 */
7590		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
7591
7592		if (masked) {
7593			DPRINTF("kp_sigmask="
7594			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7595			    PRIx32 "\n",
7596			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7597			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7598
7599			DPRINTF("kp.p_sigmask="
7600			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7601			    PRIx32 "\n",
7602			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7603			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7604
7605			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7606			    sizeof(kp_sigmask)));
7607		}
7608
7609		if (ignored) {
7610			DPRINTF("kp_sigignore="
7611			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7612			    PRIx32 "\n",
7613			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7614			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7615
7616			DPRINTF("kp.p_sigignore="
7617			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7618			    PRIx32 "\n",
7619			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7620			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7621
7622			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7623			    sizeof(kp_sigignore)));
7624		}
7625
7626		SYSCALL_REQUIRE(
7627		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7628		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
7629
7630		child2 = state.pe_other_pid;
7631		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
7632		    child2);
7633
7634		DPRINTF("Before resuming the child process where it left off "
7635		    "and without signal to be sent\n");
7636		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7637	}
7638
7639	DPRINTF("Before calling %s() for the forkee - expected exited"
7640	    "\n", TWAIT_FNAME);
7641	TWAIT_REQUIRE_SUCCESS(
7642	    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
7643
7644	validate_status_exited(status, exitval2);
7645
7646	DPRINTF("Before calling %s() for the forkee - expected no "
7647	    "process\n", TWAIT_FNAME);
7648	TWAIT_REQUIRE_FAILURE(ECHILD,
7649	    wpid = TWAIT_GENERIC(child2, &status, 0));
7650
7651	DPRINTF("Before calling %s() for the child - expected stopped "
7652	    "SIGCHLD\n", TWAIT_FNAME);
7653	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7654
7655	validate_status_stopped(status, SIGCHLD);
7656
7657	DPRINTF("Before resuming the child process where it left off and "
7658	    "without signal to be sent\n");
7659	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7660
7661	DPRINTF("Before calling %s() for the child - expected exited\n",
7662	    TWAIT_FNAME);
7663	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7664
7665	validate_status_exited(status, exitval);
7666
7667	DPRINTF("Before calling %s() for the child - expected no process\n",
7668	    TWAIT_FNAME);
7669	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7670}
7671
7672#define CLONE_TEST2(name,flags,masked,ignored)				\
7673ATF_TC(name);								\
7674ATF_TC_HEAD(name, tc)							\
7675{									\
7676	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\
7677	    " regardless of signal %s%s", 				\
7678	    #flags, masked ? "masked" : "", ignored ? "ignored" : "");	\
7679}									\
7680									\
7681ATF_TC_BODY(name, tc)							\
7682{									\
7683									\
7684	clone_body2(flags, masked, ignored);				\
7685}
7686
7687CLONE_TEST2(clone_signalignored, 0, true, false)
7688CLONE_TEST2(clone_signalmasked, 0, false, true)
7689CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false)
7690CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true)
7691CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false)
7692CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true)
7693CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false)
7694CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
7695//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
7696//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true)  // XXX
7697CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
7698CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
7699#endif
7700
7701/// ----------------------------------------------------------------------------
7702
7703#if defined(TWAIT_HAVE_PID)
7704static void
7705traceme_vfork_clone_body(int flags)
7706{
7707	const int exitval = 5;
7708	const int exitval2 = 15;
7709	pid_t child, child2 = 0, wpid;
7710#if defined(TWAIT_HAVE_STATUS)
7711	int status;
7712#endif
7713
7714	const size_t stack_size = 1024 * 1024;
7715	void *stack, *stack_base;
7716
7717	stack = malloc(stack_size);
7718	ATF_REQUIRE(stack != NULL);
7719
7720#ifdef __MACHINE_STACK_GROWS_UP
7721	stack_base = stack;
7722#else
7723	stack_base = (char *)stack + stack_size;
7724#endif
7725
7726	SYSCALL_REQUIRE((child = vfork()) != -1);
7727	if (child == 0) {
7728		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7729		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7730
7731		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7732		    flags);
7733		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7734		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7735
7736		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7737		    child2);
7738
7739		// XXX WALLSIG?
7740		FORKEE_REQUIRE_SUCCESS
7741		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7742
7743		forkee_status_exited(status, exitval2);
7744
7745		DPRINTF("Before exiting of the child process\n");
7746		_exit(exitval);
7747	}
7748	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7749
7750	DPRINTF("Before calling %s() for the child - expected exited\n",
7751	    TWAIT_FNAME);
7752	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7753
7754	validate_status_exited(status, exitval);
7755
7756	DPRINTF("Before calling %s() for the child - expected no process\n",
7757	    TWAIT_FNAME);
7758	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7759}
7760
7761#define TRACEME_VFORK_CLONE_TEST(name,flags)				\
7762ATF_TC(name);								\
7763ATF_TC_HEAD(name, tc)							\
7764{									\
7765	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is "	\
7766	    "handled correctly with vfork(2)ed tracer", 		\
7767	    #flags);							\
7768}									\
7769									\
7770ATF_TC_BODY(name, tc)							\
7771{									\
7772									\
7773	traceme_vfork_clone_body(flags);				\
7774}
7775
7776TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0)
7777TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM)
7778TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS)
7779TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES)
7780//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND)  // XXX
7781TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
7782#endif
7783
7784/// ----------------------------------------------------------------------------
7785
7786static void
7787user_va0_disable(int operation)
7788{
7789	pid_t child, wpid;
7790#if defined(TWAIT_HAVE_STATUS)
7791	int status;
7792#endif
7793	const int sigval = SIGSTOP;
7794	int rv;
7795
7796	struct ptrace_siginfo info;
7797
7798	if (get_user_va0_disable() == 0)
7799		atf_tc_skip("vm.user_va0_disable is set to 0");
7800
7801	memset(&info, 0, sizeof(info));
7802
7803	DPRINTF("Before forking process PID=%d\n", getpid());
7804	SYSCALL_REQUIRE((child = fork()) != -1);
7805	if (child == 0) {
7806		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7807		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7808
7809		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7810		FORKEE_ASSERT(raise(sigval) == 0);
7811
7812		/* NOTREACHED */
7813		FORKEE_ASSERTX(0 && "This shall not be reached");
7814		__unreachable();
7815	}
7816	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7817
7818	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7819	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7820
7821	validate_status_stopped(status, sigval);
7822
7823	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
7824		"child\n");
7825	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
7826		sizeof(info)) != -1);
7827
7828	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
7829	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
7830		"si_errno=%#x\n",
7831		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
7832		info.psi_siginfo.si_errno);
7833
7834	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7835	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7836
7837	DPRINTF("Before resuming the child process in PC=0x0 "
7838	    "and without signal to be sent\n");
7839	errno = 0;
7840	rv = ptrace(operation, child, (void *)0, 0);
7841	ATF_REQUIRE_EQ(errno, EINVAL);
7842	ATF_REQUIRE_EQ(rv, -1);
7843
7844	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
7845
7846	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7847	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7848	validate_status_signaled(status, SIGKILL, 0);
7849
7850	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7851	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7852}
7853
7854#define USER_VA0_DISABLE(test, operation)				\
7855ATF_TC(test);								\
7856ATF_TC_HEAD(test, tc)							\
7857{									\
7858	atf_tc_set_md_var(tc, "descr",					\
7859	    "Verify behavior of " #operation " with PC set to 0x0");	\
7860}									\
7861									\
7862ATF_TC_BODY(test, tc)							\
7863{									\
7864									\
7865	user_va0_disable(operation);					\
7866}
7867
7868USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
7869USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
7870USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
7871
7872/// ----------------------------------------------------------------------------
7873
7874/*
7875 * Parse the core file and find the requested note.  If the reading or parsing
7876 * fails, the test is failed.  If the note is found, it is read onto buf, up to
7877 * buf_len.  The actual length of the note is returned (which can be greater
7878 * than buf_len, indicating that it has been truncated).  If the note is not
7879 * found, -1 is returned.
7880 *
7881 * If the note_name ends in '*', then we find the first note that matches
7882 * the note_name prefix up to the '*' character, e.g.:
7883 *
7884 *	NetBSD-CORE@*
7885 *
7886 * finds the first note whose name prefix matches "NetBSD-CORE@".
7887 */
7888static ssize_t core_find_note(const char *core_path,
7889    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
7890{
7891	int core_fd;
7892	Elf *core_elf;
7893	size_t core_numhdr, i;
7894	ssize_t ret = -1;
7895	size_t name_len = strlen(note_name);
7896	bool prefix_match = false;
7897
7898	if (note_name[name_len - 1] == '*') {
7899		prefix_match = true;
7900		name_len--;
7901	} else {
7902		/* note: we assume note name will be null-terminated */
7903		name_len++;
7904	}
7905
7906	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
7907	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
7908	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
7909
7910	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
7911	for (i = 0; i < core_numhdr && ret == -1; i++) {
7912		GElf_Phdr core_hdr;
7913		size_t offset;
7914		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
7915		if (core_hdr.p_type != PT_NOTE)
7916		    continue;
7917
7918		for (offset = core_hdr.p_offset;
7919		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
7920			Elf64_Nhdr note_hdr;
7921			char name_buf[64];
7922
7923			switch (gelf_getclass(core_elf)) {
7924			case ELFCLASS64:
7925				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
7926				    sizeof(note_hdr), offset)
7927				    == sizeof(note_hdr));
7928				offset += sizeof(note_hdr);
7929				break;
7930			case ELFCLASS32:
7931				{
7932				Elf32_Nhdr tmp_hdr;
7933				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
7934				    sizeof(tmp_hdr), offset)
7935				    == sizeof(tmp_hdr));
7936				offset += sizeof(tmp_hdr);
7937				note_hdr.n_namesz = tmp_hdr.n_namesz;
7938				note_hdr.n_descsz = tmp_hdr.n_descsz;
7939				note_hdr.n_type = tmp_hdr.n_type;
7940				}
7941				break;
7942			}
7943
7944			/* indicates end of notes */
7945			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
7946				break;
7947			if (((prefix_match &&
7948			      note_hdr.n_namesz > name_len) ||
7949			     (!prefix_match &&
7950			      note_hdr.n_namesz == name_len)) &&
7951			    note_hdr.n_namesz <= sizeof(name_buf)) {
7952				SYSCALL_REQUIRE(pread(core_fd, name_buf,
7953				    note_hdr.n_namesz, offset)
7954				    == (ssize_t)(size_t)note_hdr.n_namesz);
7955
7956				if (!strncmp(note_name, name_buf, name_len) &&
7957				    note_hdr.n_type == note_type)
7958					ret = note_hdr.n_descsz;
7959			}
7960
7961			offset += note_hdr.n_namesz;
7962			/* fix to alignment */
7963			offset = roundup(offset, core_hdr.p_align);
7964
7965			/* if name & type matched above */
7966			if (ret != -1) {
7967				ssize_t read_len = MIN(buf_len,
7968				    note_hdr.n_descsz);
7969				SYSCALL_REQUIRE(pread(core_fd, buf,
7970				    read_len, offset) == read_len);
7971				break;
7972			}
7973
7974			offset += note_hdr.n_descsz;
7975			/* fix to alignment */
7976			offset = roundup(offset, core_hdr.p_align);
7977		}
7978	}
7979
7980	elf_end(core_elf);
7981	close(core_fd);
7982
7983	return ret;
7984}
7985
7986ATF_TC(core_dump_procinfo);
7987ATF_TC_HEAD(core_dump_procinfo, tc)
7988{
7989	atf_tc_set_md_var(tc, "descr",
7990		"Trigger a core dump and verify its contents.");
7991}
7992
7993ATF_TC_BODY(core_dump_procinfo, tc)
7994{
7995	const int exitval = 5;
7996	pid_t child, wpid;
7997#if defined(TWAIT_HAVE_STATUS)
7998	const int sigval = SIGTRAP;
7999	int status;
8000#endif
8001	char core_path[] = "/tmp/core.XXXXXX";
8002	int core_fd;
8003	struct netbsd_elfcore_procinfo procinfo;
8004
8005	DPRINTF("Before forking process PID=%d\n", getpid());
8006	SYSCALL_REQUIRE((child = fork()) != -1);
8007	if (child == 0) {
8008		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
8009		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
8010
8011		DPRINTF("Before triggering SIGTRAP\n");
8012		trigger_trap();
8013
8014		DPRINTF("Before exiting of the child process\n");
8015		_exit(exitval);
8016	}
8017	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
8018
8019	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8020	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8021
8022	validate_status_stopped(status, sigval);
8023
8024	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
8025	close(core_fd);
8026
8027	DPRINTF("Call DUMPCORE for the child process\n");
8028	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
8029	    != -1);
8030
8031	DPRINTF("Read core file\n");
8032	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
8033	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
8034	    sizeof(procinfo));
8035
8036	ATF_CHECK_EQ(procinfo.cpi_version, 1);
8037	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
8038	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
8039	ATF_CHECK_EQ(procinfo.cpi_pid, child);
8040	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
8041	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
8042	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
8043	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
8044	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
8045	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
8046	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
8047	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
8048	ATF_CHECK(procinfo.cpi_siglwp > 0);
8049
8050	unlink(core_path);
8051
8052	DPRINTF("Before resuming the child process where it left off and "
8053	    "without signal to be sent\n");
8054	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
8055
8056	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8057	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8058
8059	validate_status_exited(status, exitval);
8060
8061	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8062	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
8063}
8064
8065/// ----------------------------------------------------------------------------
8066
8067#if defined(TWAIT_HAVE_STATUS)
8068
8069#define THREAD_CONCURRENT_BREAKPOINT_NUM 50
8070#define THREAD_CONCURRENT_SIGNALS_NUM 50
8071#define THREAD_CONCURRENT_WATCHPOINT_NUM 50
8072
8073/* List of signals to use for the test */
8074const int thread_concurrent_signals_list[] = {
8075	SIGIO,
8076	SIGXCPU,
8077	SIGXFSZ,
8078	SIGVTALRM,
8079	SIGPROF,
8080	SIGWINCH,
8081	SIGINFO,
8082	SIGUSR1,
8083	SIGUSR2
8084};
8085
8086enum thread_concurrent_signal_handling {
8087	/* the signal is discarded by debugger */
8088	TCSH_DISCARD,
8089	/* the handler is set to SIG_IGN */
8090	TCSH_SIG_IGN,
8091	/* an actual handler is used */
8092	TCSH_HANDLER
8093};
8094
8095static pthread_barrier_t thread_concurrent_barrier;
8096static pthread_key_t thread_concurrent_key;
8097static uint32_t thread_concurrent_watchpoint_var = 0;
8098
8099static void *
8100thread_concurrent_breakpoint_thread(void *arg)
8101{
8102	static volatile int watchme = 1;
8103	pthread_barrier_wait(&thread_concurrent_barrier);
8104	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
8105	check_happy(watchme);
8106	return NULL;
8107}
8108
8109static void
8110thread_concurrent_sig_handler(int sig)
8111{
8112	void *tls_val = pthread_getspecific(thread_concurrent_key);
8113	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
8114	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
8115	    (void*)((uintptr_t)tls_val + 1)) == 0);
8116}
8117
8118static void *
8119thread_concurrent_signals_thread(void *arg)
8120{
8121	int sigval = thread_concurrent_signals_list[
8122	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
8123	enum thread_concurrent_signal_handling *signal_handle = arg;
8124	void *tls_val;
8125
8126	pthread_barrier_wait(&thread_concurrent_barrier);
8127	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
8128		_lwp_self());
8129	pthread_kill(pthread_self(), sigval);
8130	if (*signal_handle == TCSH_HANDLER) {
8131	    tls_val = pthread_getspecific(thread_concurrent_key);
8132	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
8133	    FORKEE_ASSERT(tls_val == (void*)1);
8134	}
8135	return NULL;
8136}
8137
8138static void *
8139thread_concurrent_watchpoint_thread(void *arg)
8140{
8141	pthread_barrier_wait(&thread_concurrent_barrier);
8142	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
8143	thread_concurrent_watchpoint_var = 1;
8144	return NULL;
8145}
8146
8147#if defined(__i386__) || defined(__x86_64__)
8148enum thread_concurrent_sigtrap_event {
8149	TCSE_UNKNOWN,
8150	TCSE_BREAKPOINT,
8151	TCSE_WATCHPOINT
8152};
8153
8154static void
8155thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
8156static enum thread_concurrent_sigtrap_event
8157thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
8158#endif
8159
8160static void
8161thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
8162    int breakpoint_threads, int signal_threads, int watchpoint_threads)
8163{
8164	const int exitval = 5;
8165	const int sigval = SIGSTOP;
8166	pid_t child, wpid;
8167	int status;
8168	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
8169	    = {{0, 0}};
8170	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
8171	    = {{0, 0}};
8172	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
8173	    = {{0, 0}};
8174	ptrace_event_t event;
8175	int i;
8176
8177#if defined(HAVE_DBREGS)
8178	if (!can_we_set_dbregs()) {
8179		atf_tc_skip("Either run this test as root or set sysctl(3) "
8180		            "security.models.extensions.user_set_dbregs to 1");
8181        }
8182#endif
8183
8184	atf_tc_skip("PR kern/54960");
8185
8186	/* Protect against out-of-bounds array access. */
8187	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
8188	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
8189	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
8190
8191	DPRINTF("Before forking process PID=%d\n", getpid());
8192	SYSCALL_REQUIRE((child = fork()) != -1);
8193	if (child == 0) {
8194		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
8195		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
8196		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
8197
8198		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
8199		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
8200
8201		DPRINTF("Before raising %s from child\n", strsignal(sigval));
8202		FORKEE_ASSERT(raise(sigval) == 0);
8203
8204		if (signal_handle != TCSH_DISCARD) {
8205			struct sigaction sa;
8206			unsigned int j;
8207
8208			memset(&sa, 0, sizeof(sa));
8209			if (signal_handle == TCSH_SIG_IGN)
8210				sa.sa_handler = SIG_IGN;
8211			else
8212				sa.sa_handler = thread_concurrent_sig_handler;
8213			sigemptyset(&sa.sa_mask);
8214
8215			for (j = 0;
8216			    j < __arraycount(thread_concurrent_signals_list);
8217			    j++)
8218				FORKEE_ASSERT(sigaction(
8219				    thread_concurrent_signals_list[j], &sa, NULL)
8220				    != -1);
8221		}
8222
8223		DPRINTF("Before starting threads from the child\n");
8224		FORKEE_ASSERT(pthread_barrier_init(
8225		    &thread_concurrent_barrier, NULL,
8226		    breakpoint_threads + signal_threads + watchpoint_threads)
8227		    == 0);
8228		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
8229		    == 0);
8230
8231		for (i = 0; i < signal_threads; i++) {
8232			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
8233			    thread_concurrent_signals_thread,
8234			    &signal_handle) == 0);
8235		}
8236		for (i = 0; i < breakpoint_threads; i++) {
8237			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
8238			    thread_concurrent_breakpoint_thread, NULL) == 0);
8239		}
8240		for (i = 0; i < watchpoint_threads; i++) {
8241			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
8242			    thread_concurrent_watchpoint_thread, NULL) == 0);
8243		}
8244
8245		DPRINTF("Before joining threads from the child\n");
8246		for (i = 0; i < watchpoint_threads; i++) {
8247			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
8248		}
8249		for (i = 0; i < breakpoint_threads; i++) {
8250			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
8251		}
8252		for (i = 0; i < signal_threads; i++) {
8253			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
8254		}
8255
8256		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
8257		FORKEE_ASSERT(pthread_barrier_destroy(
8258		    &thread_concurrent_barrier) == 0);
8259
8260		DPRINTF("Before exiting of the child process\n");
8261		_exit(exitval);
8262	}
8263	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
8264
8265	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8266	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8267
8268	validate_status_stopped(status, sigval);
8269
8270	DPRINTF("Set LWP event mask for the child process\n");
8271	memset(&event, 0, sizeof(event));
8272	event.pe_set_event |= PTRACE_LWP_CREATE;
8273	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
8274	    != -1);
8275
8276	DPRINTF("Before resuming the child process where it left off\n");
8277	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
8278
8279	DPRINTF("Before entering signal collection loop\n");
8280	while (1) {
8281		ptrace_siginfo_t info;
8282
8283		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8284		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
8285		    child);
8286		if (WIFEXITED(status))
8287			break;
8288		/* Note: we use validate_status_stopped() to get nice error
8289		 * message.  Signal is irrelevant since it won't be reached.
8290		 */
8291		else if (!WIFSTOPPED(status))
8292			validate_status_stopped(status, 0);
8293
8294		DPRINTF("Before calling PT_GET_SIGINFO\n");
8295		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
8296		    sizeof(info)) != -1);
8297
8298		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
8299		    info.psi_siginfo.si_signo, info.psi_lwpid,
8300		    WSTOPSIG(status));
8301
8302		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
8303		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
8304		    WSTOPSIG(status), info.psi_siginfo.si_signo);
8305
8306		if (WSTOPSIG(status) != SIGTRAP) {
8307			int expected_sig =
8308			    thread_concurrent_signals_list[info.psi_lwpid %
8309			    __arraycount(thread_concurrent_signals_list)];
8310			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
8311				"lwp=%d, expected %d, got %d", info.psi_lwpid,
8312				expected_sig, WSTOPSIG(status));
8313
8314			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
8315		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
8316#if defined(__i386__) || defined(__x86_64__)
8317			thread_concurrent_lwp_setup(child, info.psi_lwpid);
8318#endif
8319		} else {
8320#if defined(__i386__) || defined(__x86_64__)
8321			switch (thread_concurrent_handle_sigtrap(child, &info)) {
8322				case TCSE_UNKNOWN:
8323					/* already reported inside the function */
8324					break;
8325				case TCSE_BREAKPOINT:
8326					*FIND_EVENT_COUNT(bp_counts,
8327					    info.psi_lwpid) += 1;
8328					break;
8329				case TCSE_WATCHPOINT:
8330					*FIND_EVENT_COUNT(wp_counts,
8331					    info.psi_lwpid) += 1;
8332					break;
8333			}
8334#else
8335			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
8336			    info.psi_siginfo.si_code);
8337#endif
8338		}
8339
8340		DPRINTF("Before resuming the child process\n");
8341		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
8342		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
8343		     ? WSTOPSIG(status) : 0) != -1);
8344	}
8345
8346	for (i = 0; i < signal_threads; i++)
8347		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
8348		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
8349		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
8350	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
8351		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
8352		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
8353		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
8354
8355	for (i = 0; i < breakpoint_threads; i++)
8356		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
8357		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
8358		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
8359	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
8360		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
8361		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
8362		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
8363
8364	for (i = 0; i < watchpoint_threads; i++)
8365		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
8366		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
8367		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
8368	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
8369		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
8370		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
8371		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
8372
8373	validate_status_exited(status, exitval);
8374}
8375
8376#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
8377ATF_TC(test);								\
8378ATF_TC_HEAD(test, tc)							\
8379{									\
8380	atf_tc_set_md_var(tc, "descr", descr);				\
8381}									\
8382									\
8383ATF_TC_BODY(test, tc)							\
8384{									\
8385	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
8386}
8387
8388THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
8389    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8390    "Verify that concurrent signals issued to a single thread are reported "
8391    "correctly");
8392THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
8393    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8394    "Verify that concurrent signals issued to a single thread are reported "
8395    "correctly and passed back to SIG_IGN handler");
8396THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
8397    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8398    "Verify that concurrent signals issued to a single thread are reported "
8399    "correctly and passed back to a handler function");
8400
8401#if defined(__i386__) || defined(__x86_64__)
8402THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
8403    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
8404    "Verify that concurrent breakpoints are reported correctly");
8405THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
8406    0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
8407    "Verify that concurrent breakpoints are reported correctly");
8408THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
8409    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
8410    "Verify that concurrent breakpoints and watchpoints are reported "
8411    "correctly");
8412
8413THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
8414    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8415    "Verify that concurrent breakpoints and signals are reported correctly");
8416THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
8417    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8418    "Verify that concurrent breakpoints and signals are reported correctly "
8419    "and passed back to SIG_IGN handler");
8420THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
8421    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8422    "Verify that concurrent breakpoints and signals are reported correctly "
8423    "and passed back to a handler function");
8424
8425THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
8426    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8427    "Verify that concurrent watchpoints and signals are reported correctly");
8428THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
8429    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8430    "Verify that concurrent watchpoints and signals are reported correctly "
8431    "and passed back to SIG_IGN handler");
8432THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
8433    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8434    "Verify that concurrent watchpoints and signals are reported correctly "
8435    "and passed back to a handler function");
8436
8437THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
8438    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8439    THREAD_CONCURRENT_WATCHPOINT_NUM,
8440    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8441    "correctly");
8442THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
8443    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8444    THREAD_CONCURRENT_WATCHPOINT_NUM,
8445    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8446    "correctly and passed back to SIG_IGN handler");
8447THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
8448    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8449    THREAD_CONCURRENT_WATCHPOINT_NUM,
8450    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8451    "correctly and passed back to a handler function");
8452#endif
8453
8454#endif /*defined(TWAIT_HAVE_STATUS)*/
8455
8456/// ----------------------------------------------------------------------------
8457
8458#include "t_ptrace_register_wait.h"
8459#include "t_ptrace_syscall_wait.h"
8460#include "t_ptrace_step_wait.h"
8461
8462/// ----------------------------------------------------------------------------
8463
8464#include "t_ptrace_amd64_wait.h"
8465#include "t_ptrace_i386_wait.h"
8466#include "t_ptrace_x86_wait.h"
8467
8468/// ----------------------------------------------------------------------------
8469
8470#else
8471ATF_TC(dummy);
8472ATF_TC_HEAD(dummy, tc)
8473{
8474	atf_tc_set_md_var(tc, "descr", "A dummy test");
8475}
8476
8477ATF_TC_BODY(dummy, tc)
8478{
8479
8480	// Dummy, skipped
8481	// The ATF framework requires at least a single defined test.
8482}
8483#endif
8484
8485ATF_TP_ADD_TCS(tp)
8486{
8487	setvbuf(stdout, NULL, _IONBF, 0);
8488	setvbuf(stderr, NULL, _IONBF, 0);
8489
8490#ifdef ENABLE_TESTS
8491	ATF_TP_ADD_TC(tp, traceme_raise1);
8492	ATF_TP_ADD_TC(tp, traceme_raise2);
8493	ATF_TP_ADD_TC(tp, traceme_raise3);
8494	ATF_TP_ADD_TC(tp, traceme_raise4);
8495	ATF_TP_ADD_TC(tp, traceme_raise5);
8496	ATF_TP_ADD_TC(tp, traceme_raise6);
8497	ATF_TP_ADD_TC(tp, traceme_raise7);
8498	ATF_TP_ADD_TC(tp, traceme_raise8);
8499	ATF_TP_ADD_TC(tp, traceme_raise9);
8500	ATF_TP_ADD_TC(tp, traceme_raise10);
8501
8502	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
8503	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
8504	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
8505	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
8506	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
8507	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
8508	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
8509	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
8510
8511	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
8512	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
8513	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
8514	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
8515	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
8516	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
8517	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
8518	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
8519
8520	ATF_TP_ADD_TC(tp, traceme_crash_trap);
8521	ATF_TP_ADD_TC(tp, traceme_crash_segv);
8522	ATF_TP_ADD_TC(tp, traceme_crash_ill);
8523	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
8524	ATF_TP_ADD_TC(tp, traceme_crash_bus);
8525
8526	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
8527	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
8528	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
8529	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
8530	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
8531
8532	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
8533	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
8534	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
8535	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
8536	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
8537
8538	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
8539	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
8540	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
8541	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
8542	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
8543	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
8544	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
8545	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
8546
8547	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
8548	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
8549	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
8550	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
8551	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
8552	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
8553	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
8554	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
8555
8556	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
8557	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
8558	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
8559	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
8560	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
8561	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
8562	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
8563	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
8564
8565	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
8566	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
8567	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
8568	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
8569	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
8570	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
8571	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
8572	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
8573	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
8574	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
8575
8576	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
8577
8578	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
8579	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
8580	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
8581	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
8582	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
8583	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
8584	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
8585	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
8586	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
8587	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
8588	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
8589	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
8590	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
8591
8592	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
8593	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
8594	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
8595	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
8596	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
8597
8598	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
8599	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
8600	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
8601	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
8602	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
8603
8604	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
8605	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
8606	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
8607	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
8608	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
8609
8610	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
8611	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
8612	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
8613
8614	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
8615	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
8616	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
8617	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
8618	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
8619
8620	ATF_TP_ADD_TC_HAVE_PID(tp,
8621	    unrelated_tracer_sees_signalmasked_crash_trap);
8622	ATF_TP_ADD_TC_HAVE_PID(tp,
8623	    unrelated_tracer_sees_signalmasked_crash_segv);
8624	ATF_TP_ADD_TC_HAVE_PID(tp,
8625	    unrelated_tracer_sees_signalmasked_crash_ill);
8626	ATF_TP_ADD_TC_HAVE_PID(tp,
8627	    unrelated_tracer_sees_signalmasked_crash_fpe);
8628	ATF_TP_ADD_TC_HAVE_PID(tp,
8629	    unrelated_tracer_sees_signalmasked_crash_bus);
8630
8631	ATF_TP_ADD_TC_HAVE_PID(tp,
8632	    unrelated_tracer_sees_signalignored_crash_trap);
8633	ATF_TP_ADD_TC_HAVE_PID(tp,
8634	    unrelated_tracer_sees_signalignored_crash_segv);
8635	ATF_TP_ADD_TC_HAVE_PID(tp,
8636	    unrelated_tracer_sees_signalignored_crash_ill);
8637	ATF_TP_ADD_TC_HAVE_PID(tp,
8638	    unrelated_tracer_sees_signalignored_crash_fpe);
8639	ATF_TP_ADD_TC_HAVE_PID(tp,
8640	    unrelated_tracer_sees_signalignored_crash_bus);
8641
8642	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
8643	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
8644	ATF_TP_ADD_TC_HAVE_PID(tp,
8645		unrelated_tracer_sees_terminaton_before_the_parent);
8646	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
8647
8648	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
8649	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
8650
8651	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
8652	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
8653
8654	ATF_TP_ADD_TC_HAVE_PID(tp,
8655		tracee_sees_its_original_parent_getppid);
8656	ATF_TP_ADD_TC_HAVE_PID(tp,
8657		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
8658	ATF_TP_ADD_TC_HAVE_PID(tp,
8659		tracee_sees_its_original_parent_procfs_status);
8660
8661	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
8662	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
8663	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
8664	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
8665	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
8666	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
8667	ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn);
8668
8669	ATF_TP_ADD_TC(tp, fork1);
8670	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
8671	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
8672	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
8673	ATF_TP_ADD_TC(tp, fork5);
8674	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
8675	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
8676	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
8677	ATF_TP_ADD_TC(tp, fork9);
8678	ATF_TP_ADD_TC_HAVE_PID(tp, fork10);
8679	ATF_TP_ADD_TC_HAVE_PID(tp, fork11);
8680	ATF_TP_ADD_TC_HAVE_PID(tp, fork12);
8681	ATF_TP_ADD_TC(tp, fork13);
8682	ATF_TP_ADD_TC_HAVE_PID(tp, fork14);
8683	ATF_TP_ADD_TC_HAVE_PID(tp, fork15);
8684	ATF_TP_ADD_TC_HAVE_PID(tp, fork16);
8685
8686	ATF_TP_ADD_TC(tp, vfork1);
8687	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
8688	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
8689	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
8690	ATF_TP_ADD_TC(tp, vfork5);
8691	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
8692	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
8693	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
8694	ATF_TP_ADD_TC(tp, vfork9);
8695	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10);
8696	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11);
8697	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12);
8698	ATF_TP_ADD_TC(tp, vfork13);
8699	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14);
8700	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15);
8701	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16);
8702
8703	ATF_TP_ADD_TC(tp, posix_spawn1);
8704	ATF_TP_ADD_TC(tp, posix_spawn2);
8705	ATF_TP_ADD_TC(tp, posix_spawn3);
8706	ATF_TP_ADD_TC(tp, posix_spawn4);
8707	ATF_TP_ADD_TC(tp, posix_spawn5);
8708	ATF_TP_ADD_TC(tp, posix_spawn6);
8709	ATF_TP_ADD_TC(tp, posix_spawn7);
8710	ATF_TP_ADD_TC(tp, posix_spawn8);
8711	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9);
8712	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10);
8713	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11);
8714	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12);
8715	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13);
8716	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14);
8717	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15);
8718	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16);
8719
8720	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1);
8721	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2);
8722	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3);
8723	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4);
8724	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5);
8725	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6);
8726	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7);
8727	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8);
8728	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9);
8729	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10);
8730	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11);
8731	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12);
8732	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13);
8733	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14);
8734	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15);
8735	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16);
8736
8737	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1);
8738	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2);
8739	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3);
8740	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4);
8741	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5);
8742	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6);
8743	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7);
8744	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8);
8745	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9);
8746	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10);
8747	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11);
8748	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12);
8749	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13);
8750	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14);
8751	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15);
8752	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16);
8753
8754	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1);
8755	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2);
8756	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3);
8757	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4);
8758	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5);
8759	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6);
8760	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7);
8761	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8);
8762	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9);
8763	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10);
8764	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11);
8765	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12);
8766	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13);
8767	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14);
8768	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15);
8769	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16);
8770
8771	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner);
8772	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker);
8773	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker);
8774	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone);
8775
8776	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner);
8777	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker);
8778	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker);
8779	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone);
8780
8781	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner);
8782	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker);
8783	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker);
8784	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone);
8785
8786	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner);
8787	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker);
8788	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker);
8789	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone);
8790
8791	ATF_TP_ADD_TC(tp, traceme_vfork_fork);
8792	ATF_TP_ADD_TC(tp, traceme_vfork_vfork);
8793
8794	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
8795	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
8796	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
8797	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
8798
8799	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
8800	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
8801	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
8802	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
8803
8804	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
8805	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
8806	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
8807	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
8808
8809	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
8810	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
8811	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
8812	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
8813
8814	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
8815	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
8816	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
8817	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
8818
8819	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
8820	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
8821	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
8822	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
8823
8824	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
8825	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
8826	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
8827	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
8828
8829	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
8830	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
8831	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
8832	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
8833
8834	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
8835	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
8836	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
8837	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
8838
8839	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
8840	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
8841	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
8842	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
8843
8844	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
8845
8846	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i);
8847	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d);
8848	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i);
8849	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d);
8850
8851	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i);
8852	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d);
8853	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i);
8854	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d);
8855
8856	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv);
8857
8858	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i);
8859	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d);
8860	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i);
8861	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d);
8862
8863	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i);
8864	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d);
8865	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i);
8866	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);
8867
8868	ATF_TP_ADD_TC(tp, kill1);
8869	ATF_TP_ADD_TC(tp, kill2);
8870	ATF_TP_ADD_TC(tp, kill3);
8871
8872	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
8873	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
8874	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
8875	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
8876
8877	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus);
8878	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus);
8879	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus);
8880	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus);
8881
8882	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask);
8883	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask);
8884	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask);
8885	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask);
8886
8887	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name);
8888	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name);
8889	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name);
8890	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name);
8891
8892	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private);
8893	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private);
8894	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private);
8895	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private);
8896
8897	ATF_TP_ADD_TC(tp, traceme_lwpnext0);
8898	ATF_TP_ADD_TC(tp, traceme_lwpnext1);
8899	ATF_TP_ADD_TC(tp, traceme_lwpnext2);
8900	ATF_TP_ADD_TC(tp, traceme_lwpnext3);
8901
8902	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask);
8903	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask);
8904	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask);
8905	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask);
8906
8907	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name);
8908	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name);
8909	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name);
8910	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name);
8911
8912	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private);
8913	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private);
8914	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private);
8915	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private);
8916
8917	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
8918	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
8919	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
8920	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
8921
8922	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
8923	ATF_TP_ADD_TC(tp, siginfo_set_faked);
8924
8925	ATF_TP_ADD_TC(tp, traceme_exec);
8926	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
8927	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
8928
8929	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
8930	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
8931	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
8932	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
8933
8934	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap);
8935	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap);
8936	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap);
8937
8938	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
8939
8940	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked);
8941	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored);
8942	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked);
8943	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored);
8944	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked);
8945	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored);
8946	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked);
8947	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored);
8948
8949	ATF_TP_ADD_TC(tp, threads_and_exec);
8950
8951	ATF_TP_ADD_TC(tp, suspend_no_deadlock);
8952
8953	ATF_TP_ADD_TC(tp, resume);
8954
8955	ATF_TP_ADD_TC(tp, clone1);
8956	ATF_TP_ADD_TC_HAVE_PID(tp, clone2);
8957	ATF_TP_ADD_TC_HAVE_PID(tp, clone3);
8958	ATF_TP_ADD_TC_HAVE_PID(tp, clone4);
8959	ATF_TP_ADD_TC(tp, clone5);
8960	ATF_TP_ADD_TC_HAVE_PID(tp, clone6);
8961	ATF_TP_ADD_TC_HAVE_PID(tp, clone7);
8962	ATF_TP_ADD_TC_HAVE_PID(tp, clone8);
8963
8964	ATF_TP_ADD_TC(tp, clone_vm1);
8965	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2);
8966	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3);
8967	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4);
8968	ATF_TP_ADD_TC(tp, clone_vm5);
8969	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6);
8970	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7);
8971	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8);
8972
8973	ATF_TP_ADD_TC(tp, clone_fs1);
8974	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2);
8975	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3);
8976	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4);
8977	ATF_TP_ADD_TC(tp, clone_fs5);
8978	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6);
8979	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7);
8980	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8);
8981
8982	ATF_TP_ADD_TC(tp, clone_files1);
8983	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2);
8984	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3);
8985	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4);
8986	ATF_TP_ADD_TC(tp, clone_files5);
8987	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6);
8988	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7);
8989	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8);
8990
8991//	ATF_TP_ADD_TC(tp, clone_sighand1); // XXX
8992//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX
8993//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX
8994//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX
8995//	ATF_TP_ADD_TC(tp, clone_sighand5); // XXX
8996//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX
8997//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
8998//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
8999
9000	ATF_TP_ADD_TC(tp, clone_vfork1);
9001	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2);
9002	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3);
9003	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4);
9004	ATF_TP_ADD_TC(tp, clone_vfork5);
9005	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6);
9006	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7);
9007	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8);
9008
9009	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored);
9010	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked);
9011	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored);
9012	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked);
9013	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored);
9014	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked);
9015	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored);
9016	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked);
9017//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
9018//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
9019	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored);
9020	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked);
9021
9022	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone);
9023	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm);
9024	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs);
9025	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files);
9026//	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
9027	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
9028
9029	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
9030	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
9031	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
9032
9033	ATF_TP_ADD_TC(tp, core_dump_procinfo);
9034
9035#if defined(TWAIT_HAVE_STATUS)
9036	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
9037	ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign);
9038	ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler);
9039#if defined(__i386__) || defined(__x86_64__)
9040	ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints);
9041	ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints);
9042	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp);
9043	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig);
9044	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign);
9045	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler);
9046	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig);
9047	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign);
9048	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler);
9049	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig);
9050	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign);
9051	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler);
9052#endif
9053#endif
9054
9055	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
9056	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
9057	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
9058
9059	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
9060	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
9061	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
9062
9063#else
9064	ATF_TP_ADD_TC(tp, dummy);
9065#endif
9066
9067	return atf_no_error();
9068}
9069