t_ptrace_wait.c revision 1.177
1/*	$NetBSD: t_ptrace_wait.c,v 1.177 2020/05/04 21:55:12 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.177 2020/05/04 21:55:12 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 int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
5018
5019static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
5020static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER;
5021static volatile size_t lwpinfo_thread_done;
5022
5023static void *
5024lwpinfo_thread(void *arg)
5025{
5026	sigset_t s;
5027	volatile void **tcb;
5028
5029	tcb = (volatile void **)arg;
5030
5031	*tcb = _lwp_getprivate();
5032	DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self());
5033
5034	pthread_setname_np(pthread_self(), "thread %d",
5035	    (void *)(intptr_t)_lwp_self());
5036
5037	sigemptyset(&s);
5038	pthread_mutex_lock(&lwpinfo_thread_mtx);
5039	sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
5040	lwpinfo_thread_done++;
5041	pthread_sigmask(SIG_BLOCK, &s, NULL);
5042	pthread_cond_signal(&lwpinfo_thread_cnd);
5043	pthread_mutex_unlock(&lwpinfo_thread_mtx);
5044
5045	return infinite_thread(NULL);
5046}
5047
5048static void
5049traceme_lwpinfo(const size_t threads, const char *iter)
5050{
5051	const int sigval = SIGSTOP;
5052	const int sigval2 = SIGINT;
5053	pid_t child, wpid;
5054#if defined(TWAIT_HAVE_STATUS)
5055	int status;
5056#endif
5057	struct ptrace_lwpinfo lwp = {0, 0};
5058	struct ptrace_lwpstatus lwpstatus = {0};
5059	struct ptrace_siginfo info;
5060	void *private;
5061	char *name;
5062	char namebuf[PL_LNAMELEN];
5063	volatile void *tcb[4];
5064	bool found;
5065	sigset_t s;
5066
5067	/* Maximum number of supported threads in this test */
5068	pthread_t t[__arraycount(tcb) - 1];
5069	size_t n, m;
5070	int rv;
5071	size_t bytes_read;
5072
5073	struct ptrace_io_desc io;
5074	sigset_t sigmask;
5075
5076	ATF_REQUIRE(__arraycount(t) >= threads);
5077	memset(tcb, 0, sizeof(tcb));
5078
5079	DPRINTF("Before forking process PID=%d\n", getpid());
5080	SYSCALL_REQUIRE((child = fork()) != -1);
5081	if (child == 0) {
5082		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5083		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5084
5085		tcb[0] = _lwp_getprivate();
5086		DPRINTF("Storing tcb[0] = %p\n", tcb[0]);
5087
5088		pthread_setname_np(pthread_self(), "thread %d",
5089		    (void *)(intptr_t)_lwp_self());
5090
5091		sigemptyset(&s);
5092		sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
5093		pthread_sigmask(SIG_BLOCK, &s, NULL);
5094
5095		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5096		FORKEE_ASSERT(raise(sigval) == 0);
5097
5098		for (n = 0; n < threads; n++) {
5099			rv = pthread_create(&t[n], NULL, lwpinfo_thread,
5100			    &tcb[n + 1]);
5101			FORKEE_ASSERT(rv == 0);
5102		}
5103
5104		pthread_mutex_lock(&lwpinfo_thread_mtx);
5105		while (lwpinfo_thread_done < threads) {
5106			pthread_cond_wait(&lwpinfo_thread_cnd,
5107			    &lwpinfo_thread_mtx);
5108		}
5109		pthread_mutex_unlock(&lwpinfo_thread_mtx);
5110
5111		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
5112		FORKEE_ASSERT(raise(sigval2) == 0);
5113
5114		/* NOTREACHED */
5115		FORKEE_ASSERTX(0 && "Not reached");
5116	}
5117	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5118
5119	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5120	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5121
5122	validate_status_stopped(status, sigval);
5123
5124	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
5125	SYSCALL_REQUIRE(
5126	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5127
5128	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5129	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5130	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5131	    info.psi_siginfo.si_errno);
5132
5133	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5134	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5135
5136	if (strstr(iter, "LWPINFO") != NULL) {
5137		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5138		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5139		    != -1);
5140
5141		DPRINTF("Assert that there exists a single thread only\n");
5142		ATF_REQUIRE(lwp.pl_lwpid > 0);
5143
5144		DPRINTF("Assert that lwp thread %d received event "
5145		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
5146		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
5147
5148		if (strstr(iter, "LWPSTATUS") != NULL) {
5149			DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS "
5150			    "for child\n");
5151			lwpstatus.pl_lwpid = lwp.pl_lwpid;
5152			SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus,
5153			    sizeof(lwpstatus)) != -1);
5154		}
5155
5156		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5157		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5158		    != -1);
5159
5160		DPRINTF("Assert that there exists a single thread only\n");
5161		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
5162	} else {
5163		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5164		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5165		    sizeof(lwpstatus)) != -1);
5166
5167		DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid);
5168		ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
5169
5170		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5171		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5172		    sizeof(lwpstatus)) != -1);
5173
5174		DPRINTF("Assert that there exists a single thread only\n");
5175		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
5176	}
5177
5178	DPRINTF("Before resuming the child process where it left off and "
5179	    "without signal to be sent\n");
5180	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5181
5182	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5183	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5184
5185	validate_status_stopped(status, sigval2);
5186
5187	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
5188	SYSCALL_REQUIRE(
5189	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5190
5191	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5192	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5193	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5194	    info.psi_siginfo.si_errno);
5195
5196	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
5197	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5198
5199	memset(&lwp, 0, sizeof(lwp));
5200	memset(&lwpstatus, 0, sizeof(lwpstatus));
5201
5202	memset(&io, 0, sizeof(io));
5203
5204	bytes_read = 0;
5205	io.piod_op = PIOD_READ_D;
5206	io.piod_len = sizeof(tcb);
5207
5208	do {
5209		io.piod_addr = (char *)&tcb + bytes_read;
5210		io.piod_offs = io.piod_addr;
5211
5212		rv = ptrace(PT_IO, child, &io, sizeof(io));
5213		ATF_REQUIRE(rv != -1 && io.piod_len != 0);
5214
5215		bytes_read += io.piod_len;
5216		io.piod_len = sizeof(tcb) - bytes_read;
5217	} while (bytes_read < sizeof(tcb));
5218
5219	for (n = 0; n <= threads; n++) {
5220		if (strstr(iter, "LWPINFO") != NULL) {
5221			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5222			    "child\n");
5223			SYSCALL_REQUIRE(
5224			    ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
5225			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5226
5227			DPRINTF("Assert that the thread exists\n");
5228			ATF_REQUIRE(lwp.pl_lwpid > 0);
5229
5230			DPRINTF("Assert that lwp thread %d received expected "
5231			    "event\n", lwp.pl_lwpid);
5232			FORKEE_ASSERT_EQ(lwp.pl_event,
5233			    info.psi_lwpid == lwp.pl_lwpid ?
5234			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
5235
5236			if (strstr(iter, "LWPSTATUS") != NULL) {
5237				DPRINTF("Before calling ptrace(2) with "
5238				    "PT_LWPSTATUS for child\n");
5239				lwpstatus.pl_lwpid = lwp.pl_lwpid;
5240				SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child,
5241				    &lwpstatus, sizeof(lwpstatus)) != -1);
5242
5243				goto check_lwpstatus;
5244			}
5245		} else {
5246			DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for "
5247			    "child\n");
5248			SYSCALL_REQUIRE(
5249			    ptrace(PT_LWPNEXT, child, &lwpstatus,
5250			    sizeof(lwpstatus)) != -1);
5251			DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid);
5252
5253			DPRINTF("Assert that the thread exists\n");
5254			ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
5255
5256		check_lwpstatus:
5257
5258			if (strstr(iter, "pl_sigmask") != NULL) {
5259				sigmask = lwpstatus.pl_sigmask;
5260
5261				DPRINTF("Retrieved sigmask: "
5262				    "%02x%02x%02x%02x\n",
5263				    sigmask.__bits[0], sigmask.__bits[1],
5264				    sigmask.__bits[2], sigmask.__bits[3]);
5265
5266				found = false;
5267				for (m = 0;
5268				     m < __arraycount(lwpinfo_thread_sigmask);
5269				     m++) {
5270					if (sigismember(&sigmask,
5271					    lwpinfo_thread_sigmask[m])) {
5272						found = true;
5273						lwpinfo_thread_sigmask[m] = 0;
5274						break;
5275					}
5276				}
5277				ATF_REQUIRE(found == true);
5278			} else if (strstr(iter, "pl_name") != NULL) {
5279				name = lwpstatus.pl_name;
5280
5281				DPRINTF("Retrieved thread name: "
5282				    "%s\n", name);
5283
5284				snprintf(namebuf, sizeof namebuf, "thread %d",
5285				    lwpstatus.pl_lwpid);
5286
5287				ATF_REQUIRE(strcmp(name, namebuf) == 0);
5288			} else if (strstr(iter, "pl_private") != NULL) {
5289				private = lwpstatus.pl_private;
5290
5291				DPRINTF("Retrieved thread private pointer: "
5292				    "%p\n", private);
5293
5294				found = false;
5295				for (m = 0; m < __arraycount(tcb); m++) {
5296					DPRINTF("Comparing %p and %p\n",
5297					    private, tcb[m]);
5298					if (private == tcb[m]) {
5299						found = true;
5300						break;
5301					}
5302				}
5303				ATF_REQUIRE(found == true);
5304			}
5305		}
5306	}
5307
5308	if (strstr(iter, "LWPINFO") != NULL) {
5309		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5310		    "child\n");
5311		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
5312		    != -1);
5313		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5314
5315		DPRINTF("Assert that there are no more threads\n");
5316		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
5317	} else {
5318		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
5319		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
5320		    sizeof(lwpstatus)) != -1);
5321
5322		DPRINTF("Assert that there exists a single thread only\n");
5323		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
5324	}
5325
5326	DPRINTF("Before resuming the child process where it left off and "
5327	    "without signal to be sent\n");
5328	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
5329
5330	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5331	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5332
5333	validate_status_signaled(status, SIGKILL, 0);
5334
5335	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5336	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5337}
5338
5339#define TRACEME_LWPINFO(test, threads, iter)				\
5340ATF_TC(test);								\
5341ATF_TC_HEAD(test, tc)							\
5342{									\
5343	atf_tc_set_md_var(tc, "descr",					\
5344	    "Verify " iter " with the child with " #threads		\
5345	    " spawned extra threads");					\
5346}									\
5347									\
5348ATF_TC_BODY(test, tc)							\
5349{									\
5350									\
5351	traceme_lwpinfo(threads, iter);					\
5352}
5353
5354TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO")
5355TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO")
5356TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO")
5357TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO")
5358
5359TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS")
5360TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS")
5361TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS")
5362TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS")
5363
5364TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0,
5365    "LWPINFO+LWPSTATUS+pl_sigmask")
5366TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1,
5367    "LWPINFO+LWPSTATUS+pl_sigmask")
5368TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2,
5369    "LWPINFO+LWPSTATUS+pl_sigmask")
5370TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3,
5371    "LWPINFO+LWPSTATUS+pl_sigmask")
5372
5373TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0,
5374    "LWPINFO+LWPSTATUS+pl_name")
5375TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1,
5376    "LWPINFO+LWPSTATUS+pl_name")
5377TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2,
5378    "LWPINFO+LWPSTATUS+pl_name")
5379TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3,
5380    "LWPINFO+LWPSTATUS+pl_name")
5381
5382TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0,
5383    "LWPINFO+LWPSTATUS+pl_private")
5384TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1,
5385    "LWPINFO+LWPSTATUS+pl_private")
5386TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2,
5387    "LWPINFO+LWPSTATUS+pl_private")
5388TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3,
5389    "LWPINFO+LWPSTATUS+pl_private")
5390
5391TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT")
5392TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT")
5393TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT")
5394TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT")
5395
5396TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask")
5397TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask")
5398TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask")
5399TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask")
5400
5401TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name")
5402TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name")
5403TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name")
5404TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name")
5405
5406TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private")
5407TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private")
5408TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private")
5409TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private")
5410
5411/// ----------------------------------------------------------------------------
5412
5413#if defined(TWAIT_HAVE_PID)
5414static void
5415attach_lwpinfo(const int threads)
5416{
5417	const int sigval = SIGINT;
5418	struct msg_fds parent_tracee, parent_tracer;
5419	const int exitval_tracer = 10;
5420	pid_t tracee, tracer, wpid;
5421	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
5422#if defined(TWAIT_HAVE_STATUS)
5423	int status;
5424#endif
5425	struct ptrace_lwpinfo lwp = {0, 0};
5426	struct ptrace_siginfo info;
5427
5428	/* Maximum number of supported threads in this test */
5429	pthread_t t[3];
5430	int n, rv;
5431
5432	DPRINTF("Spawn tracee\n");
5433	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
5434	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
5435	tracee = atf_utils_fork();
5436	if (tracee == 0) {
5437		/* Wait for message from the parent */
5438		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
5439
5440		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
5441
5442		for (n = 0; n < threads; n++) {
5443			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
5444			FORKEE_ASSERT(rv == 0);
5445		}
5446
5447		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
5448
5449		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5450		FORKEE_ASSERT(raise(sigval) == 0);
5451
5452		/* NOTREACHED */
5453		FORKEE_ASSERTX(0 && "Not reached");
5454	}
5455	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
5456
5457	DPRINTF("Spawn debugger\n");
5458	tracer = atf_utils_fork();
5459	if (tracer == 0) {
5460		/* No IPC to communicate with the child */
5461		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
5462		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
5463
5464		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
5465		FORKEE_REQUIRE_SUCCESS(
5466		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5467
5468		forkee_status_stopped(status, SIGSTOP);
5469
5470		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5471		    "tracee");
5472		FORKEE_ASSERT(
5473		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
5474
5475		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5476		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5477		    "si_errno=%#x\n",
5478		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5479		    info.psi_siginfo.si_errno);
5480
5481		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
5482		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
5483
5484		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
5485		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5486		    != -1);
5487
5488		DPRINTF("Assert that there exists a thread\n");
5489		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
5490
5491		DPRINTF("Assert that lwp thread %d received event "
5492		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
5493		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
5494
5495		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5496		    "tracee\n");
5497		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5498		    != -1);
5499
5500		DPRINTF("Assert that there are no more lwp threads in "
5501		    "tracee\n");
5502		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5503
5504		/* Resume tracee with PT_CONTINUE */
5505		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
5506
5507		/* Inform parent that tracer has attached to tracee */
5508		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
5509
5510		/* Wait for parent */
5511		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
5512
5513		/* Wait for tracee and assert that it raised a signal */
5514		FORKEE_REQUIRE_SUCCESS(
5515		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5516
5517		forkee_status_stopped(status, SIGINT);
5518
5519		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5520		    "child");
5521		FORKEE_ASSERT(
5522		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
5523
5524		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5525		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
5526		    "si_errno=%#x\n",
5527		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5528		    info.psi_siginfo.si_errno);
5529
5530		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
5531		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
5532
5533		memset(&lwp, 0, sizeof(lwp));
5534
5535		for (n = 0; n <= threads; n++) {
5536			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5537			    "child\n");
5538			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
5539			    sizeof(lwp)) != -1);
5540			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5541
5542			DPRINTF("Assert that the thread exists\n");
5543			FORKEE_ASSERT(lwp.pl_lwpid > 0);
5544
5545			DPRINTF("Assert that lwp thread %d received expected "
5546			    "event\n", lwp.pl_lwpid);
5547			FORKEE_ASSERT_EQ(lwp.pl_event,
5548			    info.psi_lwpid == lwp.pl_lwpid ?
5549			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
5550		}
5551		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
5552		    "tracee\n");
5553		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
5554		    != -1);
5555		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
5556
5557		DPRINTF("Assert that there are no more threads\n");
5558		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
5559
5560		DPRINTF("Before resuming the child process where it left off "
5561		    "and without signal to be sent\n");
5562		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
5563		    != -1);
5564
5565		/* Wait for tracee and assert that it exited */
5566		FORKEE_REQUIRE_SUCCESS(
5567		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
5568
5569		forkee_status_signaled(status, SIGKILL, 0);
5570
5571		DPRINTF("Before exiting of the tracer process\n");
5572		_exit(exitval_tracer);
5573	}
5574
5575	DPRINTF("Wait for the tracer to attach to the tracee\n");
5576	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
5577
5578	DPRINTF("Resume the tracee and spawn threads\n");
5579	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
5580
5581	DPRINTF("Resume the tracee and let it exit\n");
5582	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
5583
5584	DPRINTF("Resume the tracer and let it detect multiple threads\n");
5585	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
5586
5587	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
5588	    TWAIT_FNAME);
5589	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
5590	    tracer);
5591
5592	validate_status_exited(status, exitval_tracer);
5593
5594	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
5595	    TWAIT_FNAME);
5596	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
5597	    tracee);
5598
5599	validate_status_signaled(status, SIGKILL, 0);
5600
5601	msg_close(&parent_tracer);
5602	msg_close(&parent_tracee);
5603}
5604
5605#define ATTACH_LWPINFO(test, threads)					\
5606ATF_TC(test);								\
5607ATF_TC_HEAD(test, tc)							\
5608{									\
5609	atf_tc_set_md_var(tc, "descr",					\
5610	    "Verify LWPINFO with the child with " #threads		\
5611	    " spawned extra threads (tracer is not the original "	\
5612	    "parent)");							\
5613}									\
5614									\
5615ATF_TC_BODY(test, tc)							\
5616{									\
5617									\
5618	attach_lwpinfo(threads);					\
5619}
5620
5621ATTACH_LWPINFO(attach_lwpinfo0, 0)
5622ATTACH_LWPINFO(attach_lwpinfo1, 1)
5623ATTACH_LWPINFO(attach_lwpinfo2, 2)
5624ATTACH_LWPINFO(attach_lwpinfo3, 3)
5625#endif
5626
5627/// ----------------------------------------------------------------------------
5628
5629static void
5630ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
5631{
5632	const int exitval = 5;
5633	const int sigval = SIGINT;
5634	const int sigfaked = SIGTRAP;
5635	const int sicodefaked = TRAP_BRKPT;
5636	pid_t child, wpid;
5637	struct sigaction sa;
5638#if defined(TWAIT_HAVE_STATUS)
5639	int status;
5640#endif
5641	struct ptrace_siginfo info;
5642	memset(&info, 0, sizeof(info));
5643
5644	DPRINTF("Before forking process PID=%d\n", getpid());
5645	SYSCALL_REQUIRE((child = fork()) != -1);
5646	if (child == 0) {
5647		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5648		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5649
5650		sa.sa_sigaction = sah;
5651		sa.sa_flags = SA_SIGINFO;
5652		sigemptyset(&sa.sa_mask);
5653
5654		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
5655		    != -1);
5656
5657		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5658		FORKEE_ASSERT(raise(sigval) == 0);
5659
5660		FORKEE_ASSERT_EQ(*signal_caught, 1);
5661
5662		DPRINTF("Before exiting of the child process\n");
5663		_exit(exitval);
5664	}
5665	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5666
5667	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5668	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5669
5670	validate_status_stopped(status, sigval);
5671
5672	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5673	SYSCALL_REQUIRE(
5674	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5675
5676	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5677	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5678	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5679	    info.psi_siginfo.si_errno);
5680
5681	if (faked) {
5682		DPRINTF("Before setting new faked signal to signo=%d "
5683		    "si_code=%d\n", sigfaked, sicodefaked);
5684		info.psi_siginfo.si_signo = sigfaked;
5685		info.psi_siginfo.si_code = sicodefaked;
5686	}
5687
5688	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
5689	SYSCALL_REQUIRE(
5690	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
5691
5692	if (faked) {
5693		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
5694		    "child\n");
5695		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
5696		    sizeof(info)) != -1);
5697
5698		DPRINTF("Before checking siginfo_t\n");
5699		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
5700		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
5701	}
5702
5703	DPRINTF("Before resuming the child process where it left off and "
5704	    "without signal to be sent\n");
5705	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
5706	    faked ? sigfaked : sigval) != -1);
5707
5708	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5709	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5710
5711	validate_status_exited(status, exitval);
5712
5713	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5714	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5715}
5716
5717#define PTRACE_SIGINFO(test, faked)					\
5718ATF_TC(test);								\
5719ATF_TC_HEAD(test, tc)							\
5720{									\
5721	atf_tc_set_md_var(tc, "descr",					\
5722	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
5723	    "with%s setting signal to new value", faked ? "" : "out");	\
5724}									\
5725									\
5726static int test##_caught = 0;						\
5727									\
5728static void								\
5729test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
5730{									\
5731	if (faked) {							\
5732		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
5733		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
5734		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
5735	} else {							\
5736		FORKEE_ASSERT_EQ(sig, SIGINT);				\
5737		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
5738		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
5739	}								\
5740									\
5741	++ test##_caught;						\
5742}									\
5743									\
5744ATF_TC_BODY(test, tc)							\
5745{									\
5746									\
5747	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
5748}
5749
5750PTRACE_SIGINFO(siginfo_set_unmodified, false)
5751PTRACE_SIGINFO(siginfo_set_faked, true)
5752
5753/// ----------------------------------------------------------------------------
5754
5755static void
5756traceme_exec(bool masked, bool ignored)
5757{
5758	const int sigval = SIGTRAP;
5759	pid_t child, wpid;
5760#if defined(TWAIT_HAVE_STATUS)
5761	int status;
5762#endif
5763	struct sigaction sa;
5764	struct ptrace_siginfo info;
5765	sigset_t intmask;
5766	struct kinfo_proc2 kp;
5767	size_t len = sizeof(kp);
5768
5769	int name[6];
5770	const size_t namelen = __arraycount(name);
5771	ki_sigset_t kp_sigmask;
5772	ki_sigset_t kp_sigignore;
5773
5774	memset(&info, 0, sizeof(info));
5775
5776	DPRINTF("Before forking process PID=%d\n", getpid());
5777	SYSCALL_REQUIRE((child = fork()) != -1);
5778	if (child == 0) {
5779		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5780		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5781
5782		if (masked) {
5783			sigemptyset(&intmask);
5784			sigaddset(&intmask, sigval);
5785			sigprocmask(SIG_BLOCK, &intmask, NULL);
5786		}
5787
5788		if (ignored) {
5789			memset(&sa, 0, sizeof(sa));
5790			sa.sa_handler = SIG_IGN;
5791			sigemptyset(&sa.sa_mask);
5792			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
5793		}
5794
5795		DPRINTF("Before calling execve(2) from child\n");
5796		execlp("/bin/echo", "/bin/echo", NULL);
5797
5798		FORKEE_ASSERT(0 && "Not reached");
5799	}
5800	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5801
5802	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5803	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5804
5805	validate_status_stopped(status, sigval);
5806
5807	name[0] = CTL_KERN,
5808	name[1] = KERN_PROC2,
5809	name[2] = KERN_PROC_PID;
5810	name[3] = getpid();
5811	name[4] = sizeof(kp);
5812	name[5] = 1;
5813
5814	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5815
5816	if (masked)
5817		kp_sigmask = kp.p_sigmask;
5818
5819	if (ignored)
5820		kp_sigignore = kp.p_sigignore;
5821
5822	name[3] = getpid();
5823
5824	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
5825
5826	if (masked) {
5827		DPRINTF("kp_sigmask="
5828		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5829		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
5830		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
5831
5832		DPRINTF("kp.p_sigmask="
5833		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5834		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
5835		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
5836
5837		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
5838		    sizeof(kp_sigmask)));
5839	}
5840
5841	if (ignored) {
5842		DPRINTF("kp_sigignore="
5843		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5844		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
5845		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
5846
5847		DPRINTF("kp.p_sigignore="
5848		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
5849		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
5850		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
5851
5852		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
5853		    sizeof(kp_sigignore)));
5854	}
5855
5856	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5857	SYSCALL_REQUIRE(
5858	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5859
5860	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5861	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5862	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5863	    info.psi_siginfo.si_errno);
5864
5865	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5866	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
5867
5868	DPRINTF("Before resuming the child process where it left off and "
5869	    "without signal to be sent\n");
5870	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
5871
5872	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5873	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5874
5875	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5876	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
5877}
5878
5879#define TRACEME_EXEC(test, masked, ignored)				\
5880ATF_TC(test);								\
5881ATF_TC_HEAD(test, tc)							\
5882{									\
5883       atf_tc_set_md_var(tc, "descr",					\
5884           "Detect SIGTRAP TRAP_EXEC from "				\
5885           "child%s%s", masked ? " with masked signal" : "",		\
5886           masked ? " with ignored signal" : "");			\
5887}									\
5888									\
5889ATF_TC_BODY(test, tc)							\
5890{									\
5891									\
5892       traceme_exec(masked, ignored);					\
5893}
5894
5895TRACEME_EXEC(traceme_exec, false, false)
5896TRACEME_EXEC(traceme_signalmasked_exec, true, false)
5897TRACEME_EXEC(traceme_signalignored_exec, false, true)
5898
5899/// ----------------------------------------------------------------------------
5900
5901#define TRACE_THREADS_NUM 100
5902
5903static volatile int done;
5904pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
5905
5906static void *
5907trace_threads_cb(void *arg __unused)
5908{
5909
5910	pthread_mutex_lock(&trace_threads_mtx);
5911	done++;
5912	pthread_mutex_unlock(&trace_threads_mtx);
5913
5914	while (done < TRACE_THREADS_NUM)
5915		sched_yield();
5916
5917	return NULL;
5918}
5919
5920static void
5921trace_threads(bool trace_create, bool trace_exit, bool masked)
5922{
5923	const int sigval = SIGSTOP;
5924	pid_t child, wpid;
5925#if defined(TWAIT_HAVE_STATUS)
5926	int status;
5927#endif
5928	ptrace_state_t state;
5929	const int slen = sizeof(state);
5930	ptrace_event_t event;
5931	const int elen = sizeof(event);
5932	struct ptrace_siginfo info;
5933
5934	sigset_t intmask;
5935
5936	pthread_t t[TRACE_THREADS_NUM];
5937	int rv;
5938	size_t n;
5939	lwpid_t lid;
5940
5941	/* Track created and exited threads */
5942	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
5943
5944	DPRINTF("Before forking process PID=%d\n", getpid());
5945	SYSCALL_REQUIRE((child = fork()) != -1);
5946	if (child == 0) {
5947		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
5948		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
5949
5950		if (masked) {
5951			sigemptyset(&intmask);
5952			sigaddset(&intmask, SIGTRAP);
5953			sigprocmask(SIG_BLOCK, &intmask, NULL);
5954		}
5955
5956		DPRINTF("Before raising %s from child\n", strsignal(sigval));
5957		FORKEE_ASSERT(raise(sigval) == 0);
5958
5959		for (n = 0; n < __arraycount(t); n++) {
5960			rv = pthread_create(&t[n], NULL, trace_threads_cb,
5961			    NULL);
5962			FORKEE_ASSERT(rv == 0);
5963		}
5964
5965		for (n = 0; n < __arraycount(t); n++) {
5966			rv = pthread_join(t[n], NULL);
5967			FORKEE_ASSERT(rv == 0);
5968		}
5969
5970		/*
5971		 * There is race between _exit() and pthread_join() detaching
5972		 * a thread. For simplicity kill the process after detecting
5973		 * LWP events.
5974		 */
5975		while (true)
5976			continue;
5977
5978		FORKEE_ASSERT(0 && "Not reached");
5979	}
5980	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
5981
5982	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
5983	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
5984
5985	validate_status_stopped(status, sigval);
5986
5987	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
5988	SYSCALL_REQUIRE(
5989	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
5990
5991	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
5992	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
5993	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
5994	    info.psi_siginfo.si_errno);
5995
5996	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
5997	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
5998
5999	DPRINTF("Set LWP event mask for the child %d\n", child);
6000	memset(&event, 0, sizeof(event));
6001	if (trace_create)
6002		event.pe_set_event |= PTRACE_LWP_CREATE;
6003	if (trace_exit)
6004		event.pe_set_event |= PTRACE_LWP_EXIT;
6005	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6006
6007	DPRINTF("Before resuming the child process where it left off and "
6008	    "without signal to be sent\n");
6009	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6010
6011	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
6012		DPRINTF("Before calling %s() for the child - expected stopped "
6013		    "SIGTRAP\n", TWAIT_FNAME);
6014		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6015		    child);
6016
6017		validate_status_stopped(status, SIGTRAP);
6018
6019		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6020		    "child\n");
6021		SYSCALL_REQUIRE(
6022		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6023
6024		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6025		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6026		    "si_errno=%#x\n",
6027		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6028		    info.psi_siginfo.si_errno);
6029
6030		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6031		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6032
6033		SYSCALL_REQUIRE(
6034		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6035
6036		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
6037		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
6038
6039		lid = state.pe_lwp;
6040		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6041
6042		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
6043
6044		DPRINTF("Before resuming the child process where it left off "
6045		    "and without signal to be sent\n");
6046		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6047	}
6048
6049	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
6050		DPRINTF("Before calling %s() for the child - expected stopped "
6051		    "SIGTRAP\n", TWAIT_FNAME);
6052		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6053		    child);
6054
6055		validate_status_stopped(status, SIGTRAP);
6056
6057		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6058		    "child\n");
6059		SYSCALL_REQUIRE(
6060		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6061
6062		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6063		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6064		    "si_errno=%#x\n",
6065		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6066		    info.psi_siginfo.si_errno);
6067
6068		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6069		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6070
6071		SYSCALL_REQUIRE(
6072		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6073
6074		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
6075		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
6076
6077		lid = state.pe_lwp;
6078		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6079
6080		if (trace_create) {
6081			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
6082			ATF_REQUIRE_EQ(*count, 1);
6083			*count = 0;
6084		}
6085
6086		DPRINTF("Before resuming the child process where it left off "
6087		    "and without signal to be sent\n");
6088		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6089	}
6090
6091	kill(child, SIGKILL);
6092
6093	DPRINTF("Before calling %s() for the child - expected exited\n",
6094	    TWAIT_FNAME);
6095	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6096
6097	validate_status_signaled(status, SIGKILL, 0);
6098
6099	DPRINTF("Before calling %s() for the child - expected no process\n",
6100	    TWAIT_FNAME);
6101	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6102}
6103
6104#define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
6105ATF_TC(test);								\
6106ATF_TC_HEAD(test, tc)							\
6107{									\
6108        atf_tc_set_md_var(tc, "descr",					\
6109            "Verify spawning threads with%s tracing LWP create and"	\
6110	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
6111	    trace_exit ? "" : "out");					\
6112}									\
6113									\
6114ATF_TC_BODY(test, tc)							\
6115{									\
6116									\
6117        trace_threads(trace_create, trace_exit, mask);			\
6118}
6119
6120TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
6121TRACE_THREADS(trace_thread_lwpexit, false, true, false)
6122TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
6123TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
6124
6125TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
6126TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
6127TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
6128
6129/// ----------------------------------------------------------------------------
6130
6131ATF_TC(signal_mask_unrelated);
6132ATF_TC_HEAD(signal_mask_unrelated, tc)
6133{
6134	atf_tc_set_md_var(tc, "descr",
6135	    "Verify that masking single unrelated signal does not stop tracer "
6136	    "from catching other signals");
6137}
6138
6139ATF_TC_BODY(signal_mask_unrelated, tc)
6140{
6141	const int exitval = 5;
6142	const int sigval = SIGSTOP;
6143	const int sigmasked = SIGTRAP;
6144	const int signotmasked = SIGINT;
6145	pid_t child, wpid;
6146#if defined(TWAIT_HAVE_STATUS)
6147	int status;
6148#endif
6149	sigset_t intmask;
6150
6151	DPRINTF("Before forking process PID=%d\n", getpid());
6152	SYSCALL_REQUIRE((child = fork()) != -1);
6153	if (child == 0) {
6154		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6155		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6156
6157		sigemptyset(&intmask);
6158		sigaddset(&intmask, sigmasked);
6159		sigprocmask(SIG_BLOCK, &intmask, NULL);
6160
6161		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6162		FORKEE_ASSERT(raise(sigval) == 0);
6163
6164		DPRINTF("Before raising %s from child\n",
6165		    strsignal(signotmasked));
6166		FORKEE_ASSERT(raise(signotmasked) == 0);
6167
6168		DPRINTF("Before exiting of the child process\n");
6169		_exit(exitval);
6170	}
6171	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6172
6173	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6174	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6175
6176	validate_status_stopped(status, sigval);
6177
6178	DPRINTF("Before resuming the child process where it left off and "
6179	    "without signal to be sent\n");
6180	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6181
6182	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6183	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6184
6185	validate_status_stopped(status, signotmasked);
6186
6187	DPRINTF("Before resuming the child process where it left off and "
6188	    "without signal to be sent\n");
6189	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6190
6191	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6192	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6193
6194	validate_status_exited(status, exitval);
6195
6196	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6197	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6198}
6199
6200/// ----------------------------------------------------------------------------
6201
6202#if defined(TWAIT_HAVE_PID)
6203static void
6204fork2_body(const char *fn, bool masked, bool ignored)
6205{
6206	const int exitval = 5;
6207	const int exitval2 = 0; /* Match exit status from /bin/echo */
6208	const int sigval = SIGSTOP;
6209	pid_t child, child2 = 0, wpid;
6210#if defined(TWAIT_HAVE_STATUS)
6211	int status;
6212#endif
6213	ptrace_state_t state;
6214	const int slen = sizeof(state);
6215	ptrace_event_t event;
6216	const int elen = sizeof(event);
6217	struct sigaction sa;
6218	struct ptrace_siginfo info;
6219	sigset_t intmask;
6220	struct kinfo_proc2 kp;
6221	size_t len = sizeof(kp);
6222
6223	int name[6];
6224	const size_t namelen = __arraycount(name);
6225	ki_sigset_t kp_sigmask;
6226	ki_sigset_t kp_sigignore;
6227
6228	char * const arg[] = { __UNCONST("/bin/echo"), NULL };
6229
6230	DPRINTF("Before forking process PID=%d\n", getpid());
6231	SYSCALL_REQUIRE((child = fork()) != -1);
6232	if (child == 0) {
6233		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6234		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6235
6236		if (masked) {
6237			sigemptyset(&intmask);
6238			sigaddset(&intmask, SIGTRAP);
6239			sigprocmask(SIG_BLOCK, &intmask, NULL);
6240		}
6241
6242		if (ignored) {
6243			memset(&sa, 0, sizeof(sa));
6244			sa.sa_handler = SIG_IGN;
6245			sigemptyset(&sa.sa_mask);
6246			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
6247		}
6248
6249		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6250		FORKEE_ASSERT(raise(sigval) == 0);
6251
6252		if (strcmp(fn, "spawn") == 0) {
6253			FORKEE_ASSERT_EQ(posix_spawn(&child2,
6254			    arg[0], NULL, NULL, arg, NULL), 0);
6255		} else  {
6256			if (strcmp(fn, "fork") == 0) {
6257				FORKEE_ASSERT((child2 = fork()) != -1);
6258			} else {
6259				FORKEE_ASSERT((child2 = vfork()) != -1);
6260			}
6261			if (child2 == 0)
6262				_exit(exitval2);
6263		}
6264
6265		FORKEE_REQUIRE_SUCCESS
6266		    (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6267
6268		forkee_status_exited(status, exitval2);
6269
6270		DPRINTF("Before exiting of the child process\n");
6271		_exit(exitval);
6272	}
6273	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6274
6275	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6276	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6277
6278	validate_status_stopped(status, sigval);
6279
6280	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6281	SYSCALL_REQUIRE(
6282	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6283
6284	DPRINTF("Before checking siginfo_t\n");
6285	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6286	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
6287
6288	name[0] = CTL_KERN,
6289	name[1] = KERN_PROC2,
6290	name[2] = KERN_PROC_PID;
6291	name[3] = child;
6292	name[4] = sizeof(kp);
6293	name[5] = 1;
6294
6295	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6296
6297	if (masked)
6298		kp_sigmask = kp.p_sigmask;
6299
6300	if (ignored)
6301		kp_sigignore = kp.p_sigignore;
6302
6303	DPRINTF("Set 0%s%s%s%s in EVENT_MASK for the child %d\n",
6304	    strcmp(fn, "spawn") == 0 ? "|PTRACE_POSIX_SPAWN" : "",
6305	    strcmp(fn, "fork") == 0 ? "|PTRACE_FORK" : "",
6306	    strcmp(fn, "vfork") == 0 ? "|PTRACE_VFORK" : "",
6307	    strcmp(fn, "vforkdone") == 0 ? "|PTRACE_VFORK_DONE" : "", child);
6308	event.pe_set_event = 0;
6309	if (strcmp(fn, "spawn") == 0)
6310		event.pe_set_event |= PTRACE_POSIX_SPAWN;
6311	if (strcmp(fn, "fork") == 0)
6312		event.pe_set_event |= PTRACE_FORK;
6313	if (strcmp(fn, "vfork") == 0)
6314		event.pe_set_event |= PTRACE_VFORK;
6315	if (strcmp(fn, "vforkdone") == 0)
6316		event.pe_set_event |= PTRACE_VFORK_DONE;
6317	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6318
6319	DPRINTF("Before resuming the child process where it left off and "
6320	    "without signal to be sent\n");
6321	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6322
6323	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
6324	    strcmp(fn, "vfork") == 0) {
6325		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6326		    child);
6327		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6328		    child);
6329
6330		validate_status_stopped(status, SIGTRAP);
6331
6332		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6333
6334		if (masked) {
6335			DPRINTF("kp_sigmask="
6336			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6337			    PRIx32 "\n",
6338			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6339			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6340
6341			DPRINTF("kp.p_sigmask="
6342			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6343			    PRIx32 "\n",
6344			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6345			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6346
6347			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6348			    sizeof(kp_sigmask)));
6349		}
6350
6351		if (ignored) {
6352			DPRINTF("kp_sigignore="
6353			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6354			    PRIx32 "\n",
6355			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6356			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6357
6358			DPRINTF("kp.p_sigignore="
6359			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6360			    PRIx32 "\n",
6361			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6362			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6363
6364			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6365			    sizeof(kp_sigignore)));
6366		}
6367
6368		SYSCALL_REQUIRE(
6369		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6370		if (strcmp(fn, "spawn") == 0) {
6371			ATF_REQUIRE_EQ(
6372			    state.pe_report_event & PTRACE_POSIX_SPAWN,
6373			       PTRACE_POSIX_SPAWN);
6374		}
6375		if (strcmp(fn, "fork") == 0) {
6376			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6377			       PTRACE_FORK);
6378		}
6379		if (strcmp(fn, "vfork") == 0) {
6380			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6381			       PTRACE_VFORK);
6382		}
6383
6384		child2 = state.pe_other_pid;
6385		DPRINTF("Reported ptrace event with forkee %d\n", child2);
6386
6387		DPRINTF("Before calling %s() for the forkee %d of the child "
6388		    "%d\n", TWAIT_FNAME, child2, child);
6389		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
6390		    child2);
6391
6392		validate_status_stopped(status, SIGTRAP);
6393
6394		name[3] = child2;
6395		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6396
6397		if (masked) {
6398			DPRINTF("kp_sigmask="
6399			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6400			    PRIx32 "\n",
6401			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6402			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6403
6404			DPRINTF("kp.p_sigmask="
6405			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6406			    PRIx32 "\n",
6407			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6408			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6409
6410			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6411			    sizeof(kp_sigmask)));
6412		}
6413
6414		if (ignored) {
6415			DPRINTF("kp_sigignore="
6416			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6417			    PRIx32 "\n",
6418			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6419			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6420
6421			DPRINTF("kp.p_sigignore="
6422			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6423			    PRIx32 "\n",
6424			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6425			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6426
6427			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6428			    sizeof(kp_sigignore)));
6429		}
6430
6431		SYSCALL_REQUIRE(
6432		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
6433		if (strcmp(fn, "spawn") == 0) {
6434			ATF_REQUIRE_EQ(
6435			    state.pe_report_event & PTRACE_POSIX_SPAWN,
6436			       PTRACE_POSIX_SPAWN);
6437		}
6438		if (strcmp(fn, "fork") == 0) {
6439			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
6440			       PTRACE_FORK);
6441		}
6442		if (strcmp(fn, "vfork") == 0) {
6443			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
6444			       PTRACE_VFORK);
6445		}
6446
6447		ATF_REQUIRE_EQ(state.pe_other_pid, child);
6448
6449		DPRINTF("Before resuming the forkee process where it left off "
6450		    "and without signal to be sent\n");
6451		SYSCALL_REQUIRE(
6452		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
6453
6454		DPRINTF("Before resuming the child process where it left off "
6455		    "and without signal to be sent\n");
6456		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6457	}
6458
6459	if (strcmp(fn, "vforkdone") == 0) {
6460		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
6461		    child);
6462		TWAIT_REQUIRE_SUCCESS(
6463		    wpid = TWAIT_GENERIC(child, &status, 0), child);
6464
6465		validate_status_stopped(status, SIGTRAP);
6466
6467		name[3] = child;
6468		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
6469
6470		/*
6471		 * SIGCHLD is now pending in the signal queue and
6472		 * the kernel presents it to userland as a masked signal.
6473		 */
6474		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
6475
6476		if (masked) {
6477			DPRINTF("kp_sigmask="
6478			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6479			    PRIx32 "\n",
6480			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
6481			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
6482
6483			DPRINTF("kp.p_sigmask="
6484			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6485			    PRIx32 "\n",
6486			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
6487			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
6488
6489			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
6490			    sizeof(kp_sigmask)));
6491		}
6492
6493		if (ignored) {
6494			DPRINTF("kp_sigignore="
6495			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6496			    PRIx32 "\n",
6497			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
6498			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
6499
6500			DPRINTF("kp.p_sigignore="
6501			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
6502			    PRIx32 "\n",
6503			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
6504			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
6505
6506			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
6507			    sizeof(kp_sigignore)));
6508		}
6509
6510		SYSCALL_REQUIRE(
6511		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6512		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
6513
6514		child2 = state.pe_other_pid;
6515		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
6516		    child2);
6517
6518		DPRINTF("Before resuming the child process where it left off "
6519		    "and without signal to be sent\n");
6520		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6521	}
6522
6523	if (strcmp(fn, "spawn") == 0 || strcmp(fn, "fork") == 0 ||
6524	    strcmp(fn, "vfork") == 0) {
6525		DPRINTF("Before calling %s() for the forkee - expected exited"
6526		    "\n", TWAIT_FNAME);
6527		TWAIT_REQUIRE_SUCCESS(
6528		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
6529
6530		validate_status_exited(status, exitval2);
6531
6532		DPRINTF("Before calling %s() for the forkee - expected no "
6533		    "process\n", TWAIT_FNAME);
6534		TWAIT_REQUIRE_FAILURE(ECHILD,
6535		    wpid = TWAIT_GENERIC(child2, &status, 0));
6536	}
6537
6538	DPRINTF("Before calling %s() for the child - expected stopped "
6539	    "SIGCHLD\n", TWAIT_FNAME);
6540	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6541
6542	validate_status_stopped(status, SIGCHLD);
6543
6544	DPRINTF("Before resuming the child process where it left off and "
6545	    "without signal to be sent\n");
6546	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6547
6548	DPRINTF("Before calling %s() for the child - expected exited\n",
6549	    TWAIT_FNAME);
6550	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6551
6552	validate_status_exited(status, exitval);
6553
6554	DPRINTF("Before calling %s() for the child - expected no process\n",
6555	    TWAIT_FNAME);
6556	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6557}
6558
6559#define FORK2_TEST(name,fn,masked,ignored)				\
6560ATF_TC(name);								\
6561ATF_TC_HEAD(name, tc)							\
6562{									\
6563	atf_tc_set_md_var(tc, "descr", "Verify that " fn " is caught "	\
6564	    "regardless of signal %s%s", 				\
6565	    masked ? "masked" : "", ignored ? "ignored" : "");		\
6566}									\
6567									\
6568ATF_TC_BODY(name, tc)							\
6569{									\
6570									\
6571	fork2_body(fn, masked, ignored);				\
6572}
6573
6574FORK2_TEST(posix_spawn_singalmasked, "spawn", true, false)
6575FORK2_TEST(posix_spawn_singalignored, "spawn", false, true)
6576FORK2_TEST(fork_singalmasked, "fork", true, false)
6577FORK2_TEST(fork_singalignored, "fork", false, true)
6578FORK2_TEST(vfork_singalmasked, "vfork", true, false)
6579FORK2_TEST(vfork_singalignored, "vfork", false, true)
6580FORK2_TEST(vforkdone_singalmasked, "vforkdone", true, false)
6581FORK2_TEST(vforkdone_singalignored, "vforkdone", false, true)
6582#endif
6583
6584/// ----------------------------------------------------------------------------
6585
6586static void *
6587thread_and_exec_thread_cb(void *arg __unused)
6588{
6589
6590	execlp("/bin/echo", "/bin/echo", NULL);
6591
6592	abort();
6593}
6594
6595static void
6596threads_and_exec(void)
6597{
6598	const int sigval = SIGSTOP;
6599	pid_t child, wpid;
6600#if defined(TWAIT_HAVE_STATUS)
6601	int status;
6602#endif
6603	ptrace_state_t state;
6604	const int slen = sizeof(state);
6605	ptrace_event_t event;
6606	const int elen = sizeof(event);
6607	struct ptrace_siginfo info;
6608
6609	pthread_t t;
6610	lwpid_t lid;
6611
6612	DPRINTF("Before forking process PID=%d\n", getpid());
6613	SYSCALL_REQUIRE((child = fork()) != -1);
6614	if (child == 0) {
6615		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6616		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6617
6618		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6619		FORKEE_ASSERT(raise(sigval) == 0);
6620
6621		FORKEE_ASSERT(pthread_create(&t, NULL,
6622		    thread_and_exec_thread_cb, NULL) == 0);
6623
6624		for (;;)
6625			continue;
6626
6627		FORKEE_ASSERT(0 && "Not reached");
6628	}
6629	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6630
6631	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6632	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6633
6634	validate_status_stopped(status, sigval);
6635
6636	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
6637	SYSCALL_REQUIRE(
6638	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6639
6640	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6641	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
6642	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6643	    info.psi_siginfo.si_errno);
6644
6645	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
6646	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
6647
6648	DPRINTF("Set LWP event mask for the child %d\n", child);
6649	memset(&event, 0, sizeof(event));
6650	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
6651	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
6652
6653	DPRINTF("Before resuming the child process where it left off and "
6654	    "without signal to be sent\n");
6655	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6656
6657	DPRINTF("Before calling %s() for the child - expected stopped "
6658	    "SIGTRAP\n", TWAIT_FNAME);
6659	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6660	    child);
6661
6662	validate_status_stopped(status, SIGTRAP);
6663
6664	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6665	    "child\n");
6666	SYSCALL_REQUIRE(
6667	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6668
6669	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6670	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6671	    "si_errno=%#x\n",
6672	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6673	    info.psi_siginfo.si_errno);
6674
6675	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6676	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6677
6678	SYSCALL_REQUIRE(
6679	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6680
6681	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
6682	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
6683
6684	lid = state.pe_lwp;
6685	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
6686
6687	DPRINTF("Before resuming the child process where it left off "
6688	    "and without signal to be sent\n");
6689	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6690
6691	DPRINTF("Before calling %s() for the child - expected stopped "
6692	    "SIGTRAP\n", TWAIT_FNAME);
6693	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6694	    child);
6695
6696	validate_status_stopped(status, SIGTRAP);
6697
6698	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6699	    "child\n");
6700	SYSCALL_REQUIRE(
6701	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6702
6703	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6704	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6705	    "si_errno=%#x\n",
6706	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6707	    info.psi_siginfo.si_errno);
6708
6709	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6710	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
6711
6712	SYSCALL_REQUIRE(
6713	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
6714
6715	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
6716	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
6717
6718	lid = state.pe_lwp;
6719	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
6720
6721	DPRINTF("Before resuming the child process where it left off "
6722	    "and without signal to be sent\n");
6723	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6724
6725	DPRINTF("Before calling %s() for the child - expected stopped "
6726	    "SIGTRAP\n", TWAIT_FNAME);
6727	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
6728	    child);
6729
6730	validate_status_stopped(status, SIGTRAP);
6731
6732	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
6733	    "child\n");
6734	SYSCALL_REQUIRE(
6735	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
6736
6737	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
6738	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
6739	    "si_errno=%#x\n",
6740	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
6741	    info.psi_siginfo.si_errno);
6742
6743	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
6744	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
6745
6746	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
6747
6748	DPRINTF("Before calling %s() for the child - expected exited\n",
6749	    TWAIT_FNAME);
6750	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6751
6752	validate_status_signaled(status, SIGKILL, 0);
6753
6754	DPRINTF("Before calling %s() for the child - expected no process\n",
6755	    TWAIT_FNAME);
6756	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6757}
6758
6759ATF_TC(threads_and_exec);
6760ATF_TC_HEAD(threads_and_exec, tc)
6761{
6762        atf_tc_set_md_var(tc, "descr",
6763            "Verify that multithreaded application on exec() will report "
6764	    "LWP_EXIT events");
6765}
6766
6767ATF_TC_BODY(threads_and_exec, tc)
6768{
6769
6770        threads_and_exec();
6771}
6772
6773/// ----------------------------------------------------------------------------
6774
6775ATF_TC(suspend_no_deadlock);
6776ATF_TC_HEAD(suspend_no_deadlock, tc)
6777{
6778	atf_tc_set_md_var(tc, "descr",
6779	    "Verify that the while the only thread within a process is "
6780	    "suspended, the whole process cannot be unstopped");
6781}
6782
6783ATF_TC_BODY(suspend_no_deadlock, tc)
6784{
6785	const int exitval = 5;
6786	const int sigval = SIGSTOP;
6787	pid_t child, wpid;
6788#if defined(TWAIT_HAVE_STATUS)
6789	int status;
6790#endif
6791	struct ptrace_siginfo psi;
6792
6793	DPRINTF("Before forking process PID=%d\n", getpid());
6794	SYSCALL_REQUIRE((child = fork()) != -1);
6795	if (child == 0) {
6796		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6797		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6798
6799		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6800		FORKEE_ASSERT(raise(sigval) == 0);
6801
6802		DPRINTF("Before exiting of the child process\n");
6803		_exit(exitval);
6804	}
6805	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6806
6807	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6808	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6809
6810	validate_status_stopped(status, sigval);
6811
6812	DPRINTF("Before reading siginfo and lwpid_t\n");
6813	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6814
6815	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6816	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6817
6818	DPRINTF("Before resuming the child process where it left off and "
6819	    "without signal to be sent\n");
6820	ATF_REQUIRE_ERRNO(EDEADLK,
6821	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
6822
6823	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
6824	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
6825
6826	DPRINTF("Before resuming the child process where it left off and "
6827	    "without signal to be sent\n");
6828	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6829
6830	DPRINTF("Before calling %s() for the child - expected exited\n",
6831	    TWAIT_FNAME);
6832	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6833
6834	validate_status_exited(status, exitval);
6835
6836	DPRINTF("Before calling %s() for the child - expected no process\n",
6837	    TWAIT_FNAME);
6838	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6839}
6840
6841/// ----------------------------------------------------------------------------
6842
6843static pthread_barrier_t barrier1_resume;
6844static pthread_barrier_t barrier2_resume;
6845
6846static void *
6847resume_thread(void *arg)
6848{
6849
6850	raise(SIGUSR1);
6851
6852	pthread_barrier_wait(&barrier1_resume);
6853
6854	/* Debugger will suspend the process here */
6855
6856	pthread_barrier_wait(&barrier2_resume);
6857
6858	raise(SIGUSR2);
6859
6860	return infinite_thread(arg);
6861}
6862
6863ATF_TC(resume);
6864ATF_TC_HEAD(resume, tc)
6865{
6866	atf_tc_set_md_var(tc, "descr",
6867	    "Verify that a thread can be suspended by a debugger and later "
6868	    "resumed by the debugger");
6869}
6870
6871ATF_TC_BODY(resume, tc)
6872{
6873	const int sigval = SIGSTOP;
6874	pid_t child, wpid;
6875#if defined(TWAIT_HAVE_STATUS)
6876	int status;
6877#endif
6878	lwpid_t lid;
6879	struct ptrace_siginfo psi;
6880	pthread_t t;
6881
6882	DPRINTF("Before forking process PID=%d\n", getpid());
6883	SYSCALL_REQUIRE((child = fork()) != -1);
6884	if (child == 0) {
6885		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
6886		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
6887
6888		pthread_barrier_init(&barrier1_resume, NULL, 2);
6889		pthread_barrier_init(&barrier2_resume, NULL, 2);
6890
6891		DPRINTF("Before raising %s from child\n", strsignal(sigval));
6892		FORKEE_ASSERT(raise(sigval) == 0);
6893
6894		DPRINTF("Before creating new thread in child\n");
6895		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
6896
6897		pthread_barrier_wait(&barrier1_resume);
6898
6899		pthread_barrier_wait(&barrier2_resume);
6900
6901		infinite_thread(NULL);
6902	}
6903	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
6904
6905	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
6906	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6907
6908	validate_status_stopped(status, sigval);
6909
6910	DPRINTF("Before resuming the child process where it left off and "
6911	    "without signal to be sent\n");
6912	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6913
6914	DPRINTF("Before calling %s() for the child - expected stopped "
6915	    "SIGUSR1\n", TWAIT_FNAME);
6916	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6917
6918	validate_status_stopped(status, SIGUSR1);
6919
6920	DPRINTF("Before reading siginfo and lwpid_t\n");
6921	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
6922
6923	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
6924	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
6925
6926	lid = psi.psi_lwpid;
6927
6928	DPRINTF("Before resuming the child process where it left off and "
6929	    "without signal to be sent\n");
6930	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6931
6932	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
6933	SYSCALL_REQUIRE(sleep(1) == 0);
6934
6935#if defined(TWAIT_HAVE_OPTIONS)
6936	DPRINTF("Before calling %s() for the child - expected no status\n",
6937	    TWAIT_FNAME);
6938	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
6939#endif
6940
6941	DPRINTF("Before resuming the child process where it left off and "
6942	    "without signal to be sent\n");
6943	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
6944
6945	DPRINTF("Before calling %s() for the child - expected stopped "
6946	    "SIGSTOP\n", TWAIT_FNAME);
6947	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6948
6949	validate_status_stopped(status, SIGSTOP);
6950
6951	DPRINTF("Before resuming LWP %d\n", lid);
6952	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
6953
6954	DPRINTF("Before resuming the child process where it left off and "
6955	    "without signal to be sent\n");
6956	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
6957
6958	DPRINTF("Before calling %s() for the child - expected stopped "
6959	    "SIGUSR2\n", TWAIT_FNAME);
6960	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6961
6962	validate_status_stopped(status, SIGUSR2);
6963
6964	DPRINTF("Before resuming the child process where it left off and "
6965	    "without signal to be sent\n");
6966	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
6967
6968	DPRINTF("Before calling %s() for the child - expected exited\n",
6969	    TWAIT_FNAME);
6970	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
6971
6972	validate_status_signaled(status, SIGKILL, 0);
6973
6974	DPRINTF("Before calling %s() for the child - expected no process\n",
6975	    TWAIT_FNAME);
6976	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
6977}
6978
6979/// ----------------------------------------------------------------------------
6980
6981static void
6982clone_body(int flags, bool trackfork, bool trackvfork,
6983    bool trackvforkdone)
6984{
6985	const int exitval = 5;
6986	const int exitval2 = 15;
6987	const int sigval = SIGSTOP;
6988	pid_t child, child2 = 0, wpid;
6989#if defined(TWAIT_HAVE_STATUS)
6990	int status;
6991#endif
6992	ptrace_state_t state;
6993	const int slen = sizeof(state);
6994	ptrace_event_t event;
6995	const int elen = sizeof(event);
6996
6997	const size_t stack_size = 1024 * 1024;
6998	void *stack, *stack_base;
6999
7000	stack = malloc(stack_size);
7001	ATF_REQUIRE(stack != NULL);
7002
7003#ifdef __MACHINE_STACK_GROWS_UP
7004	stack_base = stack;
7005#else
7006	stack_base = (char *)stack + stack_size;
7007#endif
7008
7009	DPRINTF("Before forking process PID=%d\n", getpid());
7010	SYSCALL_REQUIRE((child = fork()) != -1);
7011	if (child == 0) {
7012		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7013		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7014
7015		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7016		FORKEE_ASSERT(raise(sigval) == 0);
7017
7018		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7019		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7020
7021		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7022		    child2);
7023
7024		// XXX WALLSIG?
7025		FORKEE_REQUIRE_SUCCESS
7026		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7027
7028		forkee_status_exited(status, exitval2);
7029
7030		DPRINTF("Before exiting of the child process\n");
7031		_exit(exitval);
7032	}
7033	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7034
7035	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7036	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7037
7038	validate_status_stopped(status, sigval);
7039
7040	DPRINTF("Set 0%s%s%s in EVENT_MASK for the child %d\n",
7041	    trackfork ? "|PTRACE_FORK" : "",
7042	    trackvfork ? "|PTRACE_VFORK" : "",
7043	    trackvforkdone ? "|PTRACE_VFORK_DONE" : "", child);
7044	event.pe_set_event = 0;
7045	if (trackfork)
7046		event.pe_set_event |= PTRACE_FORK;
7047	if (trackvfork)
7048		event.pe_set_event |= PTRACE_VFORK;
7049	if (trackvforkdone)
7050		event.pe_set_event |= PTRACE_VFORK_DONE;
7051	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
7052
7053	DPRINTF("Before resuming the child process where it left off and "
7054	    "without signal to be sent\n");
7055	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7056
7057#if defined(TWAIT_HAVE_PID)
7058	if ((trackfork && !(flags & CLONE_VFORK)) ||
7059	    (trackvfork && (flags & CLONE_VFORK))) {
7060		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7061		    child);
7062		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
7063		    child);
7064
7065		validate_status_stopped(status, SIGTRAP);
7066
7067		SYSCALL_REQUIRE(
7068		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7069		if (trackfork && !(flags & CLONE_VFORK)) {
7070			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7071			       PTRACE_FORK);
7072		}
7073		if (trackvfork && (flags & CLONE_VFORK)) {
7074			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7075			       PTRACE_VFORK);
7076		}
7077
7078		child2 = state.pe_other_pid;
7079		DPRINTF("Reported ptrace event with forkee %d\n", child2);
7080
7081		DPRINTF("Before calling %s() for the forkee %d of the child "
7082		    "%d\n", TWAIT_FNAME, child2, child);
7083		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
7084		    child2);
7085
7086		validate_status_stopped(status, SIGTRAP);
7087
7088		SYSCALL_REQUIRE(
7089		    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
7090		if (trackfork && !(flags & CLONE_VFORK)) {
7091			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7092			       PTRACE_FORK);
7093		}
7094		if (trackvfork && (flags & CLONE_VFORK)) {
7095			ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7096			       PTRACE_VFORK);
7097		}
7098
7099		ATF_REQUIRE_EQ(state.pe_other_pid, child);
7100
7101		DPRINTF("Before resuming the forkee process where it left off "
7102		    "and without signal to be sent\n");
7103		SYSCALL_REQUIRE(
7104		    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
7105
7106		DPRINTF("Before resuming the child process where it left off "
7107		    "and without signal to be sent\n");
7108		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7109	}
7110#endif
7111
7112	if (trackvforkdone && (flags & CLONE_VFORK)) {
7113		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7114		    child);
7115		TWAIT_REQUIRE_SUCCESS(
7116		    wpid = TWAIT_GENERIC(child, &status, 0), child);
7117
7118		validate_status_stopped(status, SIGTRAP);
7119
7120		SYSCALL_REQUIRE(
7121		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7122		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
7123
7124		child2 = state.pe_other_pid;
7125		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
7126		    child2);
7127
7128		DPRINTF("Before resuming the child process where it left off "
7129		    "and without signal to be sent\n");
7130		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7131	}
7132
7133#if defined(TWAIT_HAVE_PID)
7134	if ((trackfork && !(flags & CLONE_VFORK)) ||
7135	    (trackvfork && (flags & CLONE_VFORK))) {
7136		DPRINTF("Before calling %s() for the forkee - expected exited"
7137		    "\n", TWAIT_FNAME);
7138		TWAIT_REQUIRE_SUCCESS(
7139		    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
7140
7141		validate_status_exited(status, exitval2);
7142
7143		DPRINTF("Before calling %s() for the forkee - expected no "
7144		    "process\n", TWAIT_FNAME);
7145		TWAIT_REQUIRE_FAILURE(ECHILD,
7146		    wpid = TWAIT_GENERIC(child2, &status, 0));
7147	}
7148#endif
7149
7150	DPRINTF("Before calling %s() for the child - expected stopped "
7151	    "SIGCHLD\n", TWAIT_FNAME);
7152	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7153
7154	validate_status_stopped(status, SIGCHLD);
7155
7156	DPRINTF("Before resuming the child process where it left off and "
7157	    "without signal to be sent\n");
7158	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7159
7160	DPRINTF("Before calling %s() for the child - expected exited\n",
7161	    TWAIT_FNAME);
7162	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7163
7164	validate_status_exited(status, exitval);
7165
7166	DPRINTF("Before calling %s() for the child - expected no process\n",
7167	    TWAIT_FNAME);
7168	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7169}
7170
7171#define CLONE_TEST(name,flags,tfork,tvfork,tvforkdone)			\
7172ATF_TC(name);								\
7173ATF_TC_HEAD(name, tc)							\
7174{									\
7175	atf_tc_set_md_var(tc, "descr", "Verify clone(%s) "		\
7176	    "called with 0%s%s%s in EVENT_MASK",			\
7177	    #flags,							\
7178	    tfork ? "|PTRACE_FORK" : "",				\
7179	    tvfork ? "|PTRACE_VFORK" : "",				\
7180	    tvforkdone ? "|PTRACE_VFORK_DONE" : "");			\
7181}									\
7182									\
7183ATF_TC_BODY(name, tc)							\
7184{									\
7185									\
7186	clone_body(flags, tfork, tvfork, tvforkdone);			\
7187}
7188
7189CLONE_TEST(clone1, 0, false, false, false)
7190#if defined(TWAIT_HAVE_PID)
7191CLONE_TEST(clone2, 0, true, false, false)
7192CLONE_TEST(clone3, 0, false, true, false)
7193CLONE_TEST(clone4, 0, true, true, false)
7194#endif
7195CLONE_TEST(clone5, 0, false, false, true)
7196#if defined(TWAIT_HAVE_PID)
7197CLONE_TEST(clone6, 0, true, false, true)
7198CLONE_TEST(clone7, 0, false, true, true)
7199CLONE_TEST(clone8, 0, true, true, true)
7200#endif
7201
7202CLONE_TEST(clone_vm1, CLONE_VM, false, false, false)
7203#if defined(TWAIT_HAVE_PID)
7204CLONE_TEST(clone_vm2, CLONE_VM, true, false, false)
7205CLONE_TEST(clone_vm3, CLONE_VM, false, true, false)
7206CLONE_TEST(clone_vm4, CLONE_VM, true, true, false)
7207#endif
7208CLONE_TEST(clone_vm5, CLONE_VM, false, false, true)
7209#if defined(TWAIT_HAVE_PID)
7210CLONE_TEST(clone_vm6, CLONE_VM, true, false, true)
7211CLONE_TEST(clone_vm7, CLONE_VM, false, true, true)
7212CLONE_TEST(clone_vm8, CLONE_VM, true, true, true)
7213#endif
7214
7215CLONE_TEST(clone_fs1, CLONE_FS, false, false, false)
7216#if defined(TWAIT_HAVE_PID)
7217CLONE_TEST(clone_fs2, CLONE_FS, true, false, false)
7218CLONE_TEST(clone_fs3, CLONE_FS, false, true, false)
7219CLONE_TEST(clone_fs4, CLONE_FS, true, true, false)
7220#endif
7221CLONE_TEST(clone_fs5, CLONE_FS, false, false, true)
7222#if defined(TWAIT_HAVE_PID)
7223CLONE_TEST(clone_fs6, CLONE_FS, true, false, true)
7224CLONE_TEST(clone_fs7, CLONE_FS, false, true, true)
7225CLONE_TEST(clone_fs8, CLONE_FS, true, true, true)
7226#endif
7227
7228CLONE_TEST(clone_files1, CLONE_FILES, false, false, false)
7229#if defined(TWAIT_HAVE_PID)
7230CLONE_TEST(clone_files2, CLONE_FILES, true, false, false)
7231CLONE_TEST(clone_files3, CLONE_FILES, false, true, false)
7232CLONE_TEST(clone_files4, CLONE_FILES, true, true, false)
7233#endif
7234CLONE_TEST(clone_files5, CLONE_FILES, false, false, true)
7235#if defined(TWAIT_HAVE_PID)
7236CLONE_TEST(clone_files6, CLONE_FILES, true, false, true)
7237CLONE_TEST(clone_files7, CLONE_FILES, false, true, true)
7238CLONE_TEST(clone_files8, CLONE_FILES, true, true, true)
7239#endif
7240
7241//CLONE_TEST(clone_sighand1, CLONE_SIGHAND, false, false, false)
7242#if defined(TWAIT_HAVE_PID)
7243//CLONE_TEST(clone_sighand2, CLONE_SIGHAND, true, false, false)
7244//CLONE_TEST(clone_sighand3, CLONE_SIGHAND, false, true, false)
7245//CLONE_TEST(clone_sighand4, CLONE_SIGHAND, true, true, false)
7246#endif
7247//CLONE_TEST(clone_sighand5, CLONE_SIGHAND, false, false, true)
7248#if defined(TWAIT_HAVE_PID)
7249//CLONE_TEST(clone_sighand6, CLONE_SIGHAND, true, false, true)
7250//CLONE_TEST(clone_sighand7, CLONE_SIGHAND, false, true, true)
7251//CLONE_TEST(clone_sighand8, CLONE_SIGHAND, true, true, true)
7252#endif
7253
7254CLONE_TEST(clone_vfork1, CLONE_VFORK, false, false, false)
7255#if defined(TWAIT_HAVE_PID)
7256CLONE_TEST(clone_vfork2, CLONE_VFORK, true, false, false)
7257CLONE_TEST(clone_vfork3, CLONE_VFORK, false, true, false)
7258CLONE_TEST(clone_vfork4, CLONE_VFORK, true, true, false)
7259#endif
7260CLONE_TEST(clone_vfork5, CLONE_VFORK, false, false, true)
7261#if defined(TWAIT_HAVE_PID)
7262CLONE_TEST(clone_vfork6, CLONE_VFORK, true, false, true)
7263CLONE_TEST(clone_vfork7, CLONE_VFORK, false, true, true)
7264CLONE_TEST(clone_vfork8, CLONE_VFORK, true, true, true)
7265#endif
7266
7267/// ----------------------------------------------------------------------------
7268
7269#if defined(TWAIT_HAVE_PID)
7270static void
7271clone_body2(int flags, bool masked, bool ignored)
7272{
7273	const int exitval = 5;
7274	const int exitval2 = 15;
7275	const int sigval = SIGSTOP;
7276	pid_t child, child2 = 0, wpid;
7277#if defined(TWAIT_HAVE_STATUS)
7278	int status;
7279#endif
7280	ptrace_state_t state;
7281	const int slen = sizeof(state);
7282	ptrace_event_t event;
7283	const int elen = sizeof(event);
7284	struct sigaction sa;
7285	struct ptrace_siginfo info;
7286	sigset_t intmask;
7287	struct kinfo_proc2 kp;
7288	size_t len = sizeof(kp);
7289
7290	int name[6];
7291	const size_t namelen = __arraycount(name);
7292	ki_sigset_t kp_sigmask;
7293	ki_sigset_t kp_sigignore;
7294
7295	const size_t stack_size = 1024 * 1024;
7296	void *stack, *stack_base;
7297
7298	stack = malloc(stack_size);
7299	ATF_REQUIRE(stack != NULL);
7300
7301#ifdef __MACHINE_STACK_GROWS_UP
7302	stack_base = stack;
7303#else
7304	stack_base = (char *)stack + stack_size;
7305#endif
7306
7307	SYSCALL_REQUIRE((child = fork()) != -1);
7308	if (child == 0) {
7309		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7310		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7311
7312		if (masked) {
7313			sigemptyset(&intmask);
7314			sigaddset(&intmask, SIGTRAP);
7315			sigprocmask(SIG_BLOCK, &intmask, NULL);
7316		}
7317
7318		if (ignored) {
7319			memset(&sa, 0, sizeof(sa));
7320			sa.sa_handler = SIG_IGN;
7321			sigemptyset(&sa.sa_mask);
7322			FORKEE_ASSERT(sigaction(SIGTRAP, &sa, NULL) != -1);
7323		}
7324		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7325		FORKEE_ASSERT(raise(sigval) == 0);
7326
7327		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7328		    flags);
7329		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7330		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7331
7332		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7333		    child2);
7334
7335		// XXX WALLSIG?
7336		FORKEE_REQUIRE_SUCCESS
7337		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7338
7339		forkee_status_exited(status, exitval2);
7340
7341		DPRINTF("Before exiting of the child process\n");
7342		_exit(exitval);
7343	}
7344	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7345
7346	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7347	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7348
7349	validate_status_stopped(status, sigval);
7350
7351	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
7352	SYSCALL_REQUIRE(
7353	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
7354
7355	DPRINTF("Before checking siginfo_t\n");
7356	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7357	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7358
7359	name[0] = CTL_KERN,
7360	name[1] = KERN_PROC2,
7361	name[2] = KERN_PROC_PID;
7362	name[3] = child;
7363	name[4] = sizeof(kp);
7364	name[5] = 1;
7365
7366	FORKEE_ASSERT_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7367
7368	if (masked)
7369		kp_sigmask = kp.p_sigmask;
7370
7371	if (ignored)
7372		kp_sigignore = kp.p_sigignore;
7373
7374	DPRINTF("Set PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE in "
7375	    "EVENT_MASK for the child %d\n", child);
7376	event.pe_set_event = PTRACE_FORK | PTRACE_VFORK | PTRACE_VFORK_DONE;
7377	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
7378
7379	DPRINTF("Before resuming the child process where it left off and "
7380	    "without signal to be sent\n");
7381	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7382
7383	DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7384	    child);
7385	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
7386	    child);
7387
7388	validate_status_stopped(status, SIGTRAP);
7389
7390	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7391
7392	if (masked) {
7393		DPRINTF("kp_sigmask="
7394		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7395		    PRIx32 "\n",
7396		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7397		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7398
7399		DPRINTF("kp.p_sigmask="
7400		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7401		    PRIx32 "\n",
7402		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7403		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7404
7405		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7406		    sizeof(kp_sigmask)));
7407	}
7408
7409	if (ignored) {
7410		DPRINTF("kp_sigignore="
7411		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7412		    PRIx32 "\n",
7413		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7414		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7415
7416		DPRINTF("kp.p_sigignore="
7417		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7418		    PRIx32 "\n",
7419		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7420		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7421
7422		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7423		    sizeof(kp_sigignore)));
7424	}
7425
7426	SYSCALL_REQUIRE(
7427	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7428	DPRINTF("state.pe_report_event=%#x pid=%d\n", state.pe_report_event,
7429	    child2);
7430	if (!(flags & CLONE_VFORK)) {
7431		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7432		       PTRACE_FORK);
7433	} else {
7434		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7435		       PTRACE_VFORK);
7436	}
7437
7438	child2 = state.pe_other_pid;
7439	DPRINTF("Reported ptrace event with forkee %d\n", child2);
7440
7441	DPRINTF("Before calling %s() for the forkee %d of the child "
7442	    "%d\n", TWAIT_FNAME, child2, child);
7443	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
7444	    child2);
7445
7446	validate_status_stopped(status, SIGTRAP);
7447
7448	name[3] = child2;
7449	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7450
7451	if (masked) {
7452		DPRINTF("kp_sigmask="
7453		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7454		    PRIx32 "\n",
7455		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7456		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7457
7458		DPRINTF("kp.p_sigmask="
7459		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7460		    PRIx32 "\n",
7461		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7462		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7463
7464		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7465		    sizeof(kp_sigmask)));
7466	}
7467
7468	if (ignored) {
7469		DPRINTF("kp_sigignore="
7470		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7471		    PRIx32 "\n",
7472		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7473		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7474
7475		DPRINTF("kp.p_sigignore="
7476		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7477		    PRIx32 "\n",
7478		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7479		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7480
7481		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7482		    sizeof(kp_sigignore)));
7483	}
7484
7485	SYSCALL_REQUIRE(
7486	    ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
7487	if (!(flags & CLONE_VFORK)) {
7488		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_FORK,
7489		       PTRACE_FORK);
7490	} else {
7491		ATF_REQUIRE_EQ(state.pe_report_event & PTRACE_VFORK,
7492		       PTRACE_VFORK);
7493	}
7494
7495	ATF_REQUIRE_EQ(state.pe_other_pid, child);
7496
7497	DPRINTF("Before resuming the forkee process where it left off "
7498	    "and without signal to be sent\n");
7499	SYSCALL_REQUIRE(
7500	    ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
7501
7502	DPRINTF("Before resuming the child process where it left off "
7503	    "and without signal to be sent\n");
7504	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7505
7506	if (flags & CLONE_VFORK) {
7507		DPRINTF("Before calling %s() for the child %d\n", TWAIT_FNAME,
7508		    child);
7509		TWAIT_REQUIRE_SUCCESS(
7510		    wpid = TWAIT_GENERIC(child, &status, 0), child);
7511
7512		validate_status_stopped(status, SIGTRAP);
7513
7514		name[3] = child;
7515		ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
7516
7517		/*
7518		 * SIGCHLD is now pending in the signal queue and
7519		 * the kernel presents it to userland as a masked signal.
7520		 */
7521		sigdelset((sigset_t *)&kp.p_sigmask, SIGCHLD);
7522
7523		if (masked) {
7524			DPRINTF("kp_sigmask="
7525			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7526			    PRIx32 "\n",
7527			    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
7528			    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
7529
7530			DPRINTF("kp.p_sigmask="
7531			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7532			    PRIx32 "\n",
7533			    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
7534			    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
7535
7536			ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
7537			    sizeof(kp_sigmask)));
7538		}
7539
7540		if (ignored) {
7541			DPRINTF("kp_sigignore="
7542			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7543			    PRIx32 "\n",
7544			    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
7545			    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
7546
7547			DPRINTF("kp.p_sigignore="
7548			    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02"
7549			    PRIx32 "\n",
7550			    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
7551			    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
7552
7553			ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
7554			    sizeof(kp_sigignore)));
7555		}
7556
7557		SYSCALL_REQUIRE(
7558		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
7559		ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE);
7560
7561		child2 = state.pe_other_pid;
7562		DPRINTF("Reported PTRACE_VFORK_DONE event with forkee %d\n",
7563		    child2);
7564
7565		DPRINTF("Before resuming the child process where it left off "
7566		    "and without signal to be sent\n");
7567		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7568	}
7569
7570	DPRINTF("Before calling %s() for the forkee - expected exited"
7571	    "\n", TWAIT_FNAME);
7572	TWAIT_REQUIRE_SUCCESS(
7573	    wpid = TWAIT_GENERIC(child2, &status, 0), child2);
7574
7575	validate_status_exited(status, exitval2);
7576
7577	DPRINTF("Before calling %s() for the forkee - expected no "
7578	    "process\n", TWAIT_FNAME);
7579	TWAIT_REQUIRE_FAILURE(ECHILD,
7580	    wpid = TWAIT_GENERIC(child2, &status, 0));
7581
7582	DPRINTF("Before calling %s() for the child - expected stopped "
7583	    "SIGCHLD\n", TWAIT_FNAME);
7584	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7585
7586	validate_status_stopped(status, SIGCHLD);
7587
7588	DPRINTF("Before resuming the child process where it left off and "
7589	    "without signal to be sent\n");
7590	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7591
7592	DPRINTF("Before calling %s() for the child - expected exited\n",
7593	    TWAIT_FNAME);
7594	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7595
7596	validate_status_exited(status, exitval);
7597
7598	DPRINTF("Before calling %s() for the child - expected no process\n",
7599	    TWAIT_FNAME);
7600	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7601}
7602
7603#define CLONE_TEST2(name,flags,masked,ignored)				\
7604ATF_TC(name);								\
7605ATF_TC_HEAD(name, tc)							\
7606{									\
7607	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is caught"\
7608	    " regardless of signal %s%s", 				\
7609	    #flags, masked ? "masked" : "", ignored ? "ignored" : "");	\
7610}									\
7611									\
7612ATF_TC_BODY(name, tc)							\
7613{									\
7614									\
7615	clone_body2(flags, masked, ignored);				\
7616}
7617
7618CLONE_TEST2(clone_signalignored, 0, true, false)
7619CLONE_TEST2(clone_signalmasked, 0, false, true)
7620CLONE_TEST2(clone_vm_signalignored, CLONE_VM, true, false)
7621CLONE_TEST2(clone_vm_signalmasked, CLONE_VM, false, true)
7622CLONE_TEST2(clone_fs_signalignored, CLONE_FS, true, false)
7623CLONE_TEST2(clone_fs_signalmasked, CLONE_FS, false, true)
7624CLONE_TEST2(clone_files_signalignored, CLONE_FILES, true, false)
7625CLONE_TEST2(clone_files_signalmasked, CLONE_FILES, false, true)
7626//CLONE_TEST2(clone_sighand_signalignored, CLONE_SIGHAND, true, false) // XXX
7627//CLONE_TEST2(clone_sighand_signalmasked, CLONE_SIGHAND, false, true)  // XXX
7628CLONE_TEST2(clone_vfork_signalignored, CLONE_VFORK, true, false)
7629CLONE_TEST2(clone_vfork_signalmasked, CLONE_VFORK, false, true)
7630#endif
7631
7632/// ----------------------------------------------------------------------------
7633
7634#if defined(TWAIT_HAVE_PID)
7635static void
7636traceme_vfork_clone_body(int flags)
7637{
7638	const int exitval = 5;
7639	const int exitval2 = 15;
7640	pid_t child, child2 = 0, wpid;
7641#if defined(TWAIT_HAVE_STATUS)
7642	int status;
7643#endif
7644
7645	const size_t stack_size = 1024 * 1024;
7646	void *stack, *stack_base;
7647
7648	stack = malloc(stack_size);
7649	ATF_REQUIRE(stack != NULL);
7650
7651#ifdef __MACHINE_STACK_GROWS_UP
7652	stack_base = stack;
7653#else
7654	stack_base = (char *)stack + stack_size;
7655#endif
7656
7657	SYSCALL_REQUIRE((child = vfork()) != -1);
7658	if (child == 0) {
7659		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7660		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7661
7662		DPRINTF("Before forking process PID=%d flags=%#x\n", getpid(),
7663		    flags);
7664		SYSCALL_REQUIRE((child2 = __clone(clone_func, stack_base,
7665		    flags|SIGCHLD, (void *)(intptr_t)exitval2)) != -1);
7666
7667		DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(),
7668		    child2);
7669
7670		// XXX WALLSIG?
7671		FORKEE_REQUIRE_SUCCESS
7672		    (wpid = TWAIT_GENERIC(child2, &status, WALLSIG), child2);
7673
7674		forkee_status_exited(status, exitval2);
7675
7676		DPRINTF("Before exiting of the child process\n");
7677		_exit(exitval);
7678	}
7679	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7680
7681	DPRINTF("Before calling %s() for the child - expected exited\n",
7682	    TWAIT_FNAME);
7683	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7684
7685	validate_status_exited(status, exitval);
7686
7687	DPRINTF("Before calling %s() for the child - expected no process\n",
7688	    TWAIT_FNAME);
7689	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7690}
7691
7692#define TRACEME_VFORK_CLONE_TEST(name,flags)				\
7693ATF_TC(name);								\
7694ATF_TC_HEAD(name, tc)							\
7695{									\
7696	atf_tc_set_md_var(tc, "descr", "Verify that clone(%s) is "	\
7697	    "handled correctly with vfork(2)ed tracer", 		\
7698	    #flags);							\
7699}									\
7700									\
7701ATF_TC_BODY(name, tc)							\
7702{									\
7703									\
7704	traceme_vfork_clone_body(flags);				\
7705}
7706
7707TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone, 0)
7708TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vm, CLONE_VM)
7709TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_fs, CLONE_FS)
7710TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_files, CLONE_FILES)
7711//TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_sighand, CLONE_SIGHAND)  // XXX
7712TRACEME_VFORK_CLONE_TEST(traceme_vfork_clone_vfork, CLONE_VFORK)
7713#endif
7714
7715/// ----------------------------------------------------------------------------
7716
7717static void
7718user_va0_disable(int operation)
7719{
7720	pid_t child, wpid;
7721#if defined(TWAIT_HAVE_STATUS)
7722	int status;
7723#endif
7724	const int sigval = SIGSTOP;
7725	int rv;
7726
7727	struct ptrace_siginfo info;
7728
7729	if (get_user_va0_disable() == 0)
7730		atf_tc_skip("vm.user_va0_disable is set to 0");
7731
7732	memset(&info, 0, sizeof(info));
7733
7734	DPRINTF("Before forking process PID=%d\n", getpid());
7735	SYSCALL_REQUIRE((child = fork()) != -1);
7736	if (child == 0) {
7737		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7738		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7739
7740		DPRINTF("Before raising %s from child\n", strsignal(sigval));
7741		FORKEE_ASSERT(raise(sigval) == 0);
7742
7743		/* NOTREACHED */
7744		FORKEE_ASSERTX(0 && "This shall not be reached");
7745		__unreachable();
7746	}
7747	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7748
7749	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7750	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7751
7752	validate_status_stopped(status, sigval);
7753
7754	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
7755		"child\n");
7756	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
7757		sizeof(info)) != -1);
7758
7759	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
7760	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
7761		"si_errno=%#x\n",
7762		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
7763		info.psi_siginfo.si_errno);
7764
7765	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
7766	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
7767
7768	DPRINTF("Before resuming the child process in PC=0x0 "
7769	    "and without signal to be sent\n");
7770	errno = 0;
7771	rv = ptrace(operation, child, (void *)0, 0);
7772	ATF_REQUIRE_EQ(errno, EINVAL);
7773	ATF_REQUIRE_EQ(rv, -1);
7774
7775	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
7776
7777	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7778	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7779	validate_status_signaled(status, SIGKILL, 0);
7780
7781	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7782	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7783}
7784
7785#define USER_VA0_DISABLE(test, operation)				\
7786ATF_TC(test);								\
7787ATF_TC_HEAD(test, tc)							\
7788{									\
7789	atf_tc_set_md_var(tc, "descr",					\
7790	    "Verify behavior of " #operation " with PC set to 0x0");	\
7791}									\
7792									\
7793ATF_TC_BODY(test, tc)							\
7794{									\
7795									\
7796	user_va0_disable(operation);					\
7797}
7798
7799USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
7800USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
7801USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
7802
7803/// ----------------------------------------------------------------------------
7804
7805/*
7806 * Parse the core file and find the requested note.  If the reading or parsing
7807 * fails, the test is failed.  If the note is found, it is read onto buf, up to
7808 * buf_len.  The actual length of the note is returned (which can be greater
7809 * than buf_len, indicating that it has been truncated).  If the note is not
7810 * found, -1 is returned.
7811 *
7812 * If the note_name ends in '*', then we find the first note that matches
7813 * the note_name prefix up to the '*' character, e.g.:
7814 *
7815 *	NetBSD-CORE@*
7816 *
7817 * finds the first note whose name prefix matches "NetBSD-CORE@".
7818 */
7819static ssize_t core_find_note(const char *core_path,
7820    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
7821{
7822	int core_fd;
7823	Elf *core_elf;
7824	size_t core_numhdr, i;
7825	ssize_t ret = -1;
7826	size_t name_len = strlen(note_name);
7827	bool prefix_match = false;
7828
7829	if (note_name[name_len - 1] == '*') {
7830		prefix_match = true;
7831		name_len--;
7832	} else {
7833		/* note: we assume note name will be null-terminated */
7834		name_len++;
7835	}
7836
7837	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
7838	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
7839	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
7840
7841	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
7842	for (i = 0; i < core_numhdr && ret == -1; i++) {
7843		GElf_Phdr core_hdr;
7844		size_t offset;
7845		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
7846		if (core_hdr.p_type != PT_NOTE)
7847		    continue;
7848
7849		for (offset = core_hdr.p_offset;
7850		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
7851			Elf64_Nhdr note_hdr;
7852			char name_buf[64];
7853
7854			switch (gelf_getclass(core_elf)) {
7855			case ELFCLASS64:
7856				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
7857				    sizeof(note_hdr), offset)
7858				    == sizeof(note_hdr));
7859				offset += sizeof(note_hdr);
7860				break;
7861			case ELFCLASS32:
7862				{
7863				Elf32_Nhdr tmp_hdr;
7864				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
7865				    sizeof(tmp_hdr), offset)
7866				    == sizeof(tmp_hdr));
7867				offset += sizeof(tmp_hdr);
7868				note_hdr.n_namesz = tmp_hdr.n_namesz;
7869				note_hdr.n_descsz = tmp_hdr.n_descsz;
7870				note_hdr.n_type = tmp_hdr.n_type;
7871				}
7872				break;
7873			}
7874
7875			/* indicates end of notes */
7876			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
7877				break;
7878			if (((prefix_match &&
7879			      note_hdr.n_namesz > name_len) ||
7880			     (!prefix_match &&
7881			      note_hdr.n_namesz == name_len)) &&
7882			    note_hdr.n_namesz <= sizeof(name_buf)) {
7883				SYSCALL_REQUIRE(pread(core_fd, name_buf,
7884				    note_hdr.n_namesz, offset)
7885				    == (ssize_t)(size_t)note_hdr.n_namesz);
7886
7887				if (!strncmp(note_name, name_buf, name_len) &&
7888				    note_hdr.n_type == note_type)
7889					ret = note_hdr.n_descsz;
7890			}
7891
7892			offset += note_hdr.n_namesz;
7893			/* fix to alignment */
7894			offset = roundup(offset, core_hdr.p_align);
7895
7896			/* if name & type matched above */
7897			if (ret != -1) {
7898				ssize_t read_len = MIN(buf_len,
7899				    note_hdr.n_descsz);
7900				SYSCALL_REQUIRE(pread(core_fd, buf,
7901				    read_len, offset) == read_len);
7902				break;
7903			}
7904
7905			offset += note_hdr.n_descsz;
7906			/* fix to alignment */
7907			offset = roundup(offset, core_hdr.p_align);
7908		}
7909	}
7910
7911	elf_end(core_elf);
7912	close(core_fd);
7913
7914	return ret;
7915}
7916
7917ATF_TC(core_dump_procinfo);
7918ATF_TC_HEAD(core_dump_procinfo, tc)
7919{
7920	atf_tc_set_md_var(tc, "descr",
7921		"Trigger a core dump and verify its contents.");
7922}
7923
7924ATF_TC_BODY(core_dump_procinfo, tc)
7925{
7926	const int exitval = 5;
7927	pid_t child, wpid;
7928#if defined(TWAIT_HAVE_STATUS)
7929	const int sigval = SIGTRAP;
7930	int status;
7931#endif
7932	char core_path[] = "/tmp/core.XXXXXX";
7933	int core_fd;
7934	struct netbsd_elfcore_procinfo procinfo;
7935
7936	DPRINTF("Before forking process PID=%d\n", getpid());
7937	SYSCALL_REQUIRE((child = fork()) != -1);
7938	if (child == 0) {
7939		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
7940		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
7941
7942		DPRINTF("Before triggering SIGTRAP\n");
7943		trigger_trap();
7944
7945		DPRINTF("Before exiting of the child process\n");
7946		_exit(exitval);
7947	}
7948	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
7949
7950	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7951	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7952
7953	validate_status_stopped(status, sigval);
7954
7955	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
7956	close(core_fd);
7957
7958	DPRINTF("Call DUMPCORE for the child process\n");
7959	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
7960	    != -1);
7961
7962	DPRINTF("Read core file\n");
7963	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
7964	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
7965	    sizeof(procinfo));
7966
7967	ATF_CHECK_EQ(procinfo.cpi_version, 1);
7968	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
7969	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
7970	ATF_CHECK_EQ(procinfo.cpi_pid, child);
7971	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
7972	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
7973	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
7974	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
7975	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
7976	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
7977	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
7978	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
7979	ATF_CHECK(procinfo.cpi_siglwp > 0);
7980
7981	unlink(core_path);
7982
7983	DPRINTF("Before resuming the child process where it left off and "
7984	    "without signal to be sent\n");
7985	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
7986
7987	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7988	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
7989
7990	validate_status_exited(status, exitval);
7991
7992	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
7993	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
7994}
7995
7996/// ----------------------------------------------------------------------------
7997
7998#if defined(TWAIT_HAVE_STATUS)
7999
8000#define THREAD_CONCURRENT_BREAKPOINT_NUM 50
8001#define THREAD_CONCURRENT_SIGNALS_NUM 50
8002#define THREAD_CONCURRENT_WATCHPOINT_NUM 50
8003
8004/* List of signals to use for the test */
8005const int thread_concurrent_signals_list[] = {
8006	SIGIO,
8007	SIGXCPU,
8008	SIGXFSZ,
8009	SIGVTALRM,
8010	SIGPROF,
8011	SIGWINCH,
8012	SIGINFO,
8013	SIGUSR1,
8014	SIGUSR2
8015};
8016
8017enum thread_concurrent_signal_handling {
8018	/* the signal is discarded by debugger */
8019	TCSH_DISCARD,
8020	/* the handler is set to SIG_IGN */
8021	TCSH_SIG_IGN,
8022	/* an actual handler is used */
8023	TCSH_HANDLER
8024};
8025
8026static pthread_barrier_t thread_concurrent_barrier;
8027static pthread_key_t thread_concurrent_key;
8028static uint32_t thread_concurrent_watchpoint_var = 0;
8029
8030static void *
8031thread_concurrent_breakpoint_thread(void *arg)
8032{
8033	static volatile int watchme = 1;
8034	pthread_barrier_wait(&thread_concurrent_barrier);
8035	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
8036	check_happy(watchme);
8037	return NULL;
8038}
8039
8040static void
8041thread_concurrent_sig_handler(int sig)
8042{
8043	void *tls_val = pthread_getspecific(thread_concurrent_key);
8044	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
8045	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
8046	    (void*)((uintptr_t)tls_val + 1)) == 0);
8047}
8048
8049static void *
8050thread_concurrent_signals_thread(void *arg)
8051{
8052	int sigval = thread_concurrent_signals_list[
8053	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
8054	enum thread_concurrent_signal_handling *signal_handle = arg;
8055	void *tls_val;
8056
8057	pthread_barrier_wait(&thread_concurrent_barrier);
8058	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
8059		_lwp_self());
8060	pthread_kill(pthread_self(), sigval);
8061	if (*signal_handle == TCSH_HANDLER) {
8062	    tls_val = pthread_getspecific(thread_concurrent_key);
8063	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
8064	    FORKEE_ASSERT(tls_val == (void*)1);
8065	}
8066	return NULL;
8067}
8068
8069static void *
8070thread_concurrent_watchpoint_thread(void *arg)
8071{
8072	pthread_barrier_wait(&thread_concurrent_barrier);
8073	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
8074	thread_concurrent_watchpoint_var = 1;
8075	return NULL;
8076}
8077
8078#if defined(__i386__) || defined(__x86_64__)
8079enum thread_concurrent_sigtrap_event {
8080	TCSE_UNKNOWN,
8081	TCSE_BREAKPOINT,
8082	TCSE_WATCHPOINT
8083};
8084
8085static void
8086thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
8087static enum thread_concurrent_sigtrap_event
8088thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
8089#endif
8090
8091static void
8092thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
8093    int breakpoint_threads, int signal_threads, int watchpoint_threads)
8094{
8095	const int exitval = 5;
8096	const int sigval = SIGSTOP;
8097	pid_t child, wpid;
8098	int status;
8099	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
8100	    = {{0, 0}};
8101	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
8102	    = {{0, 0}};
8103	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
8104	    = {{0, 0}};
8105	ptrace_event_t event;
8106	int i;
8107
8108#if defined(HAVE_DBREGS)
8109	if (!can_we_set_dbregs()) {
8110		atf_tc_skip("Either run this test as root or set sysctl(3) "
8111		            "security.models.extensions.user_set_dbregs to 1");
8112        }
8113#endif
8114
8115	atf_tc_skip("PR kern/54960");
8116
8117	/* Protect against out-of-bounds array access. */
8118	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
8119	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
8120	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
8121
8122	DPRINTF("Before forking process PID=%d\n", getpid());
8123	SYSCALL_REQUIRE((child = fork()) != -1);
8124	if (child == 0) {
8125		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
8126		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
8127		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
8128
8129		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
8130		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
8131
8132		DPRINTF("Before raising %s from child\n", strsignal(sigval));
8133		FORKEE_ASSERT(raise(sigval) == 0);
8134
8135		if (signal_handle != TCSH_DISCARD) {
8136			struct sigaction sa;
8137			unsigned int j;
8138
8139			memset(&sa, 0, sizeof(sa));
8140			if (signal_handle == TCSH_SIG_IGN)
8141				sa.sa_handler = SIG_IGN;
8142			else
8143				sa.sa_handler = thread_concurrent_sig_handler;
8144			sigemptyset(&sa.sa_mask);
8145
8146			for (j = 0;
8147			    j < __arraycount(thread_concurrent_signals_list);
8148			    j++)
8149				FORKEE_ASSERT(sigaction(
8150				    thread_concurrent_signals_list[j], &sa, NULL)
8151				    != -1);
8152		}
8153
8154		DPRINTF("Before starting threads from the child\n");
8155		FORKEE_ASSERT(pthread_barrier_init(
8156		    &thread_concurrent_barrier, NULL,
8157		    breakpoint_threads + signal_threads + watchpoint_threads)
8158		    == 0);
8159		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
8160		    == 0);
8161
8162		for (i = 0; i < signal_threads; i++) {
8163			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
8164			    thread_concurrent_signals_thread,
8165			    &signal_handle) == 0);
8166		}
8167		for (i = 0; i < breakpoint_threads; i++) {
8168			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
8169			    thread_concurrent_breakpoint_thread, NULL) == 0);
8170		}
8171		for (i = 0; i < watchpoint_threads; i++) {
8172			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
8173			    thread_concurrent_watchpoint_thread, NULL) == 0);
8174		}
8175
8176		DPRINTF("Before joining threads from the child\n");
8177		for (i = 0; i < watchpoint_threads; i++) {
8178			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
8179		}
8180		for (i = 0; i < breakpoint_threads; i++) {
8181			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
8182		}
8183		for (i = 0; i < signal_threads; i++) {
8184			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
8185		}
8186
8187		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
8188		FORKEE_ASSERT(pthread_barrier_destroy(
8189		    &thread_concurrent_barrier) == 0);
8190
8191		DPRINTF("Before exiting of the child process\n");
8192		_exit(exitval);
8193	}
8194	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
8195
8196	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8197	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
8198
8199	validate_status_stopped(status, sigval);
8200
8201	DPRINTF("Set LWP event mask for the child process\n");
8202	memset(&event, 0, sizeof(event));
8203	event.pe_set_event |= PTRACE_LWP_CREATE;
8204	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
8205	    != -1);
8206
8207	DPRINTF("Before resuming the child process where it left off\n");
8208	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
8209
8210	DPRINTF("Before entering signal collection loop\n");
8211	while (1) {
8212		ptrace_siginfo_t info;
8213
8214		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
8215		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
8216		    child);
8217		if (WIFEXITED(status))
8218			break;
8219		/* Note: we use validate_status_stopped() to get nice error
8220		 * message.  Signal is irrelevant since it won't be reached.
8221		 */
8222		else if (!WIFSTOPPED(status))
8223			validate_status_stopped(status, 0);
8224
8225		DPRINTF("Before calling PT_GET_SIGINFO\n");
8226		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
8227		    sizeof(info)) != -1);
8228
8229		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
8230		    info.psi_siginfo.si_signo, info.psi_lwpid,
8231		    WSTOPSIG(status));
8232
8233		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
8234		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
8235		    WSTOPSIG(status), info.psi_siginfo.si_signo);
8236
8237		if (WSTOPSIG(status) != SIGTRAP) {
8238			int expected_sig =
8239			    thread_concurrent_signals_list[info.psi_lwpid %
8240			    __arraycount(thread_concurrent_signals_list)];
8241			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
8242				"lwp=%d, expected %d, got %d", info.psi_lwpid,
8243				expected_sig, WSTOPSIG(status));
8244
8245			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
8246		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
8247#if defined(__i386__) || defined(__x86_64__)
8248			thread_concurrent_lwp_setup(child, info.psi_lwpid);
8249#endif
8250		} else {
8251#if defined(__i386__) || defined(__x86_64__)
8252			switch (thread_concurrent_handle_sigtrap(child, &info)) {
8253				case TCSE_UNKNOWN:
8254					/* already reported inside the function */
8255					break;
8256				case TCSE_BREAKPOINT:
8257					*FIND_EVENT_COUNT(bp_counts,
8258					    info.psi_lwpid) += 1;
8259					break;
8260				case TCSE_WATCHPOINT:
8261					*FIND_EVENT_COUNT(wp_counts,
8262					    info.psi_lwpid) += 1;
8263					break;
8264			}
8265#else
8266			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
8267			    info.psi_siginfo.si_code);
8268#endif
8269		}
8270
8271		DPRINTF("Before resuming the child process\n");
8272		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
8273		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
8274		     ? WSTOPSIG(status) : 0) != -1);
8275	}
8276
8277	for (i = 0; i < signal_threads; i++)
8278		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
8279		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
8280		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
8281	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
8282		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
8283		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
8284		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
8285
8286	for (i = 0; i < breakpoint_threads; i++)
8287		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
8288		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
8289		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
8290	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
8291		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
8292		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
8293		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
8294
8295	for (i = 0; i < watchpoint_threads; i++)
8296		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
8297		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
8298		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
8299	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
8300		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
8301		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
8302		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
8303
8304	validate_status_exited(status, exitval);
8305}
8306
8307#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
8308ATF_TC(test);								\
8309ATF_TC_HEAD(test, tc)							\
8310{									\
8311	atf_tc_set_md_var(tc, "descr", descr);				\
8312}									\
8313									\
8314ATF_TC_BODY(test, tc)							\
8315{									\
8316	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
8317}
8318
8319THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
8320    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8321    "Verify that concurrent signals issued to a single thread are reported "
8322    "correctly");
8323THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
8324    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8325    "Verify that concurrent signals issued to a single thread are reported "
8326    "correctly and passed back to SIG_IGN handler");
8327THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
8328    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8329    "Verify that concurrent signals issued to a single thread are reported "
8330    "correctly and passed back to a handler function");
8331
8332#if defined(__i386__) || defined(__x86_64__)
8333THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
8334    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
8335    "Verify that concurrent breakpoints are reported correctly");
8336THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
8337    0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
8338    "Verify that concurrent breakpoints are reported correctly");
8339THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
8340    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
8341    "Verify that concurrent breakpoints and watchpoints are reported "
8342    "correctly");
8343
8344THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
8345    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8346    "Verify that concurrent breakpoints and signals are reported correctly");
8347THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
8348    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8349    "Verify that concurrent breakpoints and signals are reported correctly "
8350    "and passed back to SIG_IGN handler");
8351THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
8352    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
8353    "Verify that concurrent breakpoints and signals are reported correctly "
8354    "and passed back to a handler function");
8355
8356THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
8357    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8358    "Verify that concurrent watchpoints and signals are reported correctly");
8359THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
8360    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8361    "Verify that concurrent watchpoints and signals are reported correctly "
8362    "and passed back to SIG_IGN handler");
8363THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
8364    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
8365    "Verify that concurrent watchpoints and signals are reported correctly "
8366    "and passed back to a handler function");
8367
8368THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
8369    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8370    THREAD_CONCURRENT_WATCHPOINT_NUM,
8371    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8372    "correctly");
8373THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
8374    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8375    THREAD_CONCURRENT_WATCHPOINT_NUM,
8376    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8377    "correctly and passed back to SIG_IGN handler");
8378THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
8379    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
8380    THREAD_CONCURRENT_WATCHPOINT_NUM,
8381    "Verify that concurrent breakpoints, watchpoints and signals are reported "
8382    "correctly and passed back to a handler function");
8383#endif
8384
8385#endif /*defined(TWAIT_HAVE_STATUS)*/
8386
8387/// ----------------------------------------------------------------------------
8388
8389#include "t_ptrace_register_wait.h"
8390#include "t_ptrace_syscall_wait.h"
8391#include "t_ptrace_step_wait.h"
8392#include "t_ptrace_kill_wait.h"
8393
8394/// ----------------------------------------------------------------------------
8395
8396#include "t_ptrace_amd64_wait.h"
8397#include "t_ptrace_i386_wait.h"
8398#include "t_ptrace_x86_wait.h"
8399
8400/// ----------------------------------------------------------------------------
8401
8402#else
8403ATF_TC(dummy);
8404ATF_TC_HEAD(dummy, tc)
8405{
8406	atf_tc_set_md_var(tc, "descr", "A dummy test");
8407}
8408
8409ATF_TC_BODY(dummy, tc)
8410{
8411
8412	// Dummy, skipped
8413	// The ATF framework requires at least a single defined test.
8414}
8415#endif
8416
8417ATF_TP_ADD_TCS(tp)
8418{
8419	setvbuf(stdout, NULL, _IONBF, 0);
8420	setvbuf(stderr, NULL, _IONBF, 0);
8421
8422#ifdef ENABLE_TESTS
8423	ATF_TP_ADD_TC(tp, traceme_raise1);
8424	ATF_TP_ADD_TC(tp, traceme_raise2);
8425	ATF_TP_ADD_TC(tp, traceme_raise3);
8426	ATF_TP_ADD_TC(tp, traceme_raise4);
8427	ATF_TP_ADD_TC(tp, traceme_raise5);
8428	ATF_TP_ADD_TC(tp, traceme_raise6);
8429	ATF_TP_ADD_TC(tp, traceme_raise7);
8430	ATF_TP_ADD_TC(tp, traceme_raise8);
8431	ATF_TP_ADD_TC(tp, traceme_raise9);
8432	ATF_TP_ADD_TC(tp, traceme_raise10);
8433
8434	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored1);
8435	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored2);
8436	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored3);
8437	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored4);
8438	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored5);
8439	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored6);
8440	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored7);
8441	ATF_TP_ADD_TC(tp, traceme_raisesignal_ignored8);
8442
8443	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked1);
8444	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked2);
8445	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked3);
8446	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked4);
8447	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked5);
8448	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked6);
8449	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked7);
8450	ATF_TP_ADD_TC(tp, traceme_raisesignal_masked8);
8451
8452	ATF_TP_ADD_TC(tp, traceme_crash_trap);
8453	ATF_TP_ADD_TC(tp, traceme_crash_segv);
8454	ATF_TP_ADD_TC(tp, traceme_crash_ill);
8455	ATF_TP_ADD_TC(tp, traceme_crash_fpe);
8456	ATF_TP_ADD_TC(tp, traceme_crash_bus);
8457
8458	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_trap);
8459	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_segv);
8460	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_ill);
8461	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_fpe);
8462	ATF_TP_ADD_TC(tp, traceme_signalmasked_crash_bus);
8463
8464	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_trap);
8465	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_segv);
8466	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_ill);
8467	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_fpe);
8468	ATF_TP_ADD_TC(tp, traceme_signalignored_crash_bus);
8469
8470	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle1);
8471	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle2);
8472	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle3);
8473	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle4);
8474	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle5);
8475	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle6);
8476	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle7);
8477	ATF_TP_ADD_TC(tp, traceme_sendsignal_handle8);
8478
8479	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked1);
8480	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked2);
8481	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked3);
8482	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked4);
8483	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked5);
8484	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked6);
8485	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked7);
8486	ATF_TP_ADD_TC(tp, traceme_sendsignal_masked8);
8487
8488	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored1);
8489	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored2);
8490	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored3);
8491	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored4);
8492	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored5);
8493	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored6);
8494	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored7);
8495	ATF_TP_ADD_TC(tp, traceme_sendsignal_ignored8);
8496
8497	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple1);
8498	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple2);
8499	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple3);
8500	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple4);
8501	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple5);
8502	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple6);
8503	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple7);
8504	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple8);
8505	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple9);
8506	ATF_TP_ADD_TC(tp, traceme_sendsignal_simple10);
8507
8508	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
8509
8510	ATF_TP_ADD_TC(tp, traceme_vfork_raise1);
8511	ATF_TP_ADD_TC(tp, traceme_vfork_raise2);
8512	ATF_TP_ADD_TC(tp, traceme_vfork_raise3);
8513	ATF_TP_ADD_TC(tp, traceme_vfork_raise4);
8514	ATF_TP_ADD_TC(tp, traceme_vfork_raise5);
8515	ATF_TP_ADD_TC(tp, traceme_vfork_raise6);
8516	ATF_TP_ADD_TC(tp, traceme_vfork_raise7);
8517	ATF_TP_ADD_TC(tp, traceme_vfork_raise8);
8518	ATF_TP_ADD_TC(tp, traceme_vfork_raise9);
8519	ATF_TP_ADD_TC(tp, traceme_vfork_raise10);
8520	ATF_TP_ADD_TC(tp, traceme_vfork_raise11);
8521	ATF_TP_ADD_TC(tp, traceme_vfork_raise12);
8522	ATF_TP_ADD_TC(tp, traceme_vfork_raise13);
8523
8524	ATF_TP_ADD_TC(tp, traceme_vfork_crash_trap);
8525	ATF_TP_ADD_TC(tp, traceme_vfork_crash_segv);
8526	ATF_TP_ADD_TC(tp, traceme_vfork_crash_ill);
8527	ATF_TP_ADD_TC(tp, traceme_vfork_crash_fpe);
8528	ATF_TP_ADD_TC(tp, traceme_vfork_crash_bus);
8529
8530	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_trap);
8531	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_segv);
8532	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_ill);
8533	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_fpe);
8534	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_crash_bus);
8535
8536	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_trap);
8537	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_segv);
8538	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_ill);
8539	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_fpe);
8540	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_crash_bus);
8541
8542	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
8543	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
8544	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
8545
8546	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_trap);
8547	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_segv);
8548	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_ill);
8549	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_fpe);
8550	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_sees_crash_bus);
8551
8552	ATF_TP_ADD_TC_HAVE_PID(tp,
8553	    unrelated_tracer_sees_signalmasked_crash_trap);
8554	ATF_TP_ADD_TC_HAVE_PID(tp,
8555	    unrelated_tracer_sees_signalmasked_crash_segv);
8556	ATF_TP_ADD_TC_HAVE_PID(tp,
8557	    unrelated_tracer_sees_signalmasked_crash_ill);
8558	ATF_TP_ADD_TC_HAVE_PID(tp,
8559	    unrelated_tracer_sees_signalmasked_crash_fpe);
8560	ATF_TP_ADD_TC_HAVE_PID(tp,
8561	    unrelated_tracer_sees_signalmasked_crash_bus);
8562
8563	ATF_TP_ADD_TC_HAVE_PID(tp,
8564	    unrelated_tracer_sees_signalignored_crash_trap);
8565	ATF_TP_ADD_TC_HAVE_PID(tp,
8566	    unrelated_tracer_sees_signalignored_crash_segv);
8567	ATF_TP_ADD_TC_HAVE_PID(tp,
8568	    unrelated_tracer_sees_signalignored_crash_ill);
8569	ATF_TP_ADD_TC_HAVE_PID(tp,
8570	    unrelated_tracer_sees_signalignored_crash_fpe);
8571	ATF_TP_ADD_TC_HAVE_PID(tp,
8572	    unrelated_tracer_sees_signalignored_crash_bus);
8573
8574	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
8575	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
8576	ATF_TP_ADD_TC_HAVE_PID(tp,
8577		unrelated_tracer_sees_terminaton_before_the_parent);
8578	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
8579
8580	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
8581	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
8582
8583	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
8584	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
8585
8586	ATF_TP_ADD_TC_HAVE_PID(tp,
8587		tracee_sees_its_original_parent_getppid);
8588	ATF_TP_ADD_TC_HAVE_PID(tp,
8589		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
8590	ATF_TP_ADD_TC_HAVE_PID(tp,
8591		tracee_sees_its_original_parent_procfs_status);
8592
8593	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
8594	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
8595	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
8596	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
8597	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
8598	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
8599	ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn);
8600
8601	ATF_TP_ADD_TC(tp, fork1);
8602	ATF_TP_ADD_TC_HAVE_PID(tp, fork2);
8603	ATF_TP_ADD_TC_HAVE_PID(tp, fork3);
8604	ATF_TP_ADD_TC_HAVE_PID(tp, fork4);
8605	ATF_TP_ADD_TC(tp, fork5);
8606	ATF_TP_ADD_TC_HAVE_PID(tp, fork6);
8607	ATF_TP_ADD_TC_HAVE_PID(tp, fork7);
8608	ATF_TP_ADD_TC_HAVE_PID(tp, fork8);
8609	ATF_TP_ADD_TC(tp, fork9);
8610	ATF_TP_ADD_TC_HAVE_PID(tp, fork10);
8611	ATF_TP_ADD_TC_HAVE_PID(tp, fork11);
8612	ATF_TP_ADD_TC_HAVE_PID(tp, fork12);
8613	ATF_TP_ADD_TC(tp, fork13);
8614	ATF_TP_ADD_TC_HAVE_PID(tp, fork14);
8615	ATF_TP_ADD_TC_HAVE_PID(tp, fork15);
8616	ATF_TP_ADD_TC_HAVE_PID(tp, fork16);
8617
8618	ATF_TP_ADD_TC(tp, vfork1);
8619	ATF_TP_ADD_TC_HAVE_PID(tp, vfork2);
8620	ATF_TP_ADD_TC_HAVE_PID(tp, vfork3);
8621	ATF_TP_ADD_TC_HAVE_PID(tp, vfork4);
8622	ATF_TP_ADD_TC(tp, vfork5);
8623	ATF_TP_ADD_TC_HAVE_PID(tp, vfork6);
8624	ATF_TP_ADD_TC_HAVE_PID(tp, vfork7);
8625	ATF_TP_ADD_TC_HAVE_PID(tp, vfork8);
8626	ATF_TP_ADD_TC(tp, vfork9);
8627	ATF_TP_ADD_TC_HAVE_PID(tp, vfork10);
8628	ATF_TP_ADD_TC_HAVE_PID(tp, vfork11);
8629	ATF_TP_ADD_TC_HAVE_PID(tp, vfork12);
8630	ATF_TP_ADD_TC(tp, vfork13);
8631	ATF_TP_ADD_TC_HAVE_PID(tp, vfork14);
8632	ATF_TP_ADD_TC_HAVE_PID(tp, vfork15);
8633	ATF_TP_ADD_TC_HAVE_PID(tp, vfork16);
8634
8635	ATF_TP_ADD_TC(tp, posix_spawn1);
8636	ATF_TP_ADD_TC(tp, posix_spawn2);
8637	ATF_TP_ADD_TC(tp, posix_spawn3);
8638	ATF_TP_ADD_TC(tp, posix_spawn4);
8639	ATF_TP_ADD_TC(tp, posix_spawn5);
8640	ATF_TP_ADD_TC(tp, posix_spawn6);
8641	ATF_TP_ADD_TC(tp, posix_spawn7);
8642	ATF_TP_ADD_TC(tp, posix_spawn8);
8643	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn9);
8644	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn10);
8645	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn11);
8646	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn12);
8647	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn13);
8648	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn14);
8649	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn15);
8650	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn16);
8651
8652	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork1);
8653	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork2);
8654	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork3);
8655	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork4);
8656	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork5);
8657	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork6);
8658	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork7);
8659	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork8);
8660	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork9);
8661	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork10);
8662	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork11);
8663	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork12);
8664	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork13);
8665	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork14);
8666	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork15);
8667	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork16);
8668
8669	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork1);
8670	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork2);
8671	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork3);
8672	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork4);
8673	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork5);
8674	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork6);
8675	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork7);
8676	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork8);
8677	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork9);
8678	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork10);
8679	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork11);
8680	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork12);
8681	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork13);
8682	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork14);
8683	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork15);
8684	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork16);
8685
8686	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn1);
8687	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn2);
8688	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn3);
8689	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn4);
8690	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn5);
8691	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn6);
8692	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn7);
8693	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn8);
8694	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn9);
8695	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn10);
8696	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn11);
8697	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn12);
8698	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn13);
8699	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn14);
8700	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn15);
8701	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn16);
8702
8703	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_detach_spawner);
8704	ATF_TP_ADD_TC_HAVE_PID(tp, fork_detach_forker);
8705	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforker);
8706	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_detach_vforkerdone);
8707
8708	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_kill_spawner);
8709	ATF_TP_ADD_TC_HAVE_PID(tp, fork_kill_forker);
8710	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforker);
8711	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_kill_vforkerdone);
8712
8713	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_detach_spawner);
8714	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_detach_forker);
8715	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforker);
8716	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_detach_vforkerdone);
8717
8718	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_posix_spawn_kill_spawner);
8719	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_fork_kill_forker);
8720	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforker);
8721	ATF_TP_ADD_TC_HAVE_PID(tp, unrelated_tracer_vfork_kill_vforkerdone);
8722
8723	ATF_TP_ADD_TC(tp, traceme_vfork_fork);
8724	ATF_TP_ADD_TC(tp, traceme_vfork_vfork);
8725
8726	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8);
8727	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16);
8728	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32);
8729	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64);
8730
8731	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8);
8732	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16);
8733	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32);
8734	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64);
8735
8736	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8);
8737	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16);
8738	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32);
8739	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64);
8740
8741	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8);
8742	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16);
8743	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32);
8744	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64);
8745
8746	ATF_TP_ADD_TC(tp, bytes_transfer_read_d);
8747	ATF_TP_ADD_TC(tp, bytes_transfer_read_i);
8748	ATF_TP_ADD_TC(tp, bytes_transfer_write_d);
8749	ATF_TP_ADD_TC(tp, bytes_transfer_write_i);
8750
8751	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_8_text);
8752	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_16_text);
8753	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_32_text);
8754	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_d_64_text);
8755
8756	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_8_text);
8757	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_16_text);
8758	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_32_text);
8759	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_i_64_text);
8760
8761	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_8_text);
8762	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_16_text);
8763	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_32_text);
8764	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_d_64_text);
8765
8766	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_8_text);
8767	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_16_text);
8768	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_32_text);
8769	ATF_TP_ADD_TC(tp, bytes_transfer_piod_write_i_64_text);
8770
8771	ATF_TP_ADD_TC(tp, bytes_transfer_read_d_text);
8772	ATF_TP_ADD_TC(tp, bytes_transfer_read_i_text);
8773	ATF_TP_ADD_TC(tp, bytes_transfer_write_d_text);
8774	ATF_TP_ADD_TC(tp, bytes_transfer_write_i_text);
8775
8776	ATF_TP_ADD_TC(tp, bytes_transfer_piod_read_auxv);
8777
8778	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_i);
8779	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_read_d);
8780	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_i);
8781	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_pt_write_d);
8782
8783	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_i);
8784	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_d);
8785	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_i);
8786	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_write_d);
8787
8788	ATF_TP_ADD_TC(tp, bytes_transfer_alignment_piod_read_auxv);
8789
8790	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_i);
8791	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_read_d);
8792	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_i);
8793	ATF_TP_ADD_TC(tp, bytes_transfer_eof_pt_write_d);
8794
8795	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_i);
8796	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_read_d);
8797	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_i);
8798	ATF_TP_ADD_TC(tp, bytes_transfer_eof_piod_write_d);
8799
8800	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
8801	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
8802	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
8803	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
8804
8805	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus);
8806	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus);
8807	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus);
8808	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus);
8809
8810	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask);
8811	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask);
8812	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask);
8813	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask);
8814
8815	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name);
8816	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name);
8817	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name);
8818	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name);
8819
8820	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private);
8821	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private);
8822	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private);
8823	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private);
8824
8825	ATF_TP_ADD_TC(tp, traceme_lwpnext0);
8826	ATF_TP_ADD_TC(tp, traceme_lwpnext1);
8827	ATF_TP_ADD_TC(tp, traceme_lwpnext2);
8828	ATF_TP_ADD_TC(tp, traceme_lwpnext3);
8829
8830	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask);
8831	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask);
8832	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask);
8833	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask);
8834
8835	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name);
8836	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name);
8837	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name);
8838	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name);
8839
8840	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private);
8841	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private);
8842	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private);
8843	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private);
8844
8845	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
8846	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
8847	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
8848	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
8849
8850	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
8851	ATF_TP_ADD_TC(tp, siginfo_set_faked);
8852
8853	ATF_TP_ADD_TC(tp, traceme_exec);
8854	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
8855	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
8856
8857	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
8858	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
8859	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
8860	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
8861
8862	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap);
8863	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap);
8864	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap);
8865
8866	ATF_TP_ADD_TC(tp, signal_mask_unrelated);
8867
8868	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalmasked);
8869	ATF_TP_ADD_TC_HAVE_PID(tp, posix_spawn_singalignored);
8870	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalmasked);
8871	ATF_TP_ADD_TC_HAVE_PID(tp, fork_singalignored);
8872	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalmasked);
8873	ATF_TP_ADD_TC_HAVE_PID(tp, vfork_singalignored);
8874	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalmasked);
8875	ATF_TP_ADD_TC_HAVE_PID(tp, vforkdone_singalignored);
8876
8877	ATF_TP_ADD_TC(tp, threads_and_exec);
8878
8879	ATF_TP_ADD_TC(tp, suspend_no_deadlock);
8880
8881	ATF_TP_ADD_TC(tp, resume);
8882
8883	ATF_TP_ADD_TC(tp, clone1);
8884	ATF_TP_ADD_TC_HAVE_PID(tp, clone2);
8885	ATF_TP_ADD_TC_HAVE_PID(tp, clone3);
8886	ATF_TP_ADD_TC_HAVE_PID(tp, clone4);
8887	ATF_TP_ADD_TC(tp, clone5);
8888	ATF_TP_ADD_TC_HAVE_PID(tp, clone6);
8889	ATF_TP_ADD_TC_HAVE_PID(tp, clone7);
8890	ATF_TP_ADD_TC_HAVE_PID(tp, clone8);
8891
8892	ATF_TP_ADD_TC(tp, clone_vm1);
8893	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm2);
8894	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm3);
8895	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm4);
8896	ATF_TP_ADD_TC(tp, clone_vm5);
8897	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm6);
8898	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm7);
8899	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm8);
8900
8901	ATF_TP_ADD_TC(tp, clone_fs1);
8902	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs2);
8903	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs3);
8904	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs4);
8905	ATF_TP_ADD_TC(tp, clone_fs5);
8906	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs6);
8907	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs7);
8908	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs8);
8909
8910	ATF_TP_ADD_TC(tp, clone_files1);
8911	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files2);
8912	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files3);
8913	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files4);
8914	ATF_TP_ADD_TC(tp, clone_files5);
8915	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files6);
8916	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files7);
8917	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files8);
8918
8919//	ATF_TP_ADD_TC(tp, clone_sighand1); // XXX
8920//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand2); // XXX
8921//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand3); // XXX
8922//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand4); // XXX
8923//	ATF_TP_ADD_TC(tp, clone_sighand5); // XXX
8924//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand6); // XXX
8925//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand7); // XXX
8926//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand8); // XXX
8927
8928	ATF_TP_ADD_TC(tp, clone_vfork1);
8929	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork2);
8930	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork3);
8931	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork4);
8932	ATF_TP_ADD_TC(tp, clone_vfork5);
8933	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork6);
8934	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork7);
8935	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork8);
8936
8937	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalignored);
8938	ATF_TP_ADD_TC_HAVE_PID(tp, clone_signalmasked);
8939	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalignored);
8940	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vm_signalmasked);
8941	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalignored);
8942	ATF_TP_ADD_TC_HAVE_PID(tp, clone_fs_signalmasked);
8943	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalignored);
8944	ATF_TP_ADD_TC_HAVE_PID(tp, clone_files_signalmasked);
8945//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalignored); // XXX
8946//	ATF_TP_ADD_TC_HAVE_PID(tp, clone_sighand_signalmasked); // XXX
8947	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalignored);
8948	ATF_TP_ADD_TC_HAVE_PID(tp, clone_vfork_signalmasked);
8949
8950	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone);
8951	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vm);
8952	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_fs);
8953	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_files);
8954//	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_sighand); // XXX
8955	ATF_TP_ADD_TC_HAVE_PID(tp, traceme_vfork_clone_vfork);
8956
8957	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
8958	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
8959	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
8960
8961	ATF_TP_ADD_TC(tp, core_dump_procinfo);
8962
8963#if defined(TWAIT_HAVE_STATUS)
8964	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
8965	ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign);
8966	ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler);
8967#if defined(__i386__) || defined(__x86_64__)
8968	ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints);
8969	ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints);
8970	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp);
8971	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig);
8972	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign);
8973	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler);
8974	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig);
8975	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign);
8976	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler);
8977	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig);
8978	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign);
8979	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler);
8980#endif
8981#endif
8982
8983	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
8984	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
8985	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
8986	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
8987
8988	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
8989	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
8990	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
8991
8992#else
8993	ATF_TP_ADD_TC(tp, dummy);
8994#endif
8995
8996	return atf_no_error();
8997}
8998