t_ptrace_wait.c revision 1.182
1/*	$NetBSD: t_ptrace_wait.c,v 1.182 2020/05/04 23:53:20 kamil Exp $	*/
2
3/*-
4 * Copyright (c) 2016, 2017, 2018, 2019, 2020 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.182 2020/05/04 23:53:20 kamil Exp $");
31
32#define __LEGACY_PT_LWPINFO
33
34#include <sys/param.h>
35#include <sys/types.h>
36#include <sys/exec_elf.h>
37#include <sys/mman.h>
38#include <sys/ptrace.h>
39#include <sys/resource.h>
40#include <sys/stat.h>
41#include <sys/syscall.h>
42#include <sys/sysctl.h>
43#include <sys/uio.h>
44#include <sys/wait.h>
45#include <machine/reg.h>
46#include <assert.h>
47#include <elf.h>
48#include <err.h>
49#include <errno.h>
50#include <fcntl.h>
51#include <lwp.h>
52#include <pthread.h>
53#include <sched.h>
54#include <signal.h>
55#include <spawn.h>
56#include <stdint.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <strings.h>
60#include <time.h>
61#include <unistd.h>
62
63#if defined(__i386__) || defined(__x86_64__)
64#include <cpuid.h>
65#include <x86/cpu_extended_state.h>
66#include <x86/specialreg.h>
67#endif
68
69#include <libelf.h>
70#include <gelf.h>
71
72#include <atf-c.h>
73
74#ifdef ENABLE_TESTS
75
76/* Assumptions in the kernel code that must be kept. */
77__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_report_event) ==
78    sizeof(((siginfo_t *)0)->si_pe_report_event));
79__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
80    sizeof(((siginfo_t *)0)->si_pe_other_pid));
81__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_lwp) ==
82    sizeof(((siginfo_t *)0)->si_pe_lwp));
83__CTASSERT(sizeof(((struct ptrace_state *)0)->pe_other_pid) ==
84    sizeof(((struct ptrace_state *)0)->pe_lwp));
85
86#include "h_macros.h"
87
88#include "t_ptrace_wait.h"
89#include "msg.h"
90
91#define SYSCALL_REQUIRE(expr) ATF_REQUIRE_MSG(expr, "%s: %s", # expr, \
92    strerror(errno))
93#define SYSCALL_REQUIRE_ERRNO(res, exp) ATF_REQUIRE_MSG(res == exp, \
94    "%d(%s) != %d", res, strerror(res), exp)
95
96static int debug = 0;
97
98#define DPRINTF(a, ...)	do  \
99	if (debug) \
100	printf("%s() %d.%d %s:%d " a, \
101	__func__, getpid(), _lwp_self(), __FILE__, __LINE__,  ##__VA_ARGS__); \
102    while (/*CONSTCOND*/0)
103
104/// ----------------------------------------------------------------------------
105
106ATF_TC(traceme_pid1_parent);
107ATF_TC_HEAD(traceme_pid1_parent, tc)
108{
109	atf_tc_set_md_var(tc, "descr",
110	    "Verify that PT_TRACE_ME is not allowed when our parent is PID1");
111}
112
113ATF_TC_BODY(traceme_pid1_parent, tc)
114{
115	struct msg_fds parent_child;
116	int exitval_child1 = 1, exitval_child2 = 2;
117	pid_t child1, child2, wpid;
118	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
119#if defined(TWAIT_HAVE_STATUS)
120	int status;
121#endif
122
123	SYSCALL_REQUIRE(msg_open(&parent_child) == 0);
124
125	DPRINTF("Before forking process PID=%d\n", getpid());
126	SYSCALL_REQUIRE((child1 = fork()) != -1);
127	if (child1 == 0) {
128		DPRINTF("Before forking process PID=%d\n", getpid());
129		SYSCALL_REQUIRE((child2 = fork()) != -1);
130		if (child2 != 0) {
131			DPRINTF("Parent process PID=%d, child2's PID=%d\n",
132			    getpid(), child2);
133			_exit(exitval_child1);
134		}
135		CHILD_FROM_PARENT("exit child1", parent_child, msg);
136
137		DPRINTF("Assert that our parent is PID1 (initproc)\n");
138		FORKEE_ASSERT_EQ(getppid(), 1);
139
140		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
141		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) == -1);
142		SYSCALL_REQUIRE_ERRNO(errno, EPERM);
143
144		CHILD_TO_PARENT("child2 exiting", parent_child, msg);
145
146		_exit(exitval_child2);
147	}
148	DPRINTF("Parent process PID=%d, child1's PID=%d\n", getpid(), child1);
149
150	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
151	TWAIT_REQUIRE_SUCCESS(
152	    wpid = TWAIT_GENERIC(child1, &status, WEXITED), child1);
153
154	validate_status_exited(status, exitval_child1);
155
156	DPRINTF("Notify that child1 is dead\n");
157	PARENT_TO_CHILD("exit child1", parent_child, msg);
158
159	DPRINTF("Wait for exiting of child2\n");
160	PARENT_FROM_CHILD("child2 exiting", parent_child, msg);
161}
162
163/// ----------------------------------------------------------------------------
164
165static void
166traceme_vfork_exec(bool masked, bool ignored)
167{
168	const int sigval = SIGTRAP;
169	pid_t child, wpid;
170#if defined(TWAIT_HAVE_STATUS)
171	int status;
172#endif
173	struct sigaction sa;
174	struct ptrace_siginfo info;
175	sigset_t intmask;
176	struct kinfo_proc2 kp;
177	size_t len = sizeof(kp);
178
179	int name[6];
180	const size_t namelen = __arraycount(name);
181	ki_sigset_t kp_sigmask;
182	ki_sigset_t kp_sigignore;
183
184	memset(&info, 0, sizeof(info));
185
186	DPRINTF("Before forking process PID=%d\n", getpid());
187	SYSCALL_REQUIRE((child = vfork()) != -1);
188	if (child == 0) {
189		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
190		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
191
192		if (masked) {
193			sigemptyset(&intmask);
194			sigaddset(&intmask, sigval);
195			sigprocmask(SIG_BLOCK, &intmask, NULL);
196		}
197
198		if (ignored) {
199			memset(&sa, 0, sizeof(sa));
200			sa.sa_handler = SIG_IGN;
201			sigemptyset(&sa.sa_mask);
202			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
203		}
204
205		DPRINTF("Before calling execve(2) from child\n");
206		execlp("/bin/echo", "/bin/echo", NULL);
207
208		/* NOTREACHED */
209		FORKEE_ASSERTX(0 && "Not reached");
210	}
211	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
212
213	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
214	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
215
216	validate_status_stopped(status, sigval);
217
218	name[0] = CTL_KERN,
219	name[1] = KERN_PROC2,
220	name[2] = KERN_PROC_PID;
221	name[3] = getpid();
222	name[4] = sizeof(kp);
223	name[5] = 1;
224
225	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
226
227	if (masked)
228		kp_sigmask = kp.p_sigmask;
229
230	if (ignored)
231		kp_sigignore = kp.p_sigignore;
232
233	name[3] = getpid();
234
235	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
236
237	if (masked) {
238		DPRINTF("kp_sigmask="
239		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
240		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
241		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
242
243	        DPRINTF("kp.p_sigmask="
244	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
245	            kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
246	            kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
247
248		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
249		    sizeof(kp_sigmask)));
250	}
251
252	if (ignored) {
253		DPRINTF("kp_sigignore="
254		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
255		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
256		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
257
258	        DPRINTF("kp.p_sigignore="
259	            "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
260	            kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
261	            kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
262
263		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
264		    sizeof(kp_sigignore)));
265	}
266
267	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
268	SYSCALL_REQUIRE(
269	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
270
271	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
272	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
273	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
274	    info.psi_siginfo.si_errno);
275
276	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
277	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
278
279	DPRINTF("Before resuming the child process where it left off and "
280	    "without signal to be sent\n");
281	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
282
283	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
284	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
285
286	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
287	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
288}
289
290#define TRACEME_VFORK_EXEC(test, masked, ignored)			\
291ATF_TC(test);								\
292ATF_TC_HEAD(test, tc)							\
293{									\
294	atf_tc_set_md_var(tc, "descr",					\
295	    "Verify PT_TRACE_ME followed by exec(3) in a vfork(2)ed "	\
296	    "child%s%s", masked ? " with masked signal" : "",		\
297	    masked ? " with ignored signal" : "");			\
298}									\
299									\
300ATF_TC_BODY(test, tc)							\
301{									\
302									\
303	traceme_vfork_exec(masked, ignored);				\
304}
305
306TRACEME_VFORK_EXEC(traceme_vfork_exec, false, false)
307TRACEME_VFORK_EXEC(traceme_vfork_signalmasked_exec, true, false)
308TRACEME_VFORK_EXEC(traceme_vfork_signalignored_exec, false, true)
309
310/// ----------------------------------------------------------------------------
311
312#if defined(TWAIT_HAVE_PID)
313static void
314tracer_sees_terminaton_before_the_parent_raw(bool notimeout, bool unrelated,
315                                             bool stopped)
316{
317	/*
318	 * notimeout - disable timeout in await zombie function
319	 * unrelated - attach from unrelated tracer reparented to initproc
320	 * stopped - attach to a stopped process
321	 */
322
323	struct msg_fds parent_tracee, parent_tracer;
324	const int exitval_tracee = 5;
325	const int exitval_tracer = 10;
326	pid_t tracee, tracer, wpid;
327	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
328#if defined(TWAIT_HAVE_STATUS)
329	int status;
330#endif
331
332	/*
333	 * Only a subset of options are supported.
334	 */
335	ATF_REQUIRE((!notimeout && !unrelated && !stopped) ||
336	            (!notimeout && unrelated && !stopped) ||
337	            (notimeout && !unrelated && !stopped) ||
338	            (!notimeout && unrelated && stopped));
339
340	DPRINTF("Spawn tracee\n");
341	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
342	tracee = atf_utils_fork();
343	if (tracee == 0) {
344		if (stopped) {
345			DPRINTF("Stop self PID %d\n", getpid());
346			raise(SIGSTOP);
347		}
348
349		// Wait for parent to let us exit
350		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
351		_exit(exitval_tracee);
352	}
353
354	DPRINTF("Spawn debugger\n");
355	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
356	tracer = atf_utils_fork();
357	if (tracer == 0) {
358		if(unrelated) {
359			/* Fork again and drop parent to reattach to PID 1 */
360			tracer = atf_utils_fork();
361			if (tracer != 0)
362				_exit(exitval_tracer);
363		}
364
365		if (stopped) {
366			DPRINTF("Await for a stopped parent PID %d\n", tracee);
367			await_stopped(tracee);
368		}
369
370		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
371		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
372
373		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
374		FORKEE_REQUIRE_SUCCESS(
375		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
376
377		forkee_status_stopped(status, SIGSTOP);
378
379		/* Resume tracee with PT_CONTINUE */
380		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
381
382		/* Inform parent that tracer has attached to tracee */
383		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
384
385		/* Wait for parent to tell use that tracee should have exited */
386		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
387
388		/* Wait for tracee and assert that it exited */
389		FORKEE_REQUIRE_SUCCESS(
390		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
391
392		forkee_status_exited(status, exitval_tracee);
393		DPRINTF("Tracee %d exited with %d\n", tracee, exitval_tracee);
394
395		DPRINTF("Before exiting of the tracer process\n");
396		_exit(unrelated ? 0 /* collect by initproc */ : exitval_tracer);
397	}
398
399	if (unrelated) {
400		DPRINTF("Wait for the tracer process (direct child) to exit "
401		    "calling %s()\n", TWAIT_FNAME);
402		TWAIT_REQUIRE_SUCCESS(
403		    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
404
405		validate_status_exited(status, exitval_tracer);
406
407		DPRINTF("Wait for the non-exited tracee process with %s()\n",
408		    TWAIT_FNAME);
409		TWAIT_REQUIRE_SUCCESS(
410		    wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0);
411	}
412
413	DPRINTF("Wait for the tracer to attach to the tracee\n");
414	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
415
416	DPRINTF("Resume the tracee and let it exit\n");
417	PARENT_TO_CHILD("exit tracee", parent_tracee,  msg);
418
419	DPRINTF("Detect that tracee is zombie\n");
420	if (notimeout)
421		await_zombie_raw(tracee, 0);
422	else
423		await_zombie(tracee);
424
425	DPRINTF("Assert that there is no status about tracee %d - "
426	    "Tracer must detect zombie first - calling %s()\n", tracee,
427	    TWAIT_FNAME);
428	TWAIT_REQUIRE_SUCCESS(
429	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
430
431	if (unrelated) {
432		DPRINTF("Resume the tracer and let it detect exited tracee\n");
433		PARENT_TO_CHILD("Message 2", parent_tracer, msg);
434	} else {
435		DPRINTF("Tell the tracer child should have exited\n");
436		PARENT_TO_CHILD("wait for tracee exit", parent_tracer,  msg);
437		DPRINTF("Wait for tracer to finish its job and exit - calling "
438			"%s()\n", TWAIT_FNAME);
439
440		DPRINTF("Wait from tracer child to complete waiting for "
441			"tracee\n");
442		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
443		    tracer);
444
445		validate_status_exited(status, exitval_tracer);
446	}
447
448	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
449	    TWAIT_FNAME);
450	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
451
452	validate_status_exited(status, exitval_tracee);
453
454	msg_close(&parent_tracer);
455	msg_close(&parent_tracee);
456}
457
458ATF_TC(tracer_sees_terminaton_before_the_parent);
459ATF_TC_HEAD(tracer_sees_terminaton_before_the_parent, tc)
460{
461	atf_tc_set_md_var(tc, "descr",
462	    "Assert that tracer sees process termination before the parent");
463}
464
465ATF_TC_BODY(tracer_sees_terminaton_before_the_parent, tc)
466{
467
468	tracer_sees_terminaton_before_the_parent_raw(false, false, false);
469}
470
471ATF_TC(tracer_sysctl_lookup_without_duplicates);
472ATF_TC_HEAD(tracer_sysctl_lookup_without_duplicates, tc)
473{
474	atf_tc_set_md_var(tc, "timeout", "15");
475	atf_tc_set_md_var(tc, "descr",
476	    "Assert that await_zombie() in attach1 always finds a single "
477	    "process and no other error is reported");
478}
479
480ATF_TC_BODY(tracer_sysctl_lookup_without_duplicates, tc)
481{
482	time_t start, end;
483	double diff;
484	unsigned long N = 0;
485
486	/*
487	 * Reuse this test with tracer_sees_terminaton_before_the_parent_raw().
488	 * This test body isn't specific to this race, however it's just good
489	 * enough for this purposes, no need to invent a dedicated code flow.
490	 */
491
492	start = time(NULL);
493	while (true) {
494		DPRINTF("Step: %lu\n", N);
495		tracer_sees_terminaton_before_the_parent_raw(true, false,
496		                                             false);
497		end = time(NULL);
498		diff = difftime(end, start);
499		if (diff >= 5.0)
500			break;
501		++N;
502	}
503	DPRINTF("Iterations: %lu\n", N);
504}
505
506ATF_TC(unrelated_tracer_sees_terminaton_before_the_parent);
507ATF_TC_HEAD(unrelated_tracer_sees_terminaton_before_the_parent, tc)
508{
509	atf_tc_set_md_var(tc, "descr",
510	    "Assert that tracer sees process termination before the parent");
511}
512
513ATF_TC_BODY(unrelated_tracer_sees_terminaton_before_the_parent, tc)
514{
515
516	tracer_sees_terminaton_before_the_parent_raw(false, true, false);
517}
518
519ATF_TC(tracer_attach_to_unrelated_stopped_process);
520ATF_TC_HEAD(tracer_attach_to_unrelated_stopped_process, tc)
521{
522	atf_tc_set_md_var(tc, "descr",
523	    "Assert that tracer can attach to an unrelated stopped process");
524}
525
526ATF_TC_BODY(tracer_attach_to_unrelated_stopped_process, tc)
527{
528
529	tracer_sees_terminaton_before_the_parent_raw(false, true, true);
530}
531#endif
532
533/// ----------------------------------------------------------------------------
534
535static void
536parent_attach_to_its_child(bool stopped)
537{
538	struct msg_fds parent_tracee;
539	const int exitval_tracee = 5;
540	pid_t tracee, wpid;
541	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
542#if defined(TWAIT_HAVE_STATUS)
543	int status;
544#endif
545
546	DPRINTF("Spawn tracee\n");
547	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
548	tracee = atf_utils_fork();
549	if (tracee == 0) {
550		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
551		DPRINTF("Parent should now attach to tracee\n");
552
553		if (stopped) {
554			DPRINTF("Stop self PID %d\n", getpid());
555			SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
556		}
557
558		CHILD_FROM_PARENT("Message 2", parent_tracee, msg);
559		/* Wait for message from the parent */
560		_exit(exitval_tracee);
561	}
562	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
563
564	if (stopped) {
565		DPRINTF("Await for a stopped tracee PID %d\n", tracee);
566		await_stopped(tracee);
567	}
568
569	DPRINTF("Before calling PT_ATTACH for tracee %d\n", tracee);
570	SYSCALL_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
571
572	DPRINTF("Wait for the stopped tracee process with %s()\n",
573	    TWAIT_FNAME);
574	TWAIT_REQUIRE_SUCCESS(
575	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
576
577	validate_status_stopped(status, SIGSTOP);
578
579	DPRINTF("Resume tracee with PT_CONTINUE\n");
580	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
581
582	DPRINTF("Let the tracee exit now\n");
583	PARENT_TO_CHILD("Message 2", parent_tracee, msg);
584
585	DPRINTF("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
586	TWAIT_REQUIRE_SUCCESS(
587	    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
588
589	validate_status_exited(status, exitval_tracee);
590
591	DPRINTF("Before calling %s() for tracee\n", TWAIT_FNAME);
592	TWAIT_REQUIRE_FAILURE(ECHILD,
593	    wpid = TWAIT_GENERIC(tracee, &status, 0));
594
595	msg_close(&parent_tracee);
596}
597
598ATF_TC(parent_attach_to_its_child);
599ATF_TC_HEAD(parent_attach_to_its_child, tc)
600{
601	atf_tc_set_md_var(tc, "descr",
602	    "Assert that tracer parent can PT_ATTACH to its child");
603}
604
605ATF_TC_BODY(parent_attach_to_its_child, tc)
606{
607
608	parent_attach_to_its_child(false);
609}
610
611ATF_TC(parent_attach_to_its_stopped_child);
612ATF_TC_HEAD(parent_attach_to_its_stopped_child, tc)
613{
614	atf_tc_set_md_var(tc, "descr",
615	    "Assert that tracer parent can PT_ATTACH to its stopped child");
616}
617
618ATF_TC_BODY(parent_attach_to_its_stopped_child, tc)
619{
620
621	parent_attach_to_its_child(true);
622}
623
624/// ----------------------------------------------------------------------------
625
626static void
627child_attach_to_its_parent(bool stopped)
628{
629	struct msg_fds parent_tracee;
630	const int exitval_tracer = 5;
631	pid_t tracer, wpid;
632	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
633#if defined(TWAIT_HAVE_STATUS)
634	int status;
635#endif
636
637	DPRINTF("Spawn tracer\n");
638	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
639	tracer = atf_utils_fork();
640	if (tracer == 0) {
641		/* Wait for message from the parent */
642		CHILD_FROM_PARENT("Message 1", parent_tracee, msg);
643
644		if (stopped) {
645			DPRINTF("Await for a stopped parent PID %d\n",
646			        getppid());
647			await_stopped(getppid());
648		}
649
650		DPRINTF("Attach to parent PID %d with PT_ATTACH from child\n",
651		    getppid());
652		FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1);
653
654		DPRINTF("Wait for the stopped parent process with %s()\n",
655		    TWAIT_FNAME);
656		FORKEE_REQUIRE_SUCCESS(
657		    wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid());
658
659		forkee_status_stopped(status, SIGSTOP);
660
661		DPRINTF("Resume parent with PT_DETACH\n");
662		FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0)
663		    != -1);
664
665		/* Tell parent we are ready */
666		CHILD_TO_PARENT("Message 1", parent_tracee, msg);
667
668		_exit(exitval_tracer);
669	}
670
671	DPRINTF("Wait for the tracer to become ready\n");
672	PARENT_TO_CHILD("Message 1", parent_tracee, msg);
673
674	if (stopped) {
675		DPRINTF("Stop self PID %d\n", getpid());
676		SYSCALL_REQUIRE(raise(SIGSTOP) != -1);
677	}
678
679	DPRINTF("Allow the tracer to exit now\n");
680	PARENT_FROM_CHILD("Message 1", parent_tracee, msg);
681
682	DPRINTF("Wait for tracer to exit with %s()\n", TWAIT_FNAME);
683	TWAIT_REQUIRE_SUCCESS(
684	    wpid = TWAIT_GENERIC(tracer, &status, 0), tracer);
685
686	validate_status_exited(status, exitval_tracer);
687
688	DPRINTF("Before calling %s() for tracer\n", TWAIT_FNAME);
689	TWAIT_REQUIRE_FAILURE(ECHILD,
690	    wpid = TWAIT_GENERIC(tracer, &status, 0));
691
692	msg_close(&parent_tracee);
693}
694
695ATF_TC(child_attach_to_its_parent);
696ATF_TC_HEAD(child_attach_to_its_parent, tc)
697{
698	atf_tc_set_md_var(tc, "descr",
699	    "Assert that tracer child can PT_ATTACH to its parent");
700}
701
702ATF_TC_BODY(child_attach_to_its_parent, tc)
703{
704
705	child_attach_to_its_parent(false);
706}
707
708ATF_TC(child_attach_to_its_stopped_parent);
709ATF_TC_HEAD(child_attach_to_its_stopped_parent, tc)
710{
711	atf_tc_set_md_var(tc, "descr",
712	    "Assert that tracer child can PT_ATTACH to its stopped parent");
713}
714
715ATF_TC_BODY(child_attach_to_its_stopped_parent, tc)
716{
717	/*
718	 * The ATF framework (atf-run) does not tolerate raise(SIGSTOP), as
719	 * this causes a pipe (established from atf-run) to be broken.
720	 * atf-run uses this mechanism to monitor whether a test is alive.
721	 *
722	 * As a workaround spawn this test as a subprocess.
723	 */
724
725	const int exitval = 15;
726	pid_t child, wpid;
727#if defined(TWAIT_HAVE_STATUS)
728	int status;
729#endif
730
731	SYSCALL_REQUIRE((child = fork()) != -1);
732	if (child == 0) {
733		child_attach_to_its_parent(true);
734		_exit(exitval);
735	} else {
736		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
737		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
738
739		validate_status_exited(status, exitval);
740
741		DPRINTF("Before calling %s() for the exited child\n", TWAIT_FNAME);
742		TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
743	}
744}
745
746/// ----------------------------------------------------------------------------
747
748#if defined(TWAIT_HAVE_PID)
749
750enum tracee_sees_its_original_parent_type {
751	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
752	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
753	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS
754};
755
756static void
757tracee_sees_its_original_parent(enum tracee_sees_its_original_parent_type type)
758{
759	struct msg_fds parent_tracer, parent_tracee;
760	const int exitval_tracee = 5;
761	const int exitval_tracer = 10;
762	pid_t parent, tracee, tracer, wpid;
763	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
764#if defined(TWAIT_HAVE_STATUS)
765	int status;
766#endif
767	/* sysctl(3) - kinfo_proc2 */
768	int name[CTL_MAXNAME];
769	struct kinfo_proc2 kp;
770	size_t len = sizeof(kp);
771	unsigned int namelen;
772
773	/* procfs - status  */
774	FILE *fp;
775	struct stat st;
776	const char *fname = "/proc/curproc/status";
777	char s_executable[MAXPATHLEN];
778	int s_pid, s_ppid;
779	int rv;
780
781	if (type == TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS) {
782		SYSCALL_REQUIRE(
783		    (rv = stat(fname, &st)) == 0 || (errno == ENOENT));
784		if (rv != 0)
785			atf_tc_skip("/proc/curproc/status not found");
786	}
787
788	DPRINTF("Spawn tracee\n");
789	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
790	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
791	tracee = atf_utils_fork();
792	if (tracee == 0) {
793		parent = getppid();
794
795		/* Emit message to the parent */
796		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
797		CHILD_FROM_PARENT("exit tracee", parent_tracee, msg);
798
799		switch (type) {
800		case TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID:
801			FORKEE_ASSERT_EQ(parent, getppid());
802			break;
803		case TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2:
804			namelen = 0;
805			name[namelen++] = CTL_KERN;
806			name[namelen++] = KERN_PROC2;
807			name[namelen++] = KERN_PROC_PID;
808			name[namelen++] = getpid();
809			name[namelen++] = len;
810			name[namelen++] = 1;
811
812			FORKEE_ASSERT_EQ(
813			    sysctl(name, namelen, &kp, &len, NULL, 0), 0);
814			FORKEE_ASSERT_EQ(parent, kp.p_ppid);
815			break;
816		case TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS:
817			/*
818			 * Format:
819			 *  EXECUTABLE PID PPID ...
820			 */
821			FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL);
822			fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid);
823			FORKEE_ASSERT_EQ(fclose(fp), 0);
824			FORKEE_ASSERT_EQ(parent, s_ppid);
825			break;
826		}
827
828		_exit(exitval_tracee);
829	}
830	DPRINTF("Wait for child to record its parent identifier (pid)\n");
831	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
832
833	DPRINTF("Spawn debugger\n");
834	tracer = atf_utils_fork();
835	if (tracer == 0) {
836		/* No IPC to communicate with the child */
837		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
838		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
839
840		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
841		FORKEE_REQUIRE_SUCCESS(
842		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
843
844		forkee_status_stopped(status, SIGSTOP);
845
846		/* Resume tracee with PT_CONTINUE */
847		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
848
849		/* Inform parent that tracer has attached to tracee */
850		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
851
852		/* Wait for parent to tell use that tracee should have exited */
853		CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg);
854
855		/* Wait for tracee and assert that it exited */
856		FORKEE_REQUIRE_SUCCESS(
857		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
858
859		forkee_status_exited(status, exitval_tracee);
860
861		DPRINTF("Before exiting of the tracer process\n");
862		_exit(exitval_tracer);
863	}
864
865	DPRINTF("Wait for the tracer to attach to the tracee\n");
866	PARENT_FROM_CHILD("tracer ready",  parent_tracer, msg);
867
868	DPRINTF("Resume the tracee and let it exit\n");
869	PARENT_TO_CHILD("exit tracee",  parent_tracee, msg);
870
871	DPRINTF("Detect that tracee is zombie\n");
872	await_zombie(tracee);
873
874	DPRINTF("Assert that there is no status about tracee - "
875	    "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME);
876	TWAIT_REQUIRE_SUCCESS(
877	    wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0);
878
879	DPRINTF("Tell the tracer child should have exited\n");
880	PARENT_TO_CHILD("wait for tracee exit",  parent_tracer, msg);
881
882	DPRINTF("Wait from tracer child to complete waiting for tracee\n");
883	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
884	    tracer);
885
886	validate_status_exited(status, exitval_tracer);
887
888	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
889	    TWAIT_FNAME);
890	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
891	    tracee);
892
893	validate_status_exited(status, exitval_tracee);
894
895	msg_close(&parent_tracer);
896	msg_close(&parent_tracee);
897}
898
899#define TRACEE_SEES_ITS_ORIGINAL_PARENT(test, type, descr)		\
900ATF_TC(test);								\
901ATF_TC_HEAD(test, tc)							\
902{									\
903	atf_tc_set_md_var(tc, "descr",					\
904	    "Assert that tracee sees its original parent when being traced " \
905	    "(check " descr ")");					\
906}									\
907									\
908ATF_TC_BODY(test, tc)							\
909{									\
910									\
911	tracee_sees_its_original_parent(type);				\
912}
913
914TRACEE_SEES_ITS_ORIGINAL_PARENT(
915	tracee_sees_its_original_parent_getppid,
916	TRACEE_SEES_ITS_ORIGINAL_PARENT_GETPPID,
917	"getppid(2)");
918TRACEE_SEES_ITS_ORIGINAL_PARENT(
919	tracee_sees_its_original_parent_sysctl_kinfo_proc2,
920	TRACEE_SEES_ITS_ORIGINAL_PARENT_SYSCTL_KINFO_PROC2,
921	"sysctl(3) and kinfo_proc2");
922TRACEE_SEES_ITS_ORIGINAL_PARENT(
923	tracee_sees_its_original_parent_procfs_status,
924	TRACEE_SEES_ITS_ORIGINAL_PARENT_PROCFS_STATUS,
925	"the status file in procfs");
926#endif
927
928/// ----------------------------------------------------------------------------
929
930static void
931eventmask_preserved(int event)
932{
933	const int exitval = 5;
934	const int sigval = SIGSTOP;
935	pid_t child, wpid;
936#if defined(TWAIT_HAVE_STATUS)
937	int status;
938#endif
939	ptrace_event_t set_event, get_event;
940	const int len = sizeof(ptrace_event_t);
941
942	DPRINTF("Before forking process PID=%d\n", getpid());
943	SYSCALL_REQUIRE((child = fork()) != -1);
944	if (child == 0) {
945		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
946		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
947
948		DPRINTF("Before raising %s from child\n", strsignal(sigval));
949		FORKEE_ASSERT(raise(sigval) == 0);
950
951		DPRINTF("Before exiting of the child process\n");
952		_exit(exitval);
953	}
954	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
955
956	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
957	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
958
959	validate_status_stopped(status, sigval);
960
961	set_event.pe_set_event = event;
962	SYSCALL_REQUIRE(
963	    ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1);
964	SYSCALL_REQUIRE(
965	    ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1);
966	DPRINTF("set_event=%#x get_event=%#x\n", set_event.pe_set_event,
967	    get_event.pe_set_event);
968	ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0);
969
970	DPRINTF("Before resuming the child process where it left off and "
971	    "without signal to be sent\n");
972	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
973
974	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
975	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
976
977	validate_status_exited(status, exitval);
978
979	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
980	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
981}
982
983#define EVENTMASK_PRESERVED(test, event)				\
984ATF_TC(test);								\
985ATF_TC_HEAD(test, tc)							\
986{									\
987	atf_tc_set_md_var(tc, "descr",					\
988	    "Verify that eventmask " #event " is preserved");		\
989}									\
990									\
991ATF_TC_BODY(test, tc)							\
992{									\
993									\
994	eventmask_preserved(event);					\
995}
996
997EVENTMASK_PRESERVED(eventmask_preserved_empty, 0)
998EVENTMASK_PRESERVED(eventmask_preserved_fork, PTRACE_FORK)
999EVENTMASK_PRESERVED(eventmask_preserved_vfork, PTRACE_VFORK)
1000EVENTMASK_PRESERVED(eventmask_preserved_vfork_done, PTRACE_VFORK_DONE)
1001EVENTMASK_PRESERVED(eventmask_preserved_lwp_create, PTRACE_LWP_CREATE)
1002EVENTMASK_PRESERVED(eventmask_preserved_lwp_exit, PTRACE_LWP_EXIT)
1003EVENTMASK_PRESERVED(eventmask_preserved_posix_spawn, PTRACE_POSIX_SPAWN)
1004
1005/// ----------------------------------------------------------------------------
1006
1007static int lwpinfo_thread_sigmask[] = {SIGXCPU, SIGPIPE, SIGALRM, SIGURG};
1008
1009static pthread_mutex_t lwpinfo_thread_mtx = PTHREAD_MUTEX_INITIALIZER;
1010static pthread_cond_t lwpinfo_thread_cnd = PTHREAD_COND_INITIALIZER;
1011static volatile size_t lwpinfo_thread_done;
1012
1013static void *
1014lwpinfo_thread(void *arg)
1015{
1016	sigset_t s;
1017	volatile void **tcb;
1018
1019	tcb = (volatile void **)arg;
1020
1021	*tcb = _lwp_getprivate();
1022	DPRINTF("Storing tcb[] = %p from thread %d\n", *tcb, _lwp_self());
1023
1024	pthread_setname_np(pthread_self(), "thread %d",
1025	    (void *)(intptr_t)_lwp_self());
1026
1027	sigemptyset(&s);
1028	pthread_mutex_lock(&lwpinfo_thread_mtx);
1029	sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
1030	lwpinfo_thread_done++;
1031	pthread_sigmask(SIG_BLOCK, &s, NULL);
1032	pthread_cond_signal(&lwpinfo_thread_cnd);
1033	pthread_mutex_unlock(&lwpinfo_thread_mtx);
1034
1035	return infinite_thread(NULL);
1036}
1037
1038static void
1039traceme_lwpinfo(const size_t threads, const char *iter)
1040{
1041	const int sigval = SIGSTOP;
1042	const int sigval2 = SIGINT;
1043	pid_t child, wpid;
1044#if defined(TWAIT_HAVE_STATUS)
1045	int status;
1046#endif
1047	struct ptrace_lwpinfo lwp = {0, 0};
1048	struct ptrace_lwpstatus lwpstatus = {0};
1049	struct ptrace_siginfo info;
1050	void *private;
1051	char *name;
1052	char namebuf[PL_LNAMELEN];
1053	volatile void *tcb[4];
1054	bool found;
1055	sigset_t s;
1056
1057	/* Maximum number of supported threads in this test */
1058	pthread_t t[__arraycount(tcb) - 1];
1059	size_t n, m;
1060	int rv;
1061	size_t bytes_read;
1062
1063	struct ptrace_io_desc io;
1064	sigset_t sigmask;
1065
1066	ATF_REQUIRE(__arraycount(t) >= threads);
1067	memset(tcb, 0, sizeof(tcb));
1068
1069	DPRINTF("Before forking process PID=%d\n", getpid());
1070	SYSCALL_REQUIRE((child = fork()) != -1);
1071	if (child == 0) {
1072		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1073		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1074
1075		tcb[0] = _lwp_getprivate();
1076		DPRINTF("Storing tcb[0] = %p\n", tcb[0]);
1077
1078		pthread_setname_np(pthread_self(), "thread %d",
1079		    (void *)(intptr_t)_lwp_self());
1080
1081		sigemptyset(&s);
1082		sigaddset(&s, lwpinfo_thread_sigmask[lwpinfo_thread_done]);
1083		pthread_sigmask(SIG_BLOCK, &s, NULL);
1084
1085		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1086		FORKEE_ASSERT(raise(sigval) == 0);
1087
1088		for (n = 0; n < threads; n++) {
1089			rv = pthread_create(&t[n], NULL, lwpinfo_thread,
1090			    &tcb[n + 1]);
1091			FORKEE_ASSERT(rv == 0);
1092		}
1093
1094		pthread_mutex_lock(&lwpinfo_thread_mtx);
1095		while (lwpinfo_thread_done < threads) {
1096			pthread_cond_wait(&lwpinfo_thread_cnd,
1097			    &lwpinfo_thread_mtx);
1098		}
1099		pthread_mutex_unlock(&lwpinfo_thread_mtx);
1100
1101		DPRINTF("Before raising %s from child\n", strsignal(sigval2));
1102		FORKEE_ASSERT(raise(sigval2) == 0);
1103
1104		/* NOTREACHED */
1105		FORKEE_ASSERTX(0 && "Not reached");
1106	}
1107	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1108
1109	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1110	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1111
1112	validate_status_stopped(status, sigval);
1113
1114	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
1115	SYSCALL_REQUIRE(
1116	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1117
1118	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1119	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1120	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1121	    info.psi_siginfo.si_errno);
1122
1123	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1124	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1125
1126	if (strstr(iter, "LWPINFO") != NULL) {
1127		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
1128		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
1129		    != -1);
1130
1131		DPRINTF("Assert that there exists a single thread only\n");
1132		ATF_REQUIRE(lwp.pl_lwpid > 0);
1133
1134		DPRINTF("Assert that lwp thread %d received event "
1135		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
1136		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
1137
1138		if (strstr(iter, "LWPSTATUS") != NULL) {
1139			DPRINTF("Before calling ptrace(2) with PT_LWPSTATUS "
1140			    "for child\n");
1141			lwpstatus.pl_lwpid = lwp.pl_lwpid;
1142			SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child, &lwpstatus,
1143			    sizeof(lwpstatus)) != -1);
1144		}
1145
1146		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
1147		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
1148		    != -1);
1149
1150		DPRINTF("Assert that there exists a single thread only\n");
1151		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
1152	} else {
1153		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
1154		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
1155		    sizeof(lwpstatus)) != -1);
1156
1157		DPRINTF("Assert that there exists a single thread only %d\n", lwpstatus.pl_lwpid);
1158		ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
1159
1160		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
1161		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
1162		    sizeof(lwpstatus)) != -1);
1163
1164		DPRINTF("Assert that there exists a single thread only\n");
1165		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
1166	}
1167
1168	DPRINTF("Before resuming the child process where it left off and "
1169	    "without signal to be sent\n");
1170	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1171
1172	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1173	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1174
1175	validate_status_stopped(status, sigval2);
1176
1177	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child");
1178	SYSCALL_REQUIRE(
1179	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1180
1181	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1182	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1183	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1184	    info.psi_siginfo.si_errno);
1185
1186	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval2);
1187	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1188
1189	memset(&lwp, 0, sizeof(lwp));
1190	memset(&lwpstatus, 0, sizeof(lwpstatus));
1191
1192	memset(&io, 0, sizeof(io));
1193
1194	bytes_read = 0;
1195	io.piod_op = PIOD_READ_D;
1196	io.piod_len = sizeof(tcb);
1197
1198	do {
1199		io.piod_addr = (char *)&tcb + bytes_read;
1200		io.piod_offs = io.piod_addr;
1201
1202		rv = ptrace(PT_IO, child, &io, sizeof(io));
1203		ATF_REQUIRE(rv != -1 && io.piod_len != 0);
1204
1205		bytes_read += io.piod_len;
1206		io.piod_len = sizeof(tcb) - bytes_read;
1207	} while (bytes_read < sizeof(tcb));
1208
1209	for (n = 0; n <= threads; n++) {
1210		if (strstr(iter, "LWPINFO") != NULL) {
1211			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
1212			    "child\n");
1213			SYSCALL_REQUIRE(
1214			    ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp)) != -1);
1215			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
1216
1217			DPRINTF("Assert that the thread exists\n");
1218			ATF_REQUIRE(lwp.pl_lwpid > 0);
1219
1220			DPRINTF("Assert that lwp thread %d received expected "
1221			    "event\n", lwp.pl_lwpid);
1222			FORKEE_ASSERT_EQ(lwp.pl_event,
1223			    info.psi_lwpid == lwp.pl_lwpid ?
1224			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
1225
1226			if (strstr(iter, "LWPSTATUS") != NULL) {
1227				DPRINTF("Before calling ptrace(2) with "
1228				    "PT_LWPSTATUS for child\n");
1229				lwpstatus.pl_lwpid = lwp.pl_lwpid;
1230				SYSCALL_REQUIRE(ptrace(PT_LWPSTATUS, child,
1231				    &lwpstatus, sizeof(lwpstatus)) != -1);
1232
1233				goto check_lwpstatus;
1234			}
1235		} else {
1236			DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for "
1237			    "child\n");
1238			SYSCALL_REQUIRE(
1239			    ptrace(PT_LWPNEXT, child, &lwpstatus,
1240			    sizeof(lwpstatus)) != -1);
1241			DPRINTF("LWP=%d\n", lwpstatus.pl_lwpid);
1242
1243			DPRINTF("Assert that the thread exists\n");
1244			ATF_REQUIRE(lwpstatus.pl_lwpid > 0);
1245
1246		check_lwpstatus:
1247
1248			if (strstr(iter, "pl_sigmask") != NULL) {
1249				sigmask = lwpstatus.pl_sigmask;
1250
1251				DPRINTF("Retrieved sigmask: "
1252				    "%02x%02x%02x%02x\n",
1253				    sigmask.__bits[0], sigmask.__bits[1],
1254				    sigmask.__bits[2], sigmask.__bits[3]);
1255
1256				found = false;
1257				for (m = 0;
1258				     m < __arraycount(lwpinfo_thread_sigmask);
1259				     m++) {
1260					if (sigismember(&sigmask,
1261					    lwpinfo_thread_sigmask[m])) {
1262						found = true;
1263						lwpinfo_thread_sigmask[m] = 0;
1264						break;
1265					}
1266				}
1267				ATF_REQUIRE(found == true);
1268			} else if (strstr(iter, "pl_name") != NULL) {
1269				name = lwpstatus.pl_name;
1270
1271				DPRINTF("Retrieved thread name: "
1272				    "%s\n", name);
1273
1274				snprintf(namebuf, sizeof namebuf, "thread %d",
1275				    lwpstatus.pl_lwpid);
1276
1277				ATF_REQUIRE(strcmp(name, namebuf) == 0);
1278			} else if (strstr(iter, "pl_private") != NULL) {
1279				private = lwpstatus.pl_private;
1280
1281				DPRINTF("Retrieved thread private pointer: "
1282				    "%p\n", private);
1283
1284				found = false;
1285				for (m = 0; m < __arraycount(tcb); m++) {
1286					DPRINTF("Comparing %p and %p\n",
1287					    private, tcb[m]);
1288					if (private == tcb[m]) {
1289						found = true;
1290						break;
1291					}
1292				}
1293				ATF_REQUIRE(found == true);
1294			}
1295		}
1296	}
1297
1298	if (strstr(iter, "LWPINFO") != NULL) {
1299		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
1300		    "child\n");
1301		SYSCALL_REQUIRE(ptrace(PT_LWPINFO, child, &lwp, sizeof(lwp))
1302		    != -1);
1303		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
1304
1305		DPRINTF("Assert that there are no more threads\n");
1306		ATF_REQUIRE_EQ(lwp.pl_lwpid, 0);
1307	} else {
1308		DPRINTF("Before calling ptrace(2) with PT_LWPNEXT for child\n");
1309		SYSCALL_REQUIRE(ptrace(PT_LWPNEXT, child, &lwpstatus,
1310		    sizeof(lwpstatus)) != -1);
1311
1312		DPRINTF("Assert that there exists a single thread only\n");
1313		ATF_REQUIRE_EQ(lwpstatus.pl_lwpid, 0);
1314	}
1315
1316	DPRINTF("Before resuming the child process where it left off and "
1317	    "without signal to be sent\n");
1318	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, SIGKILL) != -1);
1319
1320	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1321	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1322
1323	validate_status_signaled(status, SIGKILL, 0);
1324
1325	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1326	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1327}
1328
1329#define TRACEME_LWPINFO(test, threads, iter)				\
1330ATF_TC(test);								\
1331ATF_TC_HEAD(test, tc)							\
1332{									\
1333	atf_tc_set_md_var(tc, "descr",					\
1334	    "Verify " iter " with the child with " #threads		\
1335	    " spawned extra threads");					\
1336}									\
1337									\
1338ATF_TC_BODY(test, tc)							\
1339{									\
1340									\
1341	traceme_lwpinfo(threads, iter);					\
1342}
1343
1344TRACEME_LWPINFO(traceme_lwpinfo0, 0, "LWPINFO")
1345TRACEME_LWPINFO(traceme_lwpinfo1, 1, "LWPINFO")
1346TRACEME_LWPINFO(traceme_lwpinfo2, 2, "LWPINFO")
1347TRACEME_LWPINFO(traceme_lwpinfo3, 3, "LWPINFO")
1348
1349TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus, 0, "LWPINFO+LWPSTATUS")
1350TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus, 1, "LWPINFO+LWPSTATUS")
1351TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus, 2, "LWPINFO+LWPSTATUS")
1352TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus, 3, "LWPINFO+LWPSTATUS")
1353
1354TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_sigmask, 0,
1355    "LWPINFO+LWPSTATUS+pl_sigmask")
1356TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_sigmask, 1,
1357    "LWPINFO+LWPSTATUS+pl_sigmask")
1358TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_sigmask, 2,
1359    "LWPINFO+LWPSTATUS+pl_sigmask")
1360TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_sigmask, 3,
1361    "LWPINFO+LWPSTATUS+pl_sigmask")
1362
1363TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_name, 0,
1364    "LWPINFO+LWPSTATUS+pl_name")
1365TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_name, 1,
1366    "LWPINFO+LWPSTATUS+pl_name")
1367TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_name, 2,
1368    "LWPINFO+LWPSTATUS+pl_name")
1369TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_name, 3,
1370    "LWPINFO+LWPSTATUS+pl_name")
1371
1372TRACEME_LWPINFO(traceme_lwpinfo0_lwpstatus_pl_private, 0,
1373    "LWPINFO+LWPSTATUS+pl_private")
1374TRACEME_LWPINFO(traceme_lwpinfo1_lwpstatus_pl_private, 1,
1375    "LWPINFO+LWPSTATUS+pl_private")
1376TRACEME_LWPINFO(traceme_lwpinfo2_lwpstatus_pl_private, 2,
1377    "LWPINFO+LWPSTATUS+pl_private")
1378TRACEME_LWPINFO(traceme_lwpinfo3_lwpstatus_pl_private, 3,
1379    "LWPINFO+LWPSTATUS+pl_private")
1380
1381TRACEME_LWPINFO(traceme_lwpnext0, 0, "LWPNEXT")
1382TRACEME_LWPINFO(traceme_lwpnext1, 1, "LWPNEXT")
1383TRACEME_LWPINFO(traceme_lwpnext2, 2, "LWPNEXT")
1384TRACEME_LWPINFO(traceme_lwpnext3, 3, "LWPNEXT")
1385
1386TRACEME_LWPINFO(traceme_lwpnext0_pl_sigmask, 0, "LWPNEXT+pl_sigmask")
1387TRACEME_LWPINFO(traceme_lwpnext1_pl_sigmask, 1, "LWPNEXT+pl_sigmask")
1388TRACEME_LWPINFO(traceme_lwpnext2_pl_sigmask, 2, "LWPNEXT+pl_sigmask")
1389TRACEME_LWPINFO(traceme_lwpnext3_pl_sigmask, 3, "LWPNEXT+pl_sigmask")
1390
1391TRACEME_LWPINFO(traceme_lwpnext0_pl_name, 0, "LWPNEXT+pl_name")
1392TRACEME_LWPINFO(traceme_lwpnext1_pl_name, 1, "LWPNEXT+pl_name")
1393TRACEME_LWPINFO(traceme_lwpnext2_pl_name, 2, "LWPNEXT+pl_name")
1394TRACEME_LWPINFO(traceme_lwpnext3_pl_name, 3, "LWPNEXT+pl_name")
1395
1396TRACEME_LWPINFO(traceme_lwpnext0_pl_private, 0, "LWPNEXT+pl_private")
1397TRACEME_LWPINFO(traceme_lwpnext1_pl_private, 1, "LWPNEXT+pl_private")
1398TRACEME_LWPINFO(traceme_lwpnext2_pl_private, 2, "LWPNEXT+pl_private")
1399TRACEME_LWPINFO(traceme_lwpnext3_pl_private, 3, "LWPNEXT+pl_private")
1400
1401/// ----------------------------------------------------------------------------
1402
1403#if defined(TWAIT_HAVE_PID)
1404static void
1405attach_lwpinfo(const int threads)
1406{
1407	const int sigval = SIGINT;
1408	struct msg_fds parent_tracee, parent_tracer;
1409	const int exitval_tracer = 10;
1410	pid_t tracee, tracer, wpid;
1411	uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
1412#if defined(TWAIT_HAVE_STATUS)
1413	int status;
1414#endif
1415	struct ptrace_lwpinfo lwp = {0, 0};
1416	struct ptrace_siginfo info;
1417
1418	/* Maximum number of supported threads in this test */
1419	pthread_t t[3];
1420	int n, rv;
1421
1422	DPRINTF("Spawn tracee\n");
1423	SYSCALL_REQUIRE(msg_open(&parent_tracee) == 0);
1424	SYSCALL_REQUIRE(msg_open(&parent_tracer) == 0);
1425	tracee = atf_utils_fork();
1426	if (tracee == 0) {
1427		/* Wait for message from the parent */
1428		CHILD_TO_PARENT("tracee ready", parent_tracee, msg);
1429
1430		CHILD_FROM_PARENT("spawn threads", parent_tracee, msg);
1431
1432		for (n = 0; n < threads; n++) {
1433			rv = pthread_create(&t[n], NULL, infinite_thread, NULL);
1434			FORKEE_ASSERT(rv == 0);
1435		}
1436
1437		CHILD_TO_PARENT("tracee exit", parent_tracee, msg);
1438
1439		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1440		FORKEE_ASSERT(raise(sigval) == 0);
1441
1442		/* NOTREACHED */
1443		FORKEE_ASSERTX(0 && "Not reached");
1444	}
1445	PARENT_FROM_CHILD("tracee ready", parent_tracee, msg);
1446
1447	DPRINTF("Spawn debugger\n");
1448	tracer = atf_utils_fork();
1449	if (tracer == 0) {
1450		/* No IPC to communicate with the child */
1451		DPRINTF("Before calling PT_ATTACH from tracee %d\n", getpid());
1452		FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
1453
1454		/* Wait for tracee and assert that it was stopped w/ SIGSTOP */
1455		FORKEE_REQUIRE_SUCCESS(
1456		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1457
1458		forkee_status_stopped(status, SIGSTOP);
1459
1460		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1461		    "tracee");
1462		FORKEE_ASSERT(
1463		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1464
1465		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1466		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1467		    "si_errno=%#x\n",
1468		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1469		    info.psi_siginfo.si_errno);
1470
1471		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, SIGSTOP);
1472		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_USER);
1473
1474		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for child\n");
1475		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
1476		    != -1);
1477
1478		DPRINTF("Assert that there exists a thread\n");
1479		FORKEE_ASSERTX(lwp.pl_lwpid > 0);
1480
1481		DPRINTF("Assert that lwp thread %d received event "
1482		    "PL_EVENT_SIGNAL\n", lwp.pl_lwpid);
1483		FORKEE_ASSERT_EQ(lwp.pl_event, PL_EVENT_SIGNAL);
1484
1485		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
1486		    "tracee\n");
1487		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
1488		    != -1);
1489
1490		DPRINTF("Assert that there are no more lwp threads in "
1491		    "tracee\n");
1492		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
1493
1494		/* Resume tracee with PT_CONTINUE */
1495		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
1496
1497		/* Inform parent that tracer has attached to tracee */
1498		CHILD_TO_PARENT("tracer ready", parent_tracer, msg);
1499
1500		/* Wait for parent */
1501		CHILD_FROM_PARENT("tracer wait", parent_tracer, msg);
1502
1503		/* Wait for tracee and assert that it raised a signal */
1504		FORKEE_REQUIRE_SUCCESS(
1505		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1506
1507		forkee_status_stopped(status, SIGINT);
1508
1509		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1510		    "child");
1511		FORKEE_ASSERT(
1512		    ptrace(PT_GET_SIGINFO, tracee, &info, sizeof(info)) != -1);
1513
1514		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1515		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1516		    "si_errno=%#x\n",
1517		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1518		    info.psi_siginfo.si_errno);
1519
1520		FORKEE_ASSERT_EQ(info.psi_siginfo.si_signo, sigval);
1521		FORKEE_ASSERT_EQ(info.psi_siginfo.si_code, SI_LWP);
1522
1523		memset(&lwp, 0, sizeof(lwp));
1524
1525		for (n = 0; n <= threads; n++) {
1526			DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
1527			    "child\n");
1528			FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp,
1529			    sizeof(lwp)) != -1);
1530			DPRINTF("LWP=%d\n", lwp.pl_lwpid);
1531
1532			DPRINTF("Assert that the thread exists\n");
1533			FORKEE_ASSERT(lwp.pl_lwpid > 0);
1534
1535			DPRINTF("Assert that lwp thread %d received expected "
1536			    "event\n", lwp.pl_lwpid);
1537			FORKEE_ASSERT_EQ(lwp.pl_event,
1538			    info.psi_lwpid == lwp.pl_lwpid ?
1539			    PL_EVENT_SIGNAL : PL_EVENT_NONE);
1540		}
1541		DPRINTF("Before calling ptrace(2) with PT_LWPINFO for "
1542		    "tracee\n");
1543		FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &lwp, sizeof(lwp))
1544		    != -1);
1545		DPRINTF("LWP=%d\n", lwp.pl_lwpid);
1546
1547		DPRINTF("Assert that there are no more threads\n");
1548		FORKEE_ASSERT_EQ(lwp.pl_lwpid, 0);
1549
1550		DPRINTF("Before resuming the child process where it left off "
1551		    "and without signal to be sent\n");
1552		FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, SIGKILL)
1553		    != -1);
1554
1555		/* Wait for tracee and assert that it exited */
1556		FORKEE_REQUIRE_SUCCESS(
1557		    wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
1558
1559		forkee_status_signaled(status, SIGKILL, 0);
1560
1561		DPRINTF("Before exiting of the tracer process\n");
1562		_exit(exitval_tracer);
1563	}
1564
1565	DPRINTF("Wait for the tracer to attach to the tracee\n");
1566	PARENT_FROM_CHILD("tracer ready", parent_tracer, msg);
1567
1568	DPRINTF("Resume the tracee and spawn threads\n");
1569	PARENT_TO_CHILD("spawn threads", parent_tracee, msg);
1570
1571	DPRINTF("Resume the tracee and let it exit\n");
1572	PARENT_FROM_CHILD("tracee exit", parent_tracee, msg);
1573
1574	DPRINTF("Resume the tracer and let it detect multiple threads\n");
1575	PARENT_TO_CHILD("tracer wait", parent_tracer, msg);
1576
1577	DPRINTF("Wait for tracer to finish its job and exit - calling %s()\n",
1578	    TWAIT_FNAME);
1579	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0),
1580	    tracer);
1581
1582	validate_status_exited(status, exitval_tracer);
1583
1584	DPRINTF("Wait for tracee to finish its job and exit - calling %s()\n",
1585	    TWAIT_FNAME);
1586	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG),
1587	    tracee);
1588
1589	validate_status_signaled(status, SIGKILL, 0);
1590
1591	msg_close(&parent_tracer);
1592	msg_close(&parent_tracee);
1593}
1594
1595#define ATTACH_LWPINFO(test, threads)					\
1596ATF_TC(test);								\
1597ATF_TC_HEAD(test, tc)							\
1598{									\
1599	atf_tc_set_md_var(tc, "descr",					\
1600	    "Verify LWPINFO with the child with " #threads		\
1601	    " spawned extra threads (tracer is not the original "	\
1602	    "parent)");							\
1603}									\
1604									\
1605ATF_TC_BODY(test, tc)							\
1606{									\
1607									\
1608	attach_lwpinfo(threads);					\
1609}
1610
1611ATTACH_LWPINFO(attach_lwpinfo0, 0)
1612ATTACH_LWPINFO(attach_lwpinfo1, 1)
1613ATTACH_LWPINFO(attach_lwpinfo2, 2)
1614ATTACH_LWPINFO(attach_lwpinfo3, 3)
1615#endif
1616
1617/// ----------------------------------------------------------------------------
1618
1619static void
1620ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
1621{
1622	const int exitval = 5;
1623	const int sigval = SIGINT;
1624	const int sigfaked = SIGTRAP;
1625	const int sicodefaked = TRAP_BRKPT;
1626	pid_t child, wpid;
1627	struct sigaction sa;
1628#if defined(TWAIT_HAVE_STATUS)
1629	int status;
1630#endif
1631	struct ptrace_siginfo info;
1632	memset(&info, 0, sizeof(info));
1633
1634	DPRINTF("Before forking process PID=%d\n", getpid());
1635	SYSCALL_REQUIRE((child = fork()) != -1);
1636	if (child == 0) {
1637		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1638		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1639
1640		sa.sa_sigaction = sah;
1641		sa.sa_flags = SA_SIGINFO;
1642		sigemptyset(&sa.sa_mask);
1643
1644		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
1645		    != -1);
1646
1647		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1648		FORKEE_ASSERT(raise(sigval) == 0);
1649
1650		FORKEE_ASSERT_EQ(*signal_caught, 1);
1651
1652		DPRINTF("Before exiting of the child process\n");
1653		_exit(exitval);
1654	}
1655	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1656
1657	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1658	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1659
1660	validate_status_stopped(status, sigval);
1661
1662	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1663	SYSCALL_REQUIRE(
1664	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1665
1666	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1667	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1668	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1669	    info.psi_siginfo.si_errno);
1670
1671	if (faked) {
1672		DPRINTF("Before setting new faked signal to signo=%d "
1673		    "si_code=%d\n", sigfaked, sicodefaked);
1674		info.psi_siginfo.si_signo = sigfaked;
1675		info.psi_siginfo.si_code = sicodefaked;
1676	}
1677
1678	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
1679	SYSCALL_REQUIRE(
1680	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
1681
1682	if (faked) {
1683		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1684		    "child\n");
1685		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1686		    sizeof(info)) != -1);
1687
1688		DPRINTF("Before checking siginfo_t\n");
1689		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
1690		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
1691	}
1692
1693	DPRINTF("Before resuming the child process where it left off and "
1694	    "without signal to be sent\n");
1695	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
1696	    faked ? sigfaked : sigval) != -1);
1697
1698	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1699	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1700
1701	validate_status_exited(status, exitval);
1702
1703	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1704	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1705}
1706
1707#define PTRACE_SIGINFO(test, faked)					\
1708ATF_TC(test);								\
1709ATF_TC_HEAD(test, tc)							\
1710{									\
1711	atf_tc_set_md_var(tc, "descr",					\
1712	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
1713	    "with%s setting signal to new value", faked ? "" : "out");	\
1714}									\
1715									\
1716static int test##_caught = 0;						\
1717									\
1718static void								\
1719test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
1720{									\
1721	if (faked) {							\
1722		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
1723		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
1724		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
1725	} else {							\
1726		FORKEE_ASSERT_EQ(sig, SIGINT);				\
1727		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
1728		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
1729	}								\
1730									\
1731	++ test##_caught;						\
1732}									\
1733									\
1734ATF_TC_BODY(test, tc)							\
1735{									\
1736									\
1737	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
1738}
1739
1740PTRACE_SIGINFO(siginfo_set_unmodified, false)
1741PTRACE_SIGINFO(siginfo_set_faked, true)
1742
1743/// ----------------------------------------------------------------------------
1744
1745static void
1746traceme_exec(bool masked, bool ignored)
1747{
1748	const int sigval = SIGTRAP;
1749	pid_t child, wpid;
1750#if defined(TWAIT_HAVE_STATUS)
1751	int status;
1752#endif
1753	struct sigaction sa;
1754	struct ptrace_siginfo info;
1755	sigset_t intmask;
1756	struct kinfo_proc2 kp;
1757	size_t len = sizeof(kp);
1758
1759	int name[6];
1760	const size_t namelen = __arraycount(name);
1761	ki_sigset_t kp_sigmask;
1762	ki_sigset_t kp_sigignore;
1763
1764	memset(&info, 0, sizeof(info));
1765
1766	DPRINTF("Before forking process PID=%d\n", getpid());
1767	SYSCALL_REQUIRE((child = fork()) != -1);
1768	if (child == 0) {
1769		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1770		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1771
1772		if (masked) {
1773			sigemptyset(&intmask);
1774			sigaddset(&intmask, sigval);
1775			sigprocmask(SIG_BLOCK, &intmask, NULL);
1776		}
1777
1778		if (ignored) {
1779			memset(&sa, 0, sizeof(sa));
1780			sa.sa_handler = SIG_IGN;
1781			sigemptyset(&sa.sa_mask);
1782			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
1783		}
1784
1785		DPRINTF("Before calling execve(2) from child\n");
1786		execlp("/bin/echo", "/bin/echo", NULL);
1787
1788		FORKEE_ASSERT(0 && "Not reached");
1789	}
1790	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1791
1792	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1793	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1794
1795	validate_status_stopped(status, sigval);
1796
1797	name[0] = CTL_KERN,
1798	name[1] = KERN_PROC2,
1799	name[2] = KERN_PROC_PID;
1800	name[3] = getpid();
1801	name[4] = sizeof(kp);
1802	name[5] = 1;
1803
1804	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1805
1806	if (masked)
1807		kp_sigmask = kp.p_sigmask;
1808
1809	if (ignored)
1810		kp_sigignore = kp.p_sigignore;
1811
1812	name[3] = getpid();
1813
1814	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1815
1816	if (masked) {
1817		DPRINTF("kp_sigmask="
1818		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1819		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1820		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1821
1822		DPRINTF("kp.p_sigmask="
1823		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1824		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1825		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1826
1827		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
1828		    sizeof(kp_sigmask)));
1829	}
1830
1831	if (ignored) {
1832		DPRINTF("kp_sigignore="
1833		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1834		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1835		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1836
1837		DPRINTF("kp.p_sigignore="
1838		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1839		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1840		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1841
1842		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
1843		    sizeof(kp_sigignore)));
1844	}
1845
1846	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1847	SYSCALL_REQUIRE(
1848	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1849
1850	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1851	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1852	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1853	    info.psi_siginfo.si_errno);
1854
1855	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1856	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1857
1858	DPRINTF("Before resuming the child process where it left off and "
1859	    "without signal to be sent\n");
1860	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1861
1862	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1863	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1864
1865	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1866	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1867}
1868
1869#define TRACEME_EXEC(test, masked, ignored)				\
1870ATF_TC(test);								\
1871ATF_TC_HEAD(test, tc)							\
1872{									\
1873       atf_tc_set_md_var(tc, "descr",					\
1874           "Detect SIGTRAP TRAP_EXEC from "				\
1875           "child%s%s", masked ? " with masked signal" : "",		\
1876           masked ? " with ignored signal" : "");			\
1877}									\
1878									\
1879ATF_TC_BODY(test, tc)							\
1880{									\
1881									\
1882       traceme_exec(masked, ignored);					\
1883}
1884
1885TRACEME_EXEC(traceme_exec, false, false)
1886TRACEME_EXEC(traceme_signalmasked_exec, true, false)
1887TRACEME_EXEC(traceme_signalignored_exec, false, true)
1888
1889/// ----------------------------------------------------------------------------
1890
1891#define TRACE_THREADS_NUM 100
1892
1893static volatile int done;
1894pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
1895
1896static void *
1897trace_threads_cb(void *arg __unused)
1898{
1899
1900	pthread_mutex_lock(&trace_threads_mtx);
1901	done++;
1902	pthread_mutex_unlock(&trace_threads_mtx);
1903
1904	while (done < TRACE_THREADS_NUM)
1905		sched_yield();
1906
1907	return NULL;
1908}
1909
1910static void
1911trace_threads(bool trace_create, bool trace_exit, bool masked)
1912{
1913	const int sigval = SIGSTOP;
1914	pid_t child, wpid;
1915#if defined(TWAIT_HAVE_STATUS)
1916	int status;
1917#endif
1918	ptrace_state_t state;
1919	const int slen = sizeof(state);
1920	ptrace_event_t event;
1921	const int elen = sizeof(event);
1922	struct ptrace_siginfo info;
1923
1924	sigset_t intmask;
1925
1926	pthread_t t[TRACE_THREADS_NUM];
1927	int rv;
1928	size_t n;
1929	lwpid_t lid;
1930
1931	/* Track created and exited threads */
1932	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
1933
1934	DPRINTF("Before forking process PID=%d\n", getpid());
1935	SYSCALL_REQUIRE((child = fork()) != -1);
1936	if (child == 0) {
1937		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1938		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1939
1940		if (masked) {
1941			sigemptyset(&intmask);
1942			sigaddset(&intmask, SIGTRAP);
1943			sigprocmask(SIG_BLOCK, &intmask, NULL);
1944		}
1945
1946		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1947		FORKEE_ASSERT(raise(sigval) == 0);
1948
1949		for (n = 0; n < __arraycount(t); n++) {
1950			rv = pthread_create(&t[n], NULL, trace_threads_cb,
1951			    NULL);
1952			FORKEE_ASSERT(rv == 0);
1953		}
1954
1955		for (n = 0; n < __arraycount(t); n++) {
1956			rv = pthread_join(t[n], NULL);
1957			FORKEE_ASSERT(rv == 0);
1958		}
1959
1960		/*
1961		 * There is race between _exit() and pthread_join() detaching
1962		 * a thread. For simplicity kill the process after detecting
1963		 * LWP events.
1964		 */
1965		while (true)
1966			continue;
1967
1968		FORKEE_ASSERT(0 && "Not reached");
1969	}
1970	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1971
1972	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1973	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1974
1975	validate_status_stopped(status, sigval);
1976
1977	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1978	SYSCALL_REQUIRE(
1979	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1980
1981	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1982	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1983	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1984	    info.psi_siginfo.si_errno);
1985
1986	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1987	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1988
1989	DPRINTF("Set LWP event mask for the child %d\n", child);
1990	memset(&event, 0, sizeof(event));
1991	if (trace_create)
1992		event.pe_set_event |= PTRACE_LWP_CREATE;
1993	if (trace_exit)
1994		event.pe_set_event |= PTRACE_LWP_EXIT;
1995	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1996
1997	DPRINTF("Before resuming the child process where it left off and "
1998	    "without signal to be sent\n");
1999	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2000
2001	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
2002		DPRINTF("Before calling %s() for the child - expected stopped "
2003		    "SIGTRAP\n", TWAIT_FNAME);
2004		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2005		    child);
2006
2007		validate_status_stopped(status, SIGTRAP);
2008
2009		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2010		    "child\n");
2011		SYSCALL_REQUIRE(
2012		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2013
2014		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2015		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2016		    "si_errno=%#x\n",
2017		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2018		    info.psi_siginfo.si_errno);
2019
2020		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
2021		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
2022
2023		SYSCALL_REQUIRE(
2024		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2025
2026		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
2027		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
2028
2029		lid = state.pe_lwp;
2030		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
2031
2032		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
2033
2034		DPRINTF("Before resuming the child process where it left off "
2035		    "and without signal to be sent\n");
2036		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2037	}
2038
2039	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
2040		DPRINTF("Before calling %s() for the child - expected stopped "
2041		    "SIGTRAP\n", TWAIT_FNAME);
2042		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2043		    child);
2044
2045		validate_status_stopped(status, SIGTRAP);
2046
2047		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2048		    "child\n");
2049		SYSCALL_REQUIRE(
2050		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2051
2052		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2053		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2054		    "si_errno=%#x\n",
2055		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2056		    info.psi_siginfo.si_errno);
2057
2058		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
2059		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
2060
2061		SYSCALL_REQUIRE(
2062		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2063
2064		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
2065		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
2066
2067		lid = state.pe_lwp;
2068		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
2069
2070		if (trace_create) {
2071			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
2072			ATF_REQUIRE_EQ(*count, 1);
2073			*count = 0;
2074		}
2075
2076		DPRINTF("Before resuming the child process where it left off "
2077		    "and without signal to be sent\n");
2078		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2079	}
2080
2081	kill(child, SIGKILL);
2082
2083	DPRINTF("Before calling %s() for the child - expected exited\n",
2084	    TWAIT_FNAME);
2085	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2086
2087	validate_status_signaled(status, SIGKILL, 0);
2088
2089	DPRINTF("Before calling %s() for the child - expected no process\n",
2090	    TWAIT_FNAME);
2091	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2092}
2093
2094#define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
2095ATF_TC(test);								\
2096ATF_TC_HEAD(test, tc)							\
2097{									\
2098        atf_tc_set_md_var(tc, "descr",					\
2099            "Verify spawning threads with%s tracing LWP create and"	\
2100	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
2101	    trace_exit ? "" : "out");					\
2102}									\
2103									\
2104ATF_TC_BODY(test, tc)							\
2105{									\
2106									\
2107        trace_threads(trace_create, trace_exit, mask);			\
2108}
2109
2110TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
2111TRACE_THREADS(trace_thread_lwpexit, false, true, false)
2112TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
2113TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
2114
2115TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
2116TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
2117TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
2118
2119/// ----------------------------------------------------------------------------
2120
2121static void *
2122thread_and_exec_thread_cb(void *arg __unused)
2123{
2124
2125	execlp("/bin/echo", "/bin/echo", NULL);
2126
2127	abort();
2128}
2129
2130static void
2131threads_and_exec(void)
2132{
2133	const int sigval = SIGSTOP;
2134	pid_t child, wpid;
2135#if defined(TWAIT_HAVE_STATUS)
2136	int status;
2137#endif
2138	ptrace_state_t state;
2139	const int slen = sizeof(state);
2140	ptrace_event_t event;
2141	const int elen = sizeof(event);
2142	struct ptrace_siginfo info;
2143
2144	pthread_t t;
2145	lwpid_t lid;
2146
2147	DPRINTF("Before forking process PID=%d\n", getpid());
2148	SYSCALL_REQUIRE((child = fork()) != -1);
2149	if (child == 0) {
2150		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2151		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2152
2153		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2154		FORKEE_ASSERT(raise(sigval) == 0);
2155
2156		FORKEE_ASSERT(pthread_create(&t, NULL,
2157		    thread_and_exec_thread_cb, NULL) == 0);
2158
2159		for (;;)
2160			continue;
2161
2162		FORKEE_ASSERT(0 && "Not reached");
2163	}
2164	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2165
2166	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2167	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2168
2169	validate_status_stopped(status, sigval);
2170
2171	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
2172	SYSCALL_REQUIRE(
2173	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2174
2175	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2176	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
2177	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2178	    info.psi_siginfo.si_errno);
2179
2180	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
2181	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
2182
2183	DPRINTF("Set LWP event mask for the child %d\n", child);
2184	memset(&event, 0, sizeof(event));
2185	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
2186	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
2187
2188	DPRINTF("Before resuming the child process where it left off and "
2189	    "without signal to be sent\n");
2190	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2191
2192	DPRINTF("Before calling %s() for the child - expected stopped "
2193	    "SIGTRAP\n", TWAIT_FNAME);
2194	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2195	    child);
2196
2197	validate_status_stopped(status, SIGTRAP);
2198
2199	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2200	    "child\n");
2201	SYSCALL_REQUIRE(
2202	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2203
2204	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2205	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2206	    "si_errno=%#x\n",
2207	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2208	    info.psi_siginfo.si_errno);
2209
2210	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
2211	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
2212
2213	SYSCALL_REQUIRE(
2214	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2215
2216	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
2217	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
2218
2219	lid = state.pe_lwp;
2220	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
2221
2222	DPRINTF("Before resuming the child process where it left off "
2223	    "and without signal to be sent\n");
2224	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2225
2226	DPRINTF("Before calling %s() for the child - expected stopped "
2227	    "SIGTRAP\n", TWAIT_FNAME);
2228	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2229	    child);
2230
2231	validate_status_stopped(status, SIGTRAP);
2232
2233	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2234	    "child\n");
2235	SYSCALL_REQUIRE(
2236	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2237
2238	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2239	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2240	    "si_errno=%#x\n",
2241	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2242	    info.psi_siginfo.si_errno);
2243
2244	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
2245	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
2246
2247	SYSCALL_REQUIRE(
2248	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
2249
2250	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
2251	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
2252
2253	lid = state.pe_lwp;
2254	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
2255
2256	DPRINTF("Before resuming the child process where it left off "
2257	    "and without signal to be sent\n");
2258	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2259
2260	DPRINTF("Before calling %s() for the child - expected stopped "
2261	    "SIGTRAP\n", TWAIT_FNAME);
2262	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2263	    child);
2264
2265	validate_status_stopped(status, SIGTRAP);
2266
2267	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2268	    "child\n");
2269	SYSCALL_REQUIRE(
2270	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
2271
2272	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2273	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2274	    "si_errno=%#x\n",
2275	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2276	    info.psi_siginfo.si_errno);
2277
2278	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
2279	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
2280
2281	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
2282
2283	DPRINTF("Before calling %s() for the child - expected exited\n",
2284	    TWAIT_FNAME);
2285	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2286
2287	validate_status_signaled(status, SIGKILL, 0);
2288
2289	DPRINTF("Before calling %s() for the child - expected no process\n",
2290	    TWAIT_FNAME);
2291	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2292}
2293
2294ATF_TC(threads_and_exec);
2295ATF_TC_HEAD(threads_and_exec, tc)
2296{
2297        atf_tc_set_md_var(tc, "descr",
2298            "Verify that multithreaded application on exec() will report "
2299	    "LWP_EXIT events");
2300}
2301
2302ATF_TC_BODY(threads_and_exec, tc)
2303{
2304
2305        threads_and_exec();
2306}
2307
2308/// ----------------------------------------------------------------------------
2309
2310ATF_TC(suspend_no_deadlock);
2311ATF_TC_HEAD(suspend_no_deadlock, tc)
2312{
2313	atf_tc_set_md_var(tc, "descr",
2314	    "Verify that the while the only thread within a process is "
2315	    "suspended, the whole process cannot be unstopped");
2316}
2317
2318ATF_TC_BODY(suspend_no_deadlock, tc)
2319{
2320	const int exitval = 5;
2321	const int sigval = SIGSTOP;
2322	pid_t child, wpid;
2323#if defined(TWAIT_HAVE_STATUS)
2324	int status;
2325#endif
2326	struct ptrace_siginfo psi;
2327
2328	DPRINTF("Before forking process PID=%d\n", getpid());
2329	SYSCALL_REQUIRE((child = fork()) != -1);
2330	if (child == 0) {
2331		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2332		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2333
2334		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2335		FORKEE_ASSERT(raise(sigval) == 0);
2336
2337		DPRINTF("Before exiting of the child process\n");
2338		_exit(exitval);
2339	}
2340	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2341
2342	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2343	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2344
2345	validate_status_stopped(status, sigval);
2346
2347	DPRINTF("Before reading siginfo and lwpid_t\n");
2348	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
2349
2350	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
2351	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
2352
2353	DPRINTF("Before resuming the child process where it left off and "
2354	    "without signal to be sent\n");
2355	ATF_REQUIRE_ERRNO(EDEADLK,
2356	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
2357
2358	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
2359	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
2360
2361	DPRINTF("Before resuming the child process where it left off and "
2362	    "without signal to be sent\n");
2363	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2364
2365	DPRINTF("Before calling %s() for the child - expected exited\n",
2366	    TWAIT_FNAME);
2367	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2368
2369	validate_status_exited(status, exitval);
2370
2371	DPRINTF("Before calling %s() for the child - expected no process\n",
2372	    TWAIT_FNAME);
2373	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2374}
2375
2376/// ----------------------------------------------------------------------------
2377
2378static pthread_barrier_t barrier1_resume;
2379static pthread_barrier_t barrier2_resume;
2380
2381static void *
2382resume_thread(void *arg)
2383{
2384
2385	raise(SIGUSR1);
2386
2387	pthread_barrier_wait(&barrier1_resume);
2388
2389	/* Debugger will suspend the process here */
2390
2391	pthread_barrier_wait(&barrier2_resume);
2392
2393	raise(SIGUSR2);
2394
2395	return infinite_thread(arg);
2396}
2397
2398ATF_TC(resume);
2399ATF_TC_HEAD(resume, tc)
2400{
2401	atf_tc_set_md_var(tc, "descr",
2402	    "Verify that a thread can be suspended by a debugger and later "
2403	    "resumed by the debugger");
2404}
2405
2406ATF_TC_BODY(resume, tc)
2407{
2408	const int sigval = SIGSTOP;
2409	pid_t child, wpid;
2410#if defined(TWAIT_HAVE_STATUS)
2411	int status;
2412#endif
2413	lwpid_t lid;
2414	struct ptrace_siginfo psi;
2415	pthread_t t;
2416
2417	DPRINTF("Before forking process PID=%d\n", getpid());
2418	SYSCALL_REQUIRE((child = fork()) != -1);
2419	if (child == 0) {
2420		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2421		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2422
2423		pthread_barrier_init(&barrier1_resume, NULL, 2);
2424		pthread_barrier_init(&barrier2_resume, NULL, 2);
2425
2426		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2427		FORKEE_ASSERT(raise(sigval) == 0);
2428
2429		DPRINTF("Before creating new thread in child\n");
2430		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
2431
2432		pthread_barrier_wait(&barrier1_resume);
2433
2434		pthread_barrier_wait(&barrier2_resume);
2435
2436		infinite_thread(NULL);
2437	}
2438	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2439
2440	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2441	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2442
2443	validate_status_stopped(status, sigval);
2444
2445	DPRINTF("Before resuming the child process where it left off and "
2446	    "without signal to be sent\n");
2447	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2448
2449	DPRINTF("Before calling %s() for the child - expected stopped "
2450	    "SIGUSR1\n", TWAIT_FNAME);
2451	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2452
2453	validate_status_stopped(status, SIGUSR1);
2454
2455	DPRINTF("Before reading siginfo and lwpid_t\n");
2456	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
2457
2458	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
2459	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
2460
2461	lid = psi.psi_lwpid;
2462
2463	DPRINTF("Before resuming the child process where it left off and "
2464	    "without signal to be sent\n");
2465	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2466
2467	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
2468	SYSCALL_REQUIRE(sleep(1) == 0);
2469
2470#if defined(TWAIT_HAVE_OPTIONS)
2471	DPRINTF("Before calling %s() for the child - expected no status\n",
2472	    TWAIT_FNAME);
2473	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
2474#endif
2475
2476	DPRINTF("Before resuming the child process where it left off and "
2477	    "without signal to be sent\n");
2478	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
2479
2480	DPRINTF("Before calling %s() for the child - expected stopped "
2481	    "SIGSTOP\n", TWAIT_FNAME);
2482	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2483
2484	validate_status_stopped(status, SIGSTOP);
2485
2486	DPRINTF("Before resuming LWP %d\n", lid);
2487	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
2488
2489	DPRINTF("Before resuming the child process where it left off and "
2490	    "without signal to be sent\n");
2491	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2492
2493	DPRINTF("Before calling %s() for the child - expected stopped "
2494	    "SIGUSR2\n", TWAIT_FNAME);
2495	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2496
2497	validate_status_stopped(status, SIGUSR2);
2498
2499	DPRINTF("Before resuming the child process where it left off and "
2500	    "without signal to be sent\n");
2501	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
2502
2503	DPRINTF("Before calling %s() for the child - expected exited\n",
2504	    TWAIT_FNAME);
2505	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2506
2507	validate_status_signaled(status, SIGKILL, 0);
2508
2509	DPRINTF("Before calling %s() for the child - expected no process\n",
2510	    TWAIT_FNAME);
2511	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2512}
2513
2514/// ----------------------------------------------------------------------------
2515
2516static void
2517user_va0_disable(int operation)
2518{
2519	pid_t child, wpid;
2520#if defined(TWAIT_HAVE_STATUS)
2521	int status;
2522#endif
2523	const int sigval = SIGSTOP;
2524	int rv;
2525
2526	struct ptrace_siginfo info;
2527
2528	if (get_user_va0_disable() == 0)
2529		atf_tc_skip("vm.user_va0_disable is set to 0");
2530
2531	memset(&info, 0, sizeof(info));
2532
2533	DPRINTF("Before forking process PID=%d\n", getpid());
2534	SYSCALL_REQUIRE((child = fork()) != -1);
2535	if (child == 0) {
2536		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2537		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2538
2539		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2540		FORKEE_ASSERT(raise(sigval) == 0);
2541
2542		/* NOTREACHED */
2543		FORKEE_ASSERTX(0 && "This shall not be reached");
2544		__unreachable();
2545	}
2546	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2547
2548	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2549	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2550
2551	validate_status_stopped(status, sigval);
2552
2553	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
2554		"child\n");
2555	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
2556		sizeof(info)) != -1);
2557
2558	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
2559	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
2560		"si_errno=%#x\n",
2561		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
2562		info.psi_siginfo.si_errno);
2563
2564	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
2565	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
2566
2567	DPRINTF("Before resuming the child process in PC=0x0 "
2568	    "and without signal to be sent\n");
2569	errno = 0;
2570	rv = ptrace(operation, child, (void *)0, 0);
2571	ATF_REQUIRE_EQ(errno, EINVAL);
2572	ATF_REQUIRE_EQ(rv, -1);
2573
2574	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
2575
2576	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2577	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2578	validate_status_signaled(status, SIGKILL, 0);
2579
2580	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2581	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2582}
2583
2584#define USER_VA0_DISABLE(test, operation)				\
2585ATF_TC(test);								\
2586ATF_TC_HEAD(test, tc)							\
2587{									\
2588	atf_tc_set_md_var(tc, "descr",					\
2589	    "Verify behavior of " #operation " with PC set to 0x0");	\
2590}									\
2591									\
2592ATF_TC_BODY(test, tc)							\
2593{									\
2594									\
2595	user_va0_disable(operation);					\
2596}
2597
2598USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
2599USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
2600USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
2601
2602/// ----------------------------------------------------------------------------
2603
2604/*
2605 * Parse the core file and find the requested note.  If the reading or parsing
2606 * fails, the test is failed.  If the note is found, it is read onto buf, up to
2607 * buf_len.  The actual length of the note is returned (which can be greater
2608 * than buf_len, indicating that it has been truncated).  If the note is not
2609 * found, -1 is returned.
2610 *
2611 * If the note_name ends in '*', then we find the first note that matches
2612 * the note_name prefix up to the '*' character, e.g.:
2613 *
2614 *	NetBSD-CORE@*
2615 *
2616 * finds the first note whose name prefix matches "NetBSD-CORE@".
2617 */
2618static ssize_t core_find_note(const char *core_path,
2619    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
2620{
2621	int core_fd;
2622	Elf *core_elf;
2623	size_t core_numhdr, i;
2624	ssize_t ret = -1;
2625	size_t name_len = strlen(note_name);
2626	bool prefix_match = false;
2627
2628	if (note_name[name_len - 1] == '*') {
2629		prefix_match = true;
2630		name_len--;
2631	} else {
2632		/* note: we assume note name will be null-terminated */
2633		name_len++;
2634	}
2635
2636	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
2637	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
2638	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
2639
2640	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
2641	for (i = 0; i < core_numhdr && ret == -1; i++) {
2642		GElf_Phdr core_hdr;
2643		size_t offset;
2644		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
2645		if (core_hdr.p_type != PT_NOTE)
2646		    continue;
2647
2648		for (offset = core_hdr.p_offset;
2649		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
2650			Elf64_Nhdr note_hdr;
2651			char name_buf[64];
2652
2653			switch (gelf_getclass(core_elf)) {
2654			case ELFCLASS64:
2655				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
2656				    sizeof(note_hdr), offset)
2657				    == sizeof(note_hdr));
2658				offset += sizeof(note_hdr);
2659				break;
2660			case ELFCLASS32:
2661				{
2662				Elf32_Nhdr tmp_hdr;
2663				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
2664				    sizeof(tmp_hdr), offset)
2665				    == sizeof(tmp_hdr));
2666				offset += sizeof(tmp_hdr);
2667				note_hdr.n_namesz = tmp_hdr.n_namesz;
2668				note_hdr.n_descsz = tmp_hdr.n_descsz;
2669				note_hdr.n_type = tmp_hdr.n_type;
2670				}
2671				break;
2672			}
2673
2674			/* indicates end of notes */
2675			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
2676				break;
2677			if (((prefix_match &&
2678			      note_hdr.n_namesz > name_len) ||
2679			     (!prefix_match &&
2680			      note_hdr.n_namesz == name_len)) &&
2681			    note_hdr.n_namesz <= sizeof(name_buf)) {
2682				SYSCALL_REQUIRE(pread(core_fd, name_buf,
2683				    note_hdr.n_namesz, offset)
2684				    == (ssize_t)(size_t)note_hdr.n_namesz);
2685
2686				if (!strncmp(note_name, name_buf, name_len) &&
2687				    note_hdr.n_type == note_type)
2688					ret = note_hdr.n_descsz;
2689			}
2690
2691			offset += note_hdr.n_namesz;
2692			/* fix to alignment */
2693			offset = roundup(offset, core_hdr.p_align);
2694
2695			/* if name & type matched above */
2696			if (ret != -1) {
2697				ssize_t read_len = MIN(buf_len,
2698				    note_hdr.n_descsz);
2699				SYSCALL_REQUIRE(pread(core_fd, buf,
2700				    read_len, offset) == read_len);
2701				break;
2702			}
2703
2704			offset += note_hdr.n_descsz;
2705			/* fix to alignment */
2706			offset = roundup(offset, core_hdr.p_align);
2707		}
2708	}
2709
2710	elf_end(core_elf);
2711	close(core_fd);
2712
2713	return ret;
2714}
2715
2716ATF_TC(core_dump_procinfo);
2717ATF_TC_HEAD(core_dump_procinfo, tc)
2718{
2719	atf_tc_set_md_var(tc, "descr",
2720		"Trigger a core dump and verify its contents.");
2721}
2722
2723ATF_TC_BODY(core_dump_procinfo, tc)
2724{
2725	const int exitval = 5;
2726	pid_t child, wpid;
2727#if defined(TWAIT_HAVE_STATUS)
2728	const int sigval = SIGTRAP;
2729	int status;
2730#endif
2731	char core_path[] = "/tmp/core.XXXXXX";
2732	int core_fd;
2733	struct netbsd_elfcore_procinfo procinfo;
2734
2735	DPRINTF("Before forking process PID=%d\n", getpid());
2736	SYSCALL_REQUIRE((child = fork()) != -1);
2737	if (child == 0) {
2738		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2739		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2740
2741		DPRINTF("Before triggering SIGTRAP\n");
2742		trigger_trap();
2743
2744		DPRINTF("Before exiting of the child process\n");
2745		_exit(exitval);
2746	}
2747	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2748
2749	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2750	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2751
2752	validate_status_stopped(status, sigval);
2753
2754	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
2755	close(core_fd);
2756
2757	DPRINTF("Call DUMPCORE for the child process\n");
2758	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
2759	    != -1);
2760
2761	DPRINTF("Read core file\n");
2762	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
2763	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
2764	    sizeof(procinfo));
2765
2766	ATF_CHECK_EQ(procinfo.cpi_version, 1);
2767	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
2768	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
2769	ATF_CHECK_EQ(procinfo.cpi_pid, child);
2770	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
2771	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
2772	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
2773	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
2774	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
2775	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
2776	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
2777	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
2778	ATF_CHECK(procinfo.cpi_siglwp > 0);
2779
2780	unlink(core_path);
2781
2782	DPRINTF("Before resuming the child process where it left off and "
2783	    "without signal to be sent\n");
2784	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2785
2786	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2787	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2788
2789	validate_status_exited(status, exitval);
2790
2791	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2792	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2793}
2794
2795/// ----------------------------------------------------------------------------
2796
2797#if defined(TWAIT_HAVE_STATUS)
2798
2799#define THREAD_CONCURRENT_BREAKPOINT_NUM 50
2800#define THREAD_CONCURRENT_SIGNALS_NUM 50
2801#define THREAD_CONCURRENT_WATCHPOINT_NUM 50
2802
2803/* List of signals to use for the test */
2804const int thread_concurrent_signals_list[] = {
2805	SIGIO,
2806	SIGXCPU,
2807	SIGXFSZ,
2808	SIGVTALRM,
2809	SIGPROF,
2810	SIGWINCH,
2811	SIGINFO,
2812	SIGUSR1,
2813	SIGUSR2
2814};
2815
2816enum thread_concurrent_signal_handling {
2817	/* the signal is discarded by debugger */
2818	TCSH_DISCARD,
2819	/* the handler is set to SIG_IGN */
2820	TCSH_SIG_IGN,
2821	/* an actual handler is used */
2822	TCSH_HANDLER
2823};
2824
2825static pthread_barrier_t thread_concurrent_barrier;
2826static pthread_key_t thread_concurrent_key;
2827static uint32_t thread_concurrent_watchpoint_var = 0;
2828
2829static void *
2830thread_concurrent_breakpoint_thread(void *arg)
2831{
2832	static volatile int watchme = 1;
2833	pthread_barrier_wait(&thread_concurrent_barrier);
2834	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
2835	check_happy(watchme);
2836	return NULL;
2837}
2838
2839static void
2840thread_concurrent_sig_handler(int sig)
2841{
2842	void *tls_val = pthread_getspecific(thread_concurrent_key);
2843	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
2844	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
2845	    (void*)((uintptr_t)tls_val + 1)) == 0);
2846}
2847
2848static void *
2849thread_concurrent_signals_thread(void *arg)
2850{
2851	int sigval = thread_concurrent_signals_list[
2852	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
2853	enum thread_concurrent_signal_handling *signal_handle = arg;
2854	void *tls_val;
2855
2856	pthread_barrier_wait(&thread_concurrent_barrier);
2857	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
2858		_lwp_self());
2859	pthread_kill(pthread_self(), sigval);
2860	if (*signal_handle == TCSH_HANDLER) {
2861	    tls_val = pthread_getspecific(thread_concurrent_key);
2862	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
2863	    FORKEE_ASSERT(tls_val == (void*)1);
2864	}
2865	return NULL;
2866}
2867
2868static void *
2869thread_concurrent_watchpoint_thread(void *arg)
2870{
2871	pthread_barrier_wait(&thread_concurrent_barrier);
2872	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
2873	thread_concurrent_watchpoint_var = 1;
2874	return NULL;
2875}
2876
2877#if defined(__i386__) || defined(__x86_64__)
2878enum thread_concurrent_sigtrap_event {
2879	TCSE_UNKNOWN,
2880	TCSE_BREAKPOINT,
2881	TCSE_WATCHPOINT
2882};
2883
2884static void
2885thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
2886static enum thread_concurrent_sigtrap_event
2887thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
2888#endif
2889
2890static void
2891thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
2892    int breakpoint_threads, int signal_threads, int watchpoint_threads)
2893{
2894	const int exitval = 5;
2895	const int sigval = SIGSTOP;
2896	pid_t child, wpid;
2897	int status;
2898	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
2899	    = {{0, 0}};
2900	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
2901	    = {{0, 0}};
2902	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
2903	    = {{0, 0}};
2904	ptrace_event_t event;
2905	int i;
2906
2907#if defined(HAVE_DBREGS)
2908	if (!can_we_set_dbregs()) {
2909		atf_tc_skip("Either run this test as root or set sysctl(3) "
2910		            "security.models.extensions.user_set_dbregs to 1");
2911        }
2912#endif
2913
2914	atf_tc_skip("PR kern/54960");
2915
2916	/* Protect against out-of-bounds array access. */
2917	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
2918	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
2919	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
2920
2921	DPRINTF("Before forking process PID=%d\n", getpid());
2922	SYSCALL_REQUIRE((child = fork()) != -1);
2923	if (child == 0) {
2924		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
2925		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
2926		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
2927
2928		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2929		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2930
2931		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2932		FORKEE_ASSERT(raise(sigval) == 0);
2933
2934		if (signal_handle != TCSH_DISCARD) {
2935			struct sigaction sa;
2936			unsigned int j;
2937
2938			memset(&sa, 0, sizeof(sa));
2939			if (signal_handle == TCSH_SIG_IGN)
2940				sa.sa_handler = SIG_IGN;
2941			else
2942				sa.sa_handler = thread_concurrent_sig_handler;
2943			sigemptyset(&sa.sa_mask);
2944
2945			for (j = 0;
2946			    j < __arraycount(thread_concurrent_signals_list);
2947			    j++)
2948				FORKEE_ASSERT(sigaction(
2949				    thread_concurrent_signals_list[j], &sa, NULL)
2950				    != -1);
2951		}
2952
2953		DPRINTF("Before starting threads from the child\n");
2954		FORKEE_ASSERT(pthread_barrier_init(
2955		    &thread_concurrent_barrier, NULL,
2956		    breakpoint_threads + signal_threads + watchpoint_threads)
2957		    == 0);
2958		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
2959		    == 0);
2960
2961		for (i = 0; i < signal_threads; i++) {
2962			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
2963			    thread_concurrent_signals_thread,
2964			    &signal_handle) == 0);
2965		}
2966		for (i = 0; i < breakpoint_threads; i++) {
2967			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
2968			    thread_concurrent_breakpoint_thread, NULL) == 0);
2969		}
2970		for (i = 0; i < watchpoint_threads; i++) {
2971			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
2972			    thread_concurrent_watchpoint_thread, NULL) == 0);
2973		}
2974
2975		DPRINTF("Before joining threads from the child\n");
2976		for (i = 0; i < watchpoint_threads; i++) {
2977			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
2978		}
2979		for (i = 0; i < breakpoint_threads; i++) {
2980			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
2981		}
2982		for (i = 0; i < signal_threads; i++) {
2983			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
2984		}
2985
2986		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
2987		FORKEE_ASSERT(pthread_barrier_destroy(
2988		    &thread_concurrent_barrier) == 0);
2989
2990		DPRINTF("Before exiting of the child process\n");
2991		_exit(exitval);
2992	}
2993	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2994
2995	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2996	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2997
2998	validate_status_stopped(status, sigval);
2999
3000	DPRINTF("Set LWP event mask for the child process\n");
3001	memset(&event, 0, sizeof(event));
3002	event.pe_set_event |= PTRACE_LWP_CREATE;
3003	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
3004	    != -1);
3005
3006	DPRINTF("Before resuming the child process where it left off\n");
3007	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
3008
3009	DPRINTF("Before entering signal collection loop\n");
3010	while (1) {
3011		ptrace_siginfo_t info;
3012
3013		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
3014		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
3015		    child);
3016		if (WIFEXITED(status))
3017			break;
3018		/* Note: we use validate_status_stopped() to get nice error
3019		 * message.  Signal is irrelevant since it won't be reached.
3020		 */
3021		else if (!WIFSTOPPED(status))
3022			validate_status_stopped(status, 0);
3023
3024		DPRINTF("Before calling PT_GET_SIGINFO\n");
3025		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
3026		    sizeof(info)) != -1);
3027
3028		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
3029		    info.psi_siginfo.si_signo, info.psi_lwpid,
3030		    WSTOPSIG(status));
3031
3032		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
3033		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
3034		    WSTOPSIG(status), info.psi_siginfo.si_signo);
3035
3036		if (WSTOPSIG(status) != SIGTRAP) {
3037			int expected_sig =
3038			    thread_concurrent_signals_list[info.psi_lwpid %
3039			    __arraycount(thread_concurrent_signals_list)];
3040			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
3041				"lwp=%d, expected %d, got %d", info.psi_lwpid,
3042				expected_sig, WSTOPSIG(status));
3043
3044			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
3045		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
3046#if defined(__i386__) || defined(__x86_64__)
3047			thread_concurrent_lwp_setup(child, info.psi_lwpid);
3048#endif
3049		} else {
3050#if defined(__i386__) || defined(__x86_64__)
3051			switch (thread_concurrent_handle_sigtrap(child, &info)) {
3052				case TCSE_UNKNOWN:
3053					/* already reported inside the function */
3054					break;
3055				case TCSE_BREAKPOINT:
3056					*FIND_EVENT_COUNT(bp_counts,
3057					    info.psi_lwpid) += 1;
3058					break;
3059				case TCSE_WATCHPOINT:
3060					*FIND_EVENT_COUNT(wp_counts,
3061					    info.psi_lwpid) += 1;
3062					break;
3063			}
3064#else
3065			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
3066			    info.psi_siginfo.si_code);
3067#endif
3068		}
3069
3070		DPRINTF("Before resuming the child process\n");
3071		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
3072		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
3073		     ? WSTOPSIG(status) : 0) != -1);
3074	}
3075
3076	for (i = 0; i < signal_threads; i++)
3077		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
3078		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
3079		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
3080	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
3081		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
3082		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
3083		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
3084
3085	for (i = 0; i < breakpoint_threads; i++)
3086		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
3087		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
3088		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
3089	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
3090		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
3091		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
3092		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
3093
3094	for (i = 0; i < watchpoint_threads; i++)
3095		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
3096		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
3097		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
3098	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
3099		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
3100		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
3101		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
3102
3103	validate_status_exited(status, exitval);
3104}
3105
3106#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
3107ATF_TC(test);								\
3108ATF_TC_HEAD(test, tc)							\
3109{									\
3110	atf_tc_set_md_var(tc, "descr", descr);				\
3111}									\
3112									\
3113ATF_TC_BODY(test, tc)							\
3114{									\
3115	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
3116}
3117
3118THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
3119    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3120    "Verify that concurrent signals issued to a single thread are reported "
3121    "correctly");
3122THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
3123    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3124    "Verify that concurrent signals issued to a single thread are reported "
3125    "correctly and passed back to SIG_IGN handler");
3126THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
3127    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3128    "Verify that concurrent signals issued to a single thread are reported "
3129    "correctly and passed back to a handler function");
3130
3131#if defined(__i386__) || defined(__x86_64__)
3132THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
3133    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
3134    "Verify that concurrent breakpoints are reported correctly");
3135THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
3136    0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
3137    "Verify that concurrent breakpoints are reported correctly");
3138THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
3139    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
3140    "Verify that concurrent breakpoints and watchpoints are reported "
3141    "correctly");
3142
3143THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
3144    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3145    "Verify that concurrent breakpoints and signals are reported correctly");
3146THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
3147    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3148    "Verify that concurrent breakpoints and signals are reported correctly "
3149    "and passed back to SIG_IGN handler");
3150THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
3151    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
3152    "Verify that concurrent breakpoints and signals are reported correctly "
3153    "and passed back to a handler function");
3154
3155THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
3156    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
3157    "Verify that concurrent watchpoints and signals are reported correctly");
3158THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
3159    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
3160    "Verify that concurrent watchpoints and signals are reported correctly "
3161    "and passed back to SIG_IGN handler");
3162THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
3163    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
3164    "Verify that concurrent watchpoints and signals are reported correctly "
3165    "and passed back to a handler function");
3166
3167THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
3168    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
3169    THREAD_CONCURRENT_WATCHPOINT_NUM,
3170    "Verify that concurrent breakpoints, watchpoints and signals are reported "
3171    "correctly");
3172THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
3173    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
3174    THREAD_CONCURRENT_WATCHPOINT_NUM,
3175    "Verify that concurrent breakpoints, watchpoints and signals are reported "
3176    "correctly and passed back to SIG_IGN handler");
3177THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
3178    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
3179    THREAD_CONCURRENT_WATCHPOINT_NUM,
3180    "Verify that concurrent breakpoints, watchpoints and signals are reported "
3181    "correctly and passed back to a handler function");
3182#endif
3183
3184#endif /*defined(TWAIT_HAVE_STATUS)*/
3185
3186/// ----------------------------------------------------------------------------
3187
3188#include "t_ptrace_register_wait.h"
3189#include "t_ptrace_syscall_wait.h"
3190#include "t_ptrace_step_wait.h"
3191#include "t_ptrace_kill_wait.h"
3192#include "t_ptrace_bytetransfer_wait.h"
3193#include "t_ptrace_clone_wait.h"
3194#include "t_ptrace_fork_wait.h"
3195#include "t_ptrace_signal_wait.h"
3196
3197/// ----------------------------------------------------------------------------
3198
3199#include "t_ptrace_amd64_wait.h"
3200#include "t_ptrace_i386_wait.h"
3201#include "t_ptrace_x86_wait.h"
3202
3203/// ----------------------------------------------------------------------------
3204
3205#else
3206ATF_TC(dummy);
3207ATF_TC_HEAD(dummy, tc)
3208{
3209	atf_tc_set_md_var(tc, "descr", "A dummy test");
3210}
3211
3212ATF_TC_BODY(dummy, tc)
3213{
3214
3215	// Dummy, skipped
3216	// The ATF framework requires at least a single defined test.
3217}
3218#endif
3219
3220ATF_TP_ADD_TCS(tp)
3221{
3222	setvbuf(stdout, NULL, _IONBF, 0);
3223	setvbuf(stderr, NULL, _IONBF, 0);
3224
3225#ifdef ENABLE_TESTS
3226	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
3227
3228	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
3229	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
3230	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
3231
3232	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
3233	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
3234	ATF_TP_ADD_TC_HAVE_PID(tp,
3235		unrelated_tracer_sees_terminaton_before_the_parent);
3236	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
3237
3238	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
3239	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
3240
3241	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
3242	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
3243
3244	ATF_TP_ADD_TC_HAVE_PID(tp,
3245		tracee_sees_its_original_parent_getppid);
3246	ATF_TP_ADD_TC_HAVE_PID(tp,
3247		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
3248	ATF_TP_ADD_TC_HAVE_PID(tp,
3249		tracee_sees_its_original_parent_procfs_status);
3250
3251	ATF_TP_ADD_TC(tp, eventmask_preserved_empty);
3252	ATF_TP_ADD_TC(tp, eventmask_preserved_fork);
3253	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork);
3254	ATF_TP_ADD_TC(tp, eventmask_preserved_vfork_done);
3255	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_create);
3256	ATF_TP_ADD_TC(tp, eventmask_preserved_lwp_exit);
3257	ATF_TP_ADD_TC(tp, eventmask_preserved_posix_spawn);
3258
3259	ATF_TP_ADD_TC(tp, traceme_lwpinfo0);
3260	ATF_TP_ADD_TC(tp, traceme_lwpinfo1);
3261	ATF_TP_ADD_TC(tp, traceme_lwpinfo2);
3262	ATF_TP_ADD_TC(tp, traceme_lwpinfo3);
3263
3264	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus);
3265	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus);
3266	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus);
3267	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus);
3268
3269	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_sigmask);
3270	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_sigmask);
3271	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_sigmask);
3272	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_sigmask);
3273
3274	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_name);
3275	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_name);
3276	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_name);
3277	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_name);
3278
3279	ATF_TP_ADD_TC(tp, traceme_lwpinfo0_lwpstatus_pl_private);
3280	ATF_TP_ADD_TC(tp, traceme_lwpinfo1_lwpstatus_pl_private);
3281	ATF_TP_ADD_TC(tp, traceme_lwpinfo2_lwpstatus_pl_private);
3282	ATF_TP_ADD_TC(tp, traceme_lwpinfo3_lwpstatus_pl_private);
3283
3284	ATF_TP_ADD_TC(tp, traceme_lwpnext0);
3285	ATF_TP_ADD_TC(tp, traceme_lwpnext1);
3286	ATF_TP_ADD_TC(tp, traceme_lwpnext2);
3287	ATF_TP_ADD_TC(tp, traceme_lwpnext3);
3288
3289	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_sigmask);
3290	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_sigmask);
3291	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_sigmask);
3292	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_sigmask);
3293
3294	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_name);
3295	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_name);
3296	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_name);
3297	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_name);
3298
3299	ATF_TP_ADD_TC(tp, traceme_lwpnext0_pl_private);
3300	ATF_TP_ADD_TC(tp, traceme_lwpnext1_pl_private);
3301	ATF_TP_ADD_TC(tp, traceme_lwpnext2_pl_private);
3302	ATF_TP_ADD_TC(tp, traceme_lwpnext3_pl_private);
3303
3304	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo0);
3305	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo1);
3306	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo2);
3307	ATF_TP_ADD_TC_HAVE_PID(tp, attach_lwpinfo3);
3308
3309	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
3310	ATF_TP_ADD_TC(tp, siginfo_set_faked);
3311
3312	ATF_TP_ADD_TC(tp, traceme_exec);
3313	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
3314	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
3315
3316	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
3317	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
3318	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
3319	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
3320
3321	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap);
3322	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap);
3323	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap);
3324
3325	ATF_TP_ADD_TC(tp, threads_and_exec);
3326
3327	ATF_TP_ADD_TC(tp, suspend_no_deadlock);
3328
3329	ATF_TP_ADD_TC(tp, resume);
3330
3331	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
3332	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
3333	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
3334
3335	ATF_TP_ADD_TC(tp, core_dump_procinfo);
3336
3337#if defined(TWAIT_HAVE_STATUS)
3338	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
3339	ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign);
3340	ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler);
3341#if defined(__i386__) || defined(__x86_64__)
3342	ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints);
3343	ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints);
3344	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp);
3345	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig);
3346	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign);
3347	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler);
3348	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig);
3349	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign);
3350	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler);
3351	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig);
3352	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign);
3353	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler);
3354#endif
3355#endif
3356
3357	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
3358	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
3359	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
3360	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
3361	ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
3362	ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE();
3363	ATF_TP_ADD_TCS_PTRACE_WAIT_FORK();
3364	ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL();
3365
3366	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
3367	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
3368	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
3369
3370#else
3371	ATF_TP_ADD_TC(tp, dummy);
3372#endif
3373
3374	return atf_no_error();
3375}
3376