t_ptrace_wait.c revision 1.185
1/*	$NetBSD: t_ptrace_wait.c,v 1.185 2020/05/05 00:15:45 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.185 2020/05/05 00:15:45 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
931ptrace_siginfo(bool faked, void (*sah)(int a, siginfo_t *b, void *c), int *signal_caught)
932{
933	const int exitval = 5;
934	const int sigval = SIGINT;
935	const int sigfaked = SIGTRAP;
936	const int sicodefaked = TRAP_BRKPT;
937	pid_t child, wpid;
938	struct sigaction sa;
939#if defined(TWAIT_HAVE_STATUS)
940	int status;
941#endif
942	struct ptrace_siginfo info;
943	memset(&info, 0, sizeof(info));
944
945	DPRINTF("Before forking process PID=%d\n", getpid());
946	SYSCALL_REQUIRE((child = fork()) != -1);
947	if (child == 0) {
948		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
949		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
950
951		sa.sa_sigaction = sah;
952		sa.sa_flags = SA_SIGINFO;
953		sigemptyset(&sa.sa_mask);
954
955		FORKEE_ASSERT(sigaction(faked ? sigfaked : sigval, &sa, NULL)
956		    != -1);
957
958		DPRINTF("Before raising %s from child\n", strsignal(sigval));
959		FORKEE_ASSERT(raise(sigval) == 0);
960
961		FORKEE_ASSERT_EQ(*signal_caught, 1);
962
963		DPRINTF("Before exiting of the child process\n");
964		_exit(exitval);
965	}
966	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
967
968	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
969	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
970
971	validate_status_stopped(status, sigval);
972
973	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
974	SYSCALL_REQUIRE(
975	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
976
977	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
978	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
979	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
980	    info.psi_siginfo.si_errno);
981
982	if (faked) {
983		DPRINTF("Before setting new faked signal to signo=%d "
984		    "si_code=%d\n", sigfaked, sicodefaked);
985		info.psi_siginfo.si_signo = sigfaked;
986		info.psi_siginfo.si_code = sicodefaked;
987	}
988
989	DPRINTF("Before calling ptrace(2) with PT_SET_SIGINFO for child\n");
990	SYSCALL_REQUIRE(
991	    ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1);
992
993	if (faked) {
994		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
995		    "child\n");
996		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
997		    sizeof(info)) != -1);
998
999		DPRINTF("Before checking siginfo_t\n");
1000		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked);
1001		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked);
1002	}
1003
1004	DPRINTF("Before resuming the child process where it left off and "
1005	    "without signal to be sent\n");
1006	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
1007	    faked ? sigfaked : sigval) != -1);
1008
1009	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1010	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1011
1012	validate_status_exited(status, exitval);
1013
1014	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1015	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1016}
1017
1018#define PTRACE_SIGINFO(test, faked)					\
1019ATF_TC(test);								\
1020ATF_TC_HEAD(test, tc)							\
1021{									\
1022	atf_tc_set_md_var(tc, "descr",					\
1023	    "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls"	\
1024	    "with%s setting signal to new value", faked ? "" : "out");	\
1025}									\
1026									\
1027static int test##_caught = 0;						\
1028									\
1029static void								\
1030test##_sighandler(int sig, siginfo_t *info, void *ctx)			\
1031{									\
1032	if (faked) {							\
1033		FORKEE_ASSERT_EQ(sig, SIGTRAP);				\
1034		FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP);		\
1035		FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT);		\
1036	} else {							\
1037		FORKEE_ASSERT_EQ(sig, SIGINT);				\
1038		FORKEE_ASSERT_EQ(info->si_signo, SIGINT);		\
1039		FORKEE_ASSERT_EQ(info->si_code, SI_LWP);		\
1040	}								\
1041									\
1042	++ test##_caught;						\
1043}									\
1044									\
1045ATF_TC_BODY(test, tc)							\
1046{									\
1047									\
1048	ptrace_siginfo(faked, test##_sighandler, & test##_caught); 	\
1049}
1050
1051PTRACE_SIGINFO(siginfo_set_unmodified, false)
1052PTRACE_SIGINFO(siginfo_set_faked, true)
1053
1054/// ----------------------------------------------------------------------------
1055
1056static void
1057traceme_exec(bool masked, bool ignored)
1058{
1059	const int sigval = SIGTRAP;
1060	pid_t child, wpid;
1061#if defined(TWAIT_HAVE_STATUS)
1062	int status;
1063#endif
1064	struct sigaction sa;
1065	struct ptrace_siginfo info;
1066	sigset_t intmask;
1067	struct kinfo_proc2 kp;
1068	size_t len = sizeof(kp);
1069
1070	int name[6];
1071	const size_t namelen = __arraycount(name);
1072	ki_sigset_t kp_sigmask;
1073	ki_sigset_t kp_sigignore;
1074
1075	memset(&info, 0, sizeof(info));
1076
1077	DPRINTF("Before forking process PID=%d\n", getpid());
1078	SYSCALL_REQUIRE((child = fork()) != -1);
1079	if (child == 0) {
1080		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1081		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1082
1083		if (masked) {
1084			sigemptyset(&intmask);
1085			sigaddset(&intmask, sigval);
1086			sigprocmask(SIG_BLOCK, &intmask, NULL);
1087		}
1088
1089		if (ignored) {
1090			memset(&sa, 0, sizeof(sa));
1091			sa.sa_handler = SIG_IGN;
1092			sigemptyset(&sa.sa_mask);
1093			FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1);
1094		}
1095
1096		DPRINTF("Before calling execve(2) from child\n");
1097		execlp("/bin/echo", "/bin/echo", NULL);
1098
1099		FORKEE_ASSERT(0 && "Not reached");
1100	}
1101	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1102
1103	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1104	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1105
1106	validate_status_stopped(status, sigval);
1107
1108	name[0] = CTL_KERN,
1109	name[1] = KERN_PROC2,
1110	name[2] = KERN_PROC_PID;
1111	name[3] = getpid();
1112	name[4] = sizeof(kp);
1113	name[5] = 1;
1114
1115	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1116
1117	if (masked)
1118		kp_sigmask = kp.p_sigmask;
1119
1120	if (ignored)
1121		kp_sigignore = kp.p_sigignore;
1122
1123	name[3] = getpid();
1124
1125	ATF_REQUIRE_EQ(sysctl(name, namelen, &kp, &len, NULL, 0), 0);
1126
1127	if (masked) {
1128		DPRINTF("kp_sigmask="
1129		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1130		    kp_sigmask.__bits[0], kp_sigmask.__bits[1],
1131		    kp_sigmask.__bits[2], kp_sigmask.__bits[3]);
1132
1133		DPRINTF("kp.p_sigmask="
1134		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1135		    kp.p_sigmask.__bits[0], kp.p_sigmask.__bits[1],
1136		    kp.p_sigmask.__bits[2], kp.p_sigmask.__bits[3]);
1137
1138		ATF_REQUIRE(!memcmp(&kp_sigmask, &kp.p_sigmask,
1139		    sizeof(kp_sigmask)));
1140	}
1141
1142	if (ignored) {
1143		DPRINTF("kp_sigignore="
1144		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1145		    kp_sigignore.__bits[0], kp_sigignore.__bits[1],
1146		    kp_sigignore.__bits[2], kp_sigignore.__bits[3]);
1147
1148		DPRINTF("kp.p_sigignore="
1149		    "%#02" PRIx32 "%02" PRIx32 "%02" PRIx32 "%02" PRIx32"\n",
1150		    kp.p_sigignore.__bits[0], kp.p_sigignore.__bits[1],
1151		    kp.p_sigignore.__bits[2], kp.p_sigignore.__bits[3]);
1152
1153		ATF_REQUIRE(!memcmp(&kp_sigignore, &kp.p_sigignore,
1154		    sizeof(kp_sigignore)));
1155	}
1156
1157	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1158	SYSCALL_REQUIRE(
1159	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1160
1161	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1162	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1163	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1164	    info.psi_siginfo.si_errno);
1165
1166	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1167	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1168
1169	DPRINTF("Before resuming the child process where it left off and "
1170	    "without signal to be sent\n");
1171	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1172
1173	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1174	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1175
1176	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1177	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1178}
1179
1180#define TRACEME_EXEC(test, masked, ignored)				\
1181ATF_TC(test);								\
1182ATF_TC_HEAD(test, tc)							\
1183{									\
1184       atf_tc_set_md_var(tc, "descr",					\
1185           "Detect SIGTRAP TRAP_EXEC from "				\
1186           "child%s%s", masked ? " with masked signal" : "",		\
1187           masked ? " with ignored signal" : "");			\
1188}									\
1189									\
1190ATF_TC_BODY(test, tc)							\
1191{									\
1192									\
1193       traceme_exec(masked, ignored);					\
1194}
1195
1196TRACEME_EXEC(traceme_exec, false, false)
1197TRACEME_EXEC(traceme_signalmasked_exec, true, false)
1198TRACEME_EXEC(traceme_signalignored_exec, false, true)
1199
1200/// ----------------------------------------------------------------------------
1201
1202#define TRACE_THREADS_NUM 100
1203
1204static volatile int done;
1205pthread_mutex_t trace_threads_mtx = PTHREAD_MUTEX_INITIALIZER;
1206
1207static void *
1208trace_threads_cb(void *arg __unused)
1209{
1210
1211	pthread_mutex_lock(&trace_threads_mtx);
1212	done++;
1213	pthread_mutex_unlock(&trace_threads_mtx);
1214
1215	while (done < TRACE_THREADS_NUM)
1216		sched_yield();
1217
1218	return NULL;
1219}
1220
1221static void
1222trace_threads(bool trace_create, bool trace_exit, bool masked)
1223{
1224	const int sigval = SIGSTOP;
1225	pid_t child, wpid;
1226#if defined(TWAIT_HAVE_STATUS)
1227	int status;
1228#endif
1229	ptrace_state_t state;
1230	const int slen = sizeof(state);
1231	ptrace_event_t event;
1232	const int elen = sizeof(event);
1233	struct ptrace_siginfo info;
1234
1235	sigset_t intmask;
1236
1237	pthread_t t[TRACE_THREADS_NUM];
1238	int rv;
1239	size_t n;
1240	lwpid_t lid;
1241
1242	/* Track created and exited threads */
1243	struct lwp_event_count traced_lwps[__arraycount(t)] = {{0, 0}};
1244
1245	DPRINTF("Before forking process PID=%d\n", getpid());
1246	SYSCALL_REQUIRE((child = fork()) != -1);
1247	if (child == 0) {
1248		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1249		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1250
1251		if (masked) {
1252			sigemptyset(&intmask);
1253			sigaddset(&intmask, SIGTRAP);
1254			sigprocmask(SIG_BLOCK, &intmask, NULL);
1255		}
1256
1257		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1258		FORKEE_ASSERT(raise(sigval) == 0);
1259
1260		for (n = 0; n < __arraycount(t); n++) {
1261			rv = pthread_create(&t[n], NULL, trace_threads_cb,
1262			    NULL);
1263			FORKEE_ASSERT(rv == 0);
1264		}
1265
1266		for (n = 0; n < __arraycount(t); n++) {
1267			rv = pthread_join(t[n], NULL);
1268			FORKEE_ASSERT(rv == 0);
1269		}
1270
1271		/*
1272		 * There is race between _exit() and pthread_join() detaching
1273		 * a thread. For simplicity kill the process after detecting
1274		 * LWP events.
1275		 */
1276		while (true)
1277			continue;
1278
1279		FORKEE_ASSERT(0 && "Not reached");
1280	}
1281	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1282
1283	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1284	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1285
1286	validate_status_stopped(status, sigval);
1287
1288	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1289	SYSCALL_REQUIRE(
1290	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1291
1292	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1293	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1294	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1295	    info.psi_siginfo.si_errno);
1296
1297	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1298	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1299
1300	DPRINTF("Set LWP event mask for the child %d\n", child);
1301	memset(&event, 0, sizeof(event));
1302	if (trace_create)
1303		event.pe_set_event |= PTRACE_LWP_CREATE;
1304	if (trace_exit)
1305		event.pe_set_event |= PTRACE_LWP_EXIT;
1306	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1307
1308	DPRINTF("Before resuming the child process where it left off and "
1309	    "without signal to be sent\n");
1310	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1311
1312	for (n = 0; n < (trace_create ? __arraycount(t) : 0); n++) {
1313		DPRINTF("Before calling %s() for the child - expected stopped "
1314		    "SIGTRAP\n", TWAIT_FNAME);
1315		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1316		    child);
1317
1318		validate_status_stopped(status, SIGTRAP);
1319
1320		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1321		    "child\n");
1322		SYSCALL_REQUIRE(
1323		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1324
1325		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1326		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1327		    "si_errno=%#x\n",
1328		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1329		    info.psi_siginfo.si_errno);
1330
1331		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1332		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
1333
1334		SYSCALL_REQUIRE(
1335		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1336
1337		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
1338		    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
1339
1340		lid = state.pe_lwp;
1341		DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
1342
1343		*FIND_EVENT_COUNT(traced_lwps, lid) += 1;
1344
1345		DPRINTF("Before resuming the child process where it left off "
1346		    "and without signal to be sent\n");
1347		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1348	}
1349
1350	for (n = 0; n < (trace_exit ? __arraycount(t) : 0); n++) {
1351		DPRINTF("Before calling %s() for the child - expected stopped "
1352		    "SIGTRAP\n", TWAIT_FNAME);
1353		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1354		    child);
1355
1356		validate_status_stopped(status, SIGTRAP);
1357
1358		DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1359		    "child\n");
1360		SYSCALL_REQUIRE(
1361		    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1362
1363		DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1364		DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1365		    "si_errno=%#x\n",
1366		    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1367		    info.psi_siginfo.si_errno);
1368
1369		ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1370		ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
1371
1372		SYSCALL_REQUIRE(
1373		    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1374
1375		ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
1376		    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
1377
1378		lid = state.pe_lwp;
1379		DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
1380
1381		if (trace_create) {
1382			int *count = FIND_EVENT_COUNT(traced_lwps, lid);
1383			ATF_REQUIRE_EQ(*count, 1);
1384			*count = 0;
1385		}
1386
1387		DPRINTF("Before resuming the child process where it left off "
1388		    "and without signal to be sent\n");
1389		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1390	}
1391
1392	kill(child, SIGKILL);
1393
1394	DPRINTF("Before calling %s() for the child - expected exited\n",
1395	    TWAIT_FNAME);
1396	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1397
1398	validate_status_signaled(status, SIGKILL, 0);
1399
1400	DPRINTF("Before calling %s() for the child - expected no process\n",
1401	    TWAIT_FNAME);
1402	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1403}
1404
1405#define TRACE_THREADS(test, trace_create, trace_exit, mask)		\
1406ATF_TC(test);								\
1407ATF_TC_HEAD(test, tc)							\
1408{									\
1409        atf_tc_set_md_var(tc, "descr",					\
1410            "Verify spawning threads with%s tracing LWP create and"	\
1411	    "with%s tracing LWP exit", trace_create ? "" : "out",	\
1412	    trace_exit ? "" : "out");					\
1413}									\
1414									\
1415ATF_TC_BODY(test, tc)							\
1416{									\
1417									\
1418        trace_threads(trace_create, trace_exit, mask);			\
1419}
1420
1421TRACE_THREADS(trace_thread_nolwpevents, false, false, false)
1422TRACE_THREADS(trace_thread_lwpexit, false, true, false)
1423TRACE_THREADS(trace_thread_lwpcreate, true, false, false)
1424TRACE_THREADS(trace_thread_lwpcreate_and_exit, true, true, false)
1425
1426TRACE_THREADS(trace_thread_lwpexit_masked_sigtrap, false, true, true)
1427TRACE_THREADS(trace_thread_lwpcreate_masked_sigtrap, true, false, true)
1428TRACE_THREADS(trace_thread_lwpcreate_and_exit_masked_sigtrap, true, true, true)
1429
1430/// ----------------------------------------------------------------------------
1431
1432static void *
1433thread_and_exec_thread_cb(void *arg __unused)
1434{
1435
1436	execlp("/bin/echo", "/bin/echo", NULL);
1437
1438	abort();
1439}
1440
1441static void
1442threads_and_exec(void)
1443{
1444	const int sigval = SIGSTOP;
1445	pid_t child, wpid;
1446#if defined(TWAIT_HAVE_STATUS)
1447	int status;
1448#endif
1449	ptrace_state_t state;
1450	const int slen = sizeof(state);
1451	ptrace_event_t event;
1452	const int elen = sizeof(event);
1453	struct ptrace_siginfo info;
1454
1455	pthread_t t;
1456	lwpid_t lid;
1457
1458	DPRINTF("Before forking process PID=%d\n", getpid());
1459	SYSCALL_REQUIRE((child = fork()) != -1);
1460	if (child == 0) {
1461		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1462		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1463
1464		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1465		FORKEE_ASSERT(raise(sigval) == 0);
1466
1467		FORKEE_ASSERT(pthread_create(&t, NULL,
1468		    thread_and_exec_thread_cb, NULL) == 0);
1469
1470		for (;;)
1471			continue;
1472
1473		FORKEE_ASSERT(0 && "Not reached");
1474	}
1475	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1476
1477	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1478	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1479
1480	validate_status_stopped(status, sigval);
1481
1482	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1483	SYSCALL_REQUIRE(
1484	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1485
1486	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1487	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1488	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1489	    info.psi_siginfo.si_errno);
1490
1491	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1492	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1493
1494	DPRINTF("Set LWP event mask for the child %d\n", child);
1495	memset(&event, 0, sizeof(event));
1496	event.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
1497	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1498
1499	DPRINTF("Before resuming the child process where it left off and "
1500	    "without signal to be sent\n");
1501	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1502
1503	DPRINTF("Before calling %s() for the child - expected stopped "
1504	    "SIGTRAP\n", TWAIT_FNAME);
1505	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1506	    child);
1507
1508	validate_status_stopped(status, SIGTRAP);
1509
1510	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1511	    "child\n");
1512	SYSCALL_REQUIRE(
1513	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1514
1515	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1516	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1517	    "si_errno=%#x\n",
1518	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1519	    info.psi_siginfo.si_errno);
1520
1521	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1522	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
1523
1524	SYSCALL_REQUIRE(
1525	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1526
1527	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_CREATE,
1528	    "%d != %d", state.pe_report_event, PTRACE_LWP_CREATE);
1529
1530	lid = state.pe_lwp;
1531	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
1532
1533	DPRINTF("Before resuming the child process where it left off "
1534	    "and without signal to be sent\n");
1535	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1536
1537	DPRINTF("Before calling %s() for the child - expected stopped "
1538	    "SIGTRAP\n", TWAIT_FNAME);
1539	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1540	    child);
1541
1542	validate_status_stopped(status, SIGTRAP);
1543
1544	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1545	    "child\n");
1546	SYSCALL_REQUIRE(
1547	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1548
1549	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1550	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1551	    "si_errno=%#x\n",
1552	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1553	    info.psi_siginfo.si_errno);
1554
1555	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1556	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_LWP);
1557
1558	SYSCALL_REQUIRE(
1559	    ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1560
1561	ATF_REQUIRE_EQ_MSG(state.pe_report_event, PTRACE_LWP_EXIT,
1562	    "%d != %d", state.pe_report_event, PTRACE_LWP_EXIT);
1563
1564	lid = state.pe_lwp;
1565	DPRINTF("Reported PTRACE_LWP_EXIT event with lid %d\n", lid);
1566
1567	DPRINTF("Before resuming the child process where it left off "
1568	    "and without signal to be sent\n");
1569	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1570
1571	DPRINTF("Before calling %s() for the child - expected stopped "
1572	    "SIGTRAP\n", TWAIT_FNAME);
1573	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
1574	    child);
1575
1576	validate_status_stopped(status, SIGTRAP);
1577
1578	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1579	    "child\n");
1580	SYSCALL_REQUIRE(
1581	    ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1582
1583	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1584	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1585	    "si_errno=%#x\n",
1586	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1587	    info.psi_siginfo.si_errno);
1588
1589	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1590	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1591
1592	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
1593
1594	DPRINTF("Before calling %s() for the child - expected exited\n",
1595	    TWAIT_FNAME);
1596	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1597
1598	validate_status_signaled(status, SIGKILL, 0);
1599
1600	DPRINTF("Before calling %s() for the child - expected no process\n",
1601	    TWAIT_FNAME);
1602	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1603}
1604
1605ATF_TC(threads_and_exec);
1606ATF_TC_HEAD(threads_and_exec, tc)
1607{
1608        atf_tc_set_md_var(tc, "descr",
1609            "Verify that multithreaded application on exec() will report "
1610	    "LWP_EXIT events");
1611}
1612
1613ATF_TC_BODY(threads_and_exec, tc)
1614{
1615
1616        threads_and_exec();
1617}
1618
1619/// ----------------------------------------------------------------------------
1620
1621ATF_TC(suspend_no_deadlock);
1622ATF_TC_HEAD(suspend_no_deadlock, tc)
1623{
1624	atf_tc_set_md_var(tc, "descr",
1625	    "Verify that the while the only thread within a process is "
1626	    "suspended, the whole process cannot be unstopped");
1627}
1628
1629ATF_TC_BODY(suspend_no_deadlock, tc)
1630{
1631	const int exitval = 5;
1632	const int sigval = SIGSTOP;
1633	pid_t child, wpid;
1634#if defined(TWAIT_HAVE_STATUS)
1635	int status;
1636#endif
1637	struct ptrace_siginfo psi;
1638
1639	DPRINTF("Before forking process PID=%d\n", getpid());
1640	SYSCALL_REQUIRE((child = fork()) != -1);
1641	if (child == 0) {
1642		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1643		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1644
1645		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1646		FORKEE_ASSERT(raise(sigval) == 0);
1647
1648		DPRINTF("Before exiting of the child process\n");
1649		_exit(exitval);
1650	}
1651	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1652
1653	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1654	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1655
1656	validate_status_stopped(status, sigval);
1657
1658	DPRINTF("Before reading siginfo and lwpid_t\n");
1659	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
1660
1661	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
1662	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
1663
1664	DPRINTF("Before resuming the child process where it left off and "
1665	    "without signal to be sent\n");
1666	ATF_REQUIRE_ERRNO(EDEADLK,
1667	    ptrace(PT_CONTINUE, child, (void *)1, 0) == -1);
1668
1669	DPRINTF("Before resuming LWP %d\n", psi.psi_lwpid);
1670	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, psi.psi_lwpid) != -1);
1671
1672	DPRINTF("Before resuming the child process where it left off and "
1673	    "without signal to be sent\n");
1674	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1675
1676	DPRINTF("Before calling %s() for the child - expected exited\n",
1677	    TWAIT_FNAME);
1678	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1679
1680	validate_status_exited(status, exitval);
1681
1682	DPRINTF("Before calling %s() for the child - expected no process\n",
1683	    TWAIT_FNAME);
1684	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1685}
1686
1687/// ----------------------------------------------------------------------------
1688
1689static pthread_barrier_t barrier1_resume;
1690static pthread_barrier_t barrier2_resume;
1691
1692static void *
1693resume_thread(void *arg)
1694{
1695
1696	raise(SIGUSR1);
1697
1698	pthread_barrier_wait(&barrier1_resume);
1699
1700	/* Debugger will suspend the process here */
1701
1702	pthread_barrier_wait(&barrier2_resume);
1703
1704	raise(SIGUSR2);
1705
1706	return infinite_thread(arg);
1707}
1708
1709ATF_TC(resume);
1710ATF_TC_HEAD(resume, tc)
1711{
1712	atf_tc_set_md_var(tc, "descr",
1713	    "Verify that a thread can be suspended by a debugger and later "
1714	    "resumed by the debugger");
1715}
1716
1717ATF_TC_BODY(resume, tc)
1718{
1719	const int sigval = SIGSTOP;
1720	pid_t child, wpid;
1721#if defined(TWAIT_HAVE_STATUS)
1722	int status;
1723#endif
1724	lwpid_t lid;
1725	struct ptrace_siginfo psi;
1726	pthread_t t;
1727
1728	DPRINTF("Before forking process PID=%d\n", getpid());
1729	SYSCALL_REQUIRE((child = fork()) != -1);
1730	if (child == 0) {
1731		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1732		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1733
1734		pthread_barrier_init(&barrier1_resume, NULL, 2);
1735		pthread_barrier_init(&barrier2_resume, NULL, 2);
1736
1737		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1738		FORKEE_ASSERT(raise(sigval) == 0);
1739
1740		DPRINTF("Before creating new thread in child\n");
1741		FORKEE_ASSERT(pthread_create(&t, NULL, resume_thread, NULL) == 0);
1742
1743		pthread_barrier_wait(&barrier1_resume);
1744
1745		pthread_barrier_wait(&barrier2_resume);
1746
1747		infinite_thread(NULL);
1748	}
1749	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1750
1751	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1752	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1753
1754	validate_status_stopped(status, sigval);
1755
1756	DPRINTF("Before resuming the child process where it left off and "
1757	    "without signal to be sent\n");
1758	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1759
1760	DPRINTF("Before calling %s() for the child - expected stopped "
1761	    "SIGUSR1\n", TWAIT_FNAME);
1762	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1763
1764	validate_status_stopped(status, SIGUSR1);
1765
1766	DPRINTF("Before reading siginfo and lwpid_t\n");
1767	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &psi, sizeof(psi)) != -1);
1768
1769	DPRINTF("Before suspending LWP %d\n", psi.psi_lwpid);
1770	SYSCALL_REQUIRE(ptrace(PT_SUSPEND, child, NULL, psi.psi_lwpid) != -1);
1771
1772	lid = psi.psi_lwpid;
1773
1774	DPRINTF("Before resuming the child process where it left off and "
1775	    "without signal to be sent\n");
1776	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1777
1778	DPRINTF("Before suspending the parent for 1 second, we expect no signals\n");
1779	SYSCALL_REQUIRE(sleep(1) == 0);
1780
1781#if defined(TWAIT_HAVE_OPTIONS)
1782	DPRINTF("Before calling %s() for the child - expected no status\n",
1783	    TWAIT_FNAME);
1784	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, WNOHANG), 0);
1785#endif
1786
1787	DPRINTF("Before resuming the child process where it left off and "
1788	    "without signal to be sent\n");
1789	SYSCALL_REQUIRE(ptrace(PT_STOP, child, NULL, 0) != -1);
1790
1791	DPRINTF("Before calling %s() for the child - expected stopped "
1792	    "SIGSTOP\n", TWAIT_FNAME);
1793	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1794
1795	validate_status_stopped(status, SIGSTOP);
1796
1797	DPRINTF("Before resuming LWP %d\n", lid);
1798	SYSCALL_REQUIRE(ptrace(PT_RESUME, child, NULL, lid) != -1);
1799
1800	DPRINTF("Before resuming the child process where it left off and "
1801	    "without signal to be sent\n");
1802	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1803
1804	DPRINTF("Before calling %s() for the child - expected stopped "
1805	    "SIGUSR2\n", TWAIT_FNAME);
1806	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1807
1808	validate_status_stopped(status, SIGUSR2);
1809
1810	DPRINTF("Before resuming the child process where it left off and "
1811	    "without signal to be sent\n");
1812	SYSCALL_REQUIRE(ptrace(PT_KILL, child, (void *)1, 0) != -1);
1813
1814	DPRINTF("Before calling %s() for the child - expected exited\n",
1815	    TWAIT_FNAME);
1816	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1817
1818	validate_status_signaled(status, SIGKILL, 0);
1819
1820	DPRINTF("Before calling %s() for the child - expected no process\n",
1821	    TWAIT_FNAME);
1822	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1823}
1824
1825/// ----------------------------------------------------------------------------
1826
1827static void
1828user_va0_disable(int operation)
1829{
1830	pid_t child, wpid;
1831#if defined(TWAIT_HAVE_STATUS)
1832	int status;
1833#endif
1834	const int sigval = SIGSTOP;
1835	int rv;
1836
1837	struct ptrace_siginfo info;
1838
1839	if (get_user_va0_disable() == 0)
1840		atf_tc_skip("vm.user_va0_disable is set to 0");
1841
1842	memset(&info, 0, sizeof(info));
1843
1844	DPRINTF("Before forking process PID=%d\n", getpid());
1845	SYSCALL_REQUIRE((child = fork()) != -1);
1846	if (child == 0) {
1847		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1848		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1849
1850		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1851		FORKEE_ASSERT(raise(sigval) == 0);
1852
1853		/* NOTREACHED */
1854		FORKEE_ASSERTX(0 && "This shall not be reached");
1855		__unreachable();
1856	}
1857	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1858
1859	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1860	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1861
1862	validate_status_stopped(status, sigval);
1863
1864	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for "
1865		"child\n");
1866	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
1867		sizeof(info)) != -1);
1868
1869	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1870	DPRINTF("Signal properties: si_signo=%#x si_code=%#x "
1871		"si_errno=%#x\n",
1872		info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1873		info.psi_siginfo.si_errno);
1874
1875	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1876	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP);
1877
1878	DPRINTF("Before resuming the child process in PC=0x0 "
1879	    "and without signal to be sent\n");
1880	errno = 0;
1881	rv = ptrace(operation, child, (void *)0, 0);
1882	ATF_REQUIRE_EQ(errno, EINVAL);
1883	ATF_REQUIRE_EQ(rv, -1);
1884
1885	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
1886
1887	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1888	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1889	validate_status_signaled(status, SIGKILL, 0);
1890
1891	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1892	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1893}
1894
1895#define USER_VA0_DISABLE(test, operation)				\
1896ATF_TC(test);								\
1897ATF_TC_HEAD(test, tc)							\
1898{									\
1899	atf_tc_set_md_var(tc, "descr",					\
1900	    "Verify behavior of " #operation " with PC set to 0x0");	\
1901}									\
1902									\
1903ATF_TC_BODY(test, tc)							\
1904{									\
1905									\
1906	user_va0_disable(operation);					\
1907}
1908
1909USER_VA0_DISABLE(user_va0_disable_pt_continue, PT_CONTINUE)
1910USER_VA0_DISABLE(user_va0_disable_pt_syscall, PT_SYSCALL)
1911USER_VA0_DISABLE(user_va0_disable_pt_detach, PT_DETACH)
1912
1913/// ----------------------------------------------------------------------------
1914
1915/*
1916 * Parse the core file and find the requested note.  If the reading or parsing
1917 * fails, the test is failed.  If the note is found, it is read onto buf, up to
1918 * buf_len.  The actual length of the note is returned (which can be greater
1919 * than buf_len, indicating that it has been truncated).  If the note is not
1920 * found, -1 is returned.
1921 *
1922 * If the note_name ends in '*', then we find the first note that matches
1923 * the note_name prefix up to the '*' character, e.g.:
1924 *
1925 *	NetBSD-CORE@*
1926 *
1927 * finds the first note whose name prefix matches "NetBSD-CORE@".
1928 */
1929static ssize_t core_find_note(const char *core_path,
1930    const char *note_name, uint64_t note_type, void *buf, size_t buf_len)
1931{
1932	int core_fd;
1933	Elf *core_elf;
1934	size_t core_numhdr, i;
1935	ssize_t ret = -1;
1936	size_t name_len = strlen(note_name);
1937	bool prefix_match = false;
1938
1939	if (note_name[name_len - 1] == '*') {
1940		prefix_match = true;
1941		name_len--;
1942	} else {
1943		/* note: we assume note name will be null-terminated */
1944		name_len++;
1945	}
1946
1947	SYSCALL_REQUIRE((core_fd = open(core_path, O_RDONLY)) != -1);
1948	SYSCALL_REQUIRE(elf_version(EV_CURRENT) != EV_NONE);
1949	SYSCALL_REQUIRE((core_elf = elf_begin(core_fd, ELF_C_READ, NULL)));
1950
1951	SYSCALL_REQUIRE(elf_getphnum(core_elf, &core_numhdr) != 0);
1952	for (i = 0; i < core_numhdr && ret == -1; i++) {
1953		GElf_Phdr core_hdr;
1954		size_t offset;
1955		SYSCALL_REQUIRE(gelf_getphdr(core_elf, i, &core_hdr));
1956		if (core_hdr.p_type != PT_NOTE)
1957		    continue;
1958
1959		for (offset = core_hdr.p_offset;
1960		    offset < core_hdr.p_offset + core_hdr.p_filesz;) {
1961			Elf64_Nhdr note_hdr;
1962			char name_buf[64];
1963
1964			switch (gelf_getclass(core_elf)) {
1965			case ELFCLASS64:
1966				SYSCALL_REQUIRE(pread(core_fd, &note_hdr,
1967				    sizeof(note_hdr), offset)
1968				    == sizeof(note_hdr));
1969				offset += sizeof(note_hdr);
1970				break;
1971			case ELFCLASS32:
1972				{
1973				Elf32_Nhdr tmp_hdr;
1974				SYSCALL_REQUIRE(pread(core_fd, &tmp_hdr,
1975				    sizeof(tmp_hdr), offset)
1976				    == sizeof(tmp_hdr));
1977				offset += sizeof(tmp_hdr);
1978				note_hdr.n_namesz = tmp_hdr.n_namesz;
1979				note_hdr.n_descsz = tmp_hdr.n_descsz;
1980				note_hdr.n_type = tmp_hdr.n_type;
1981				}
1982				break;
1983			}
1984
1985			/* indicates end of notes */
1986			if (note_hdr.n_namesz == 0 || note_hdr.n_descsz == 0)
1987				break;
1988			if (((prefix_match &&
1989			      note_hdr.n_namesz > name_len) ||
1990			     (!prefix_match &&
1991			      note_hdr.n_namesz == name_len)) &&
1992			    note_hdr.n_namesz <= sizeof(name_buf)) {
1993				SYSCALL_REQUIRE(pread(core_fd, name_buf,
1994				    note_hdr.n_namesz, offset)
1995				    == (ssize_t)(size_t)note_hdr.n_namesz);
1996
1997				if (!strncmp(note_name, name_buf, name_len) &&
1998				    note_hdr.n_type == note_type)
1999					ret = note_hdr.n_descsz;
2000			}
2001
2002			offset += note_hdr.n_namesz;
2003			/* fix to alignment */
2004			offset = roundup(offset, core_hdr.p_align);
2005
2006			/* if name & type matched above */
2007			if (ret != -1) {
2008				ssize_t read_len = MIN(buf_len,
2009				    note_hdr.n_descsz);
2010				SYSCALL_REQUIRE(pread(core_fd, buf,
2011				    read_len, offset) == read_len);
2012				break;
2013			}
2014
2015			offset += note_hdr.n_descsz;
2016			/* fix to alignment */
2017			offset = roundup(offset, core_hdr.p_align);
2018		}
2019	}
2020
2021	elf_end(core_elf);
2022	close(core_fd);
2023
2024	return ret;
2025}
2026
2027ATF_TC(core_dump_procinfo);
2028ATF_TC_HEAD(core_dump_procinfo, tc)
2029{
2030	atf_tc_set_md_var(tc, "descr",
2031		"Trigger a core dump and verify its contents.");
2032}
2033
2034ATF_TC_BODY(core_dump_procinfo, tc)
2035{
2036	const int exitval = 5;
2037	pid_t child, wpid;
2038#if defined(TWAIT_HAVE_STATUS)
2039	const int sigval = SIGTRAP;
2040	int status;
2041#endif
2042	char core_path[] = "/tmp/core.XXXXXX";
2043	int core_fd;
2044	struct netbsd_elfcore_procinfo procinfo;
2045
2046	DPRINTF("Before forking process PID=%d\n", getpid());
2047	SYSCALL_REQUIRE((child = fork()) != -1);
2048	if (child == 0) {
2049		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2050		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2051
2052		DPRINTF("Before triggering SIGTRAP\n");
2053		trigger_trap();
2054
2055		DPRINTF("Before exiting of the child process\n");
2056		_exit(exitval);
2057	}
2058	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2059
2060	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2061	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2062
2063	validate_status_stopped(status, sigval);
2064
2065	SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1);
2066	close(core_fd);
2067
2068	DPRINTF("Call DUMPCORE for the child process\n");
2069	SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, strlen(core_path))
2070	    != -1);
2071
2072	DPRINTF("Read core file\n");
2073	ATF_REQUIRE_EQ(core_find_note(core_path, "NetBSD-CORE",
2074	    ELF_NOTE_NETBSD_CORE_PROCINFO, &procinfo, sizeof(procinfo)),
2075	    sizeof(procinfo));
2076
2077	ATF_CHECK_EQ(procinfo.cpi_version, 1);
2078	ATF_CHECK_EQ(procinfo.cpi_cpisize, sizeof(procinfo));
2079	ATF_CHECK_EQ(procinfo.cpi_signo, SIGTRAP);
2080	ATF_CHECK_EQ(procinfo.cpi_pid, child);
2081	ATF_CHECK_EQ(procinfo.cpi_ppid, getpid());
2082	ATF_CHECK_EQ(procinfo.cpi_pgrp, getpgid(child));
2083	ATF_CHECK_EQ(procinfo.cpi_sid, getsid(child));
2084	ATF_CHECK_EQ(procinfo.cpi_ruid, getuid());
2085	ATF_CHECK_EQ(procinfo.cpi_euid, geteuid());
2086	ATF_CHECK_EQ(procinfo.cpi_rgid, getgid());
2087	ATF_CHECK_EQ(procinfo.cpi_egid, getegid());
2088	ATF_CHECK_EQ(procinfo.cpi_nlwps, 1);
2089	ATF_CHECK(procinfo.cpi_siglwp > 0);
2090
2091	unlink(core_path);
2092
2093	DPRINTF("Before resuming the child process where it left off and "
2094	    "without signal to be sent\n");
2095	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2096
2097	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2098	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2099
2100	validate_status_exited(status, exitval);
2101
2102	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2103	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
2104}
2105
2106/// ----------------------------------------------------------------------------
2107
2108#if defined(TWAIT_HAVE_STATUS)
2109
2110#define THREAD_CONCURRENT_BREAKPOINT_NUM 50
2111#define THREAD_CONCURRENT_SIGNALS_NUM 50
2112#define THREAD_CONCURRENT_WATCHPOINT_NUM 50
2113
2114/* List of signals to use for the test */
2115const int thread_concurrent_signals_list[] = {
2116	SIGIO,
2117	SIGXCPU,
2118	SIGXFSZ,
2119	SIGVTALRM,
2120	SIGPROF,
2121	SIGWINCH,
2122	SIGINFO,
2123	SIGUSR1,
2124	SIGUSR2
2125};
2126
2127enum thread_concurrent_signal_handling {
2128	/* the signal is discarded by debugger */
2129	TCSH_DISCARD,
2130	/* the handler is set to SIG_IGN */
2131	TCSH_SIG_IGN,
2132	/* an actual handler is used */
2133	TCSH_HANDLER
2134};
2135
2136static pthread_barrier_t thread_concurrent_barrier;
2137static pthread_key_t thread_concurrent_key;
2138static uint32_t thread_concurrent_watchpoint_var = 0;
2139
2140static void *
2141thread_concurrent_breakpoint_thread(void *arg)
2142{
2143	static volatile int watchme = 1;
2144	pthread_barrier_wait(&thread_concurrent_barrier);
2145	DPRINTF("Before entering breakpoint func from LWP %d\n", _lwp_self());
2146	check_happy(watchme);
2147	return NULL;
2148}
2149
2150static void
2151thread_concurrent_sig_handler(int sig)
2152{
2153	void *tls_val = pthread_getspecific(thread_concurrent_key);
2154	DPRINTF("Before increment, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
2155	FORKEE_ASSERT(pthread_setspecific(thread_concurrent_key,
2156	    (void*)((uintptr_t)tls_val + 1)) == 0);
2157}
2158
2159static void *
2160thread_concurrent_signals_thread(void *arg)
2161{
2162	int sigval = thread_concurrent_signals_list[
2163	    _lwp_self() % __arraycount(thread_concurrent_signals_list)];
2164	enum thread_concurrent_signal_handling *signal_handle = arg;
2165	void *tls_val;
2166
2167	pthread_barrier_wait(&thread_concurrent_barrier);
2168	DPRINTF("Before raising %s from LWP %d\n", strsignal(sigval),
2169		_lwp_self());
2170	pthread_kill(pthread_self(), sigval);
2171	if (*signal_handle == TCSH_HANDLER) {
2172	    tls_val = pthread_getspecific(thread_concurrent_key);
2173	    DPRINTF("After raising, LWP %d tls_val=%p\n", _lwp_self(), tls_val);
2174	    FORKEE_ASSERT(tls_val == (void*)1);
2175	}
2176	return NULL;
2177}
2178
2179static void *
2180thread_concurrent_watchpoint_thread(void *arg)
2181{
2182	pthread_barrier_wait(&thread_concurrent_barrier);
2183	DPRINTF("Before modifying var from LWP %d\n", _lwp_self());
2184	thread_concurrent_watchpoint_var = 1;
2185	return NULL;
2186}
2187
2188#if defined(__i386__) || defined(__x86_64__)
2189enum thread_concurrent_sigtrap_event {
2190	TCSE_UNKNOWN,
2191	TCSE_BREAKPOINT,
2192	TCSE_WATCHPOINT
2193};
2194
2195static void
2196thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid);
2197static enum thread_concurrent_sigtrap_event
2198thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info);
2199#endif
2200
2201static void
2202thread_concurrent_test(enum thread_concurrent_signal_handling signal_handle,
2203    int breakpoint_threads, int signal_threads, int watchpoint_threads)
2204{
2205	const int exitval = 5;
2206	const int sigval = SIGSTOP;
2207	pid_t child, wpid;
2208	int status;
2209	struct lwp_event_count signal_counts[THREAD_CONCURRENT_SIGNALS_NUM]
2210	    = {{0, 0}};
2211	struct lwp_event_count bp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
2212	    = {{0, 0}};
2213	struct lwp_event_count wp_counts[THREAD_CONCURRENT_BREAKPOINT_NUM]
2214	    = {{0, 0}};
2215	ptrace_event_t event;
2216	int i;
2217
2218#if defined(HAVE_DBREGS)
2219	if (!can_we_set_dbregs()) {
2220		atf_tc_skip("Either run this test as root or set sysctl(3) "
2221		            "security.models.extensions.user_set_dbregs to 1");
2222        }
2223#endif
2224
2225	atf_tc_skip("PR kern/54960");
2226
2227	/* Protect against out-of-bounds array access. */
2228	ATF_REQUIRE(breakpoint_threads <= THREAD_CONCURRENT_BREAKPOINT_NUM);
2229	ATF_REQUIRE(signal_threads <= THREAD_CONCURRENT_SIGNALS_NUM);
2230	ATF_REQUIRE(watchpoint_threads <= THREAD_CONCURRENT_WATCHPOINT_NUM);
2231
2232	DPRINTF("Before forking process PID=%d\n", getpid());
2233	SYSCALL_REQUIRE((child = fork()) != -1);
2234	if (child == 0) {
2235		pthread_t bp_threads[THREAD_CONCURRENT_BREAKPOINT_NUM];
2236		pthread_t sig_threads[THREAD_CONCURRENT_SIGNALS_NUM];
2237		pthread_t wp_threads[THREAD_CONCURRENT_WATCHPOINT_NUM];
2238
2239		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
2240		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
2241
2242		DPRINTF("Before raising %s from child\n", strsignal(sigval));
2243		FORKEE_ASSERT(raise(sigval) == 0);
2244
2245		if (signal_handle != TCSH_DISCARD) {
2246			struct sigaction sa;
2247			unsigned int j;
2248
2249			memset(&sa, 0, sizeof(sa));
2250			if (signal_handle == TCSH_SIG_IGN)
2251				sa.sa_handler = SIG_IGN;
2252			else
2253				sa.sa_handler = thread_concurrent_sig_handler;
2254			sigemptyset(&sa.sa_mask);
2255
2256			for (j = 0;
2257			    j < __arraycount(thread_concurrent_signals_list);
2258			    j++)
2259				FORKEE_ASSERT(sigaction(
2260				    thread_concurrent_signals_list[j], &sa, NULL)
2261				    != -1);
2262		}
2263
2264		DPRINTF("Before starting threads from the child\n");
2265		FORKEE_ASSERT(pthread_barrier_init(
2266		    &thread_concurrent_barrier, NULL,
2267		    breakpoint_threads + signal_threads + watchpoint_threads)
2268		    == 0);
2269		FORKEE_ASSERT(pthread_key_create(&thread_concurrent_key, NULL)
2270		    == 0);
2271
2272		for (i = 0; i < signal_threads; i++) {
2273			FORKEE_ASSERT(pthread_create(&sig_threads[i], NULL,
2274			    thread_concurrent_signals_thread,
2275			    &signal_handle) == 0);
2276		}
2277		for (i = 0; i < breakpoint_threads; i++) {
2278			FORKEE_ASSERT(pthread_create(&bp_threads[i], NULL,
2279			    thread_concurrent_breakpoint_thread, NULL) == 0);
2280		}
2281		for (i = 0; i < watchpoint_threads; i++) {
2282			FORKEE_ASSERT(pthread_create(&wp_threads[i], NULL,
2283			    thread_concurrent_watchpoint_thread, NULL) == 0);
2284		}
2285
2286		DPRINTF("Before joining threads from the child\n");
2287		for (i = 0; i < watchpoint_threads; i++) {
2288			FORKEE_ASSERT(pthread_join(wp_threads[i], NULL) == 0);
2289		}
2290		for (i = 0; i < breakpoint_threads; i++) {
2291			FORKEE_ASSERT(pthread_join(bp_threads[i], NULL) == 0);
2292		}
2293		for (i = 0; i < signal_threads; i++) {
2294			FORKEE_ASSERT(pthread_join(sig_threads[i], NULL) == 0);
2295		}
2296
2297		FORKEE_ASSERT(pthread_key_delete(thread_concurrent_key) == 0);
2298		FORKEE_ASSERT(pthread_barrier_destroy(
2299		    &thread_concurrent_barrier) == 0);
2300
2301		DPRINTF("Before exiting of the child process\n");
2302		_exit(exitval);
2303	}
2304	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
2305
2306	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2307	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
2308
2309	validate_status_stopped(status, sigval);
2310
2311	DPRINTF("Set LWP event mask for the child process\n");
2312	memset(&event, 0, sizeof(event));
2313	event.pe_set_event |= PTRACE_LWP_CREATE;
2314	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, sizeof(event))
2315	    != -1);
2316
2317	DPRINTF("Before resuming the child process where it left off\n");
2318	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
2319
2320	DPRINTF("Before entering signal collection loop\n");
2321	while (1) {
2322		ptrace_siginfo_t info;
2323
2324		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
2325		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0),
2326		    child);
2327		if (WIFEXITED(status))
2328			break;
2329		/* Note: we use validate_status_stopped() to get nice error
2330		 * message.  Signal is irrelevant since it won't be reached.
2331		 */
2332		else if (!WIFSTOPPED(status))
2333			validate_status_stopped(status, 0);
2334
2335		DPRINTF("Before calling PT_GET_SIGINFO\n");
2336		SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info,
2337		    sizeof(info)) != -1);
2338
2339		DPRINTF("Received signal %d from LWP %d (wait: %d)\n",
2340		    info.psi_siginfo.si_signo, info.psi_lwpid,
2341		    WSTOPSIG(status));
2342
2343		ATF_CHECK_EQ_MSG(info.psi_siginfo.si_signo, WSTOPSIG(status),
2344		    "lwp=%d, WSTOPSIG=%d, psi_siginfo=%d", info.psi_lwpid,
2345		    WSTOPSIG(status), info.psi_siginfo.si_signo);
2346
2347		if (WSTOPSIG(status) != SIGTRAP) {
2348			int expected_sig =
2349			    thread_concurrent_signals_list[info.psi_lwpid %
2350			    __arraycount(thread_concurrent_signals_list)];
2351			ATF_CHECK_EQ_MSG(WSTOPSIG(status), expected_sig,
2352				"lwp=%d, expected %d, got %d", info.psi_lwpid,
2353				expected_sig, WSTOPSIG(status));
2354
2355			*FIND_EVENT_COUNT(signal_counts, info.psi_lwpid) += 1;
2356		} else if (info.psi_siginfo.si_code == TRAP_LWP) {
2357#if defined(__i386__) || defined(__x86_64__)
2358			thread_concurrent_lwp_setup(child, info.psi_lwpid);
2359#endif
2360		} else {
2361#if defined(__i386__) || defined(__x86_64__)
2362			switch (thread_concurrent_handle_sigtrap(child, &info)) {
2363				case TCSE_UNKNOWN:
2364					/* already reported inside the function */
2365					break;
2366				case TCSE_BREAKPOINT:
2367					*FIND_EVENT_COUNT(bp_counts,
2368					    info.psi_lwpid) += 1;
2369					break;
2370				case TCSE_WATCHPOINT:
2371					*FIND_EVENT_COUNT(wp_counts,
2372					    info.psi_lwpid) += 1;
2373					break;
2374			}
2375#else
2376			ATF_CHECK_MSG(0, "Unexpected SIGTRAP, si_code=%d\n",
2377			    info.psi_siginfo.si_code);
2378#endif
2379		}
2380
2381		DPRINTF("Before resuming the child process\n");
2382		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1,
2383		     signal_handle != TCSH_DISCARD && WSTOPSIG(status) != SIGTRAP
2384		     ? WSTOPSIG(status) : 0) != -1);
2385	}
2386
2387	for (i = 0; i < signal_threads; i++)
2388		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 1,
2389		    "signal_counts[%d].lec_count=%d; lec_lwp=%d",
2390		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
2391	for (i = signal_threads; i < THREAD_CONCURRENT_SIGNALS_NUM; i++)
2392		ATF_CHECK_EQ_MSG(signal_counts[i].lec_count, 0,
2393		    "extraneous signal_counts[%d].lec_count=%d; lec_lwp=%d",
2394		    i, signal_counts[i].lec_count, signal_counts[i].lec_lwp);
2395
2396	for (i = 0; i < breakpoint_threads; i++)
2397		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 1,
2398		    "bp_counts[%d].lec_count=%d; lec_lwp=%d",
2399		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
2400	for (i = breakpoint_threads; i < THREAD_CONCURRENT_BREAKPOINT_NUM; i++)
2401		ATF_CHECK_EQ_MSG(bp_counts[i].lec_count, 0,
2402		    "extraneous bp_counts[%d].lec_count=%d; lec_lwp=%d",
2403		    i, bp_counts[i].lec_count, bp_counts[i].lec_lwp);
2404
2405	for (i = 0; i < watchpoint_threads; i++)
2406		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 1,
2407		    "wp_counts[%d].lec_count=%d; lec_lwp=%d",
2408		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
2409	for (i = watchpoint_threads; i < THREAD_CONCURRENT_WATCHPOINT_NUM; i++)
2410		ATF_CHECK_EQ_MSG(wp_counts[i].lec_count, 0,
2411		    "extraneous wp_counts[%d].lec_count=%d; lec_lwp=%d",
2412		    i, wp_counts[i].lec_count, wp_counts[i].lec_lwp);
2413
2414	validate_status_exited(status, exitval);
2415}
2416
2417#define THREAD_CONCURRENT_TEST(test, sig_hdl, bps, sigs, wps, descr)	\
2418ATF_TC(test);								\
2419ATF_TC_HEAD(test, tc)							\
2420{									\
2421	atf_tc_set_md_var(tc, "descr", descr);				\
2422}									\
2423									\
2424ATF_TC_BODY(test, tc)							\
2425{									\
2426	thread_concurrent_test(sig_hdl, bps, sigs, wps);		\
2427}
2428
2429THREAD_CONCURRENT_TEST(thread_concurrent_signals, TCSH_DISCARD,
2430    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2431    "Verify that concurrent signals issued to a single thread are reported "
2432    "correctly");
2433THREAD_CONCURRENT_TEST(thread_concurrent_signals_sig_ign, TCSH_SIG_IGN,
2434    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2435    "Verify that concurrent signals issued to a single thread are reported "
2436    "correctly and passed back to SIG_IGN handler");
2437THREAD_CONCURRENT_TEST(thread_concurrent_signals_handler, TCSH_HANDLER,
2438    0, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2439    "Verify that concurrent signals issued to a single thread are reported "
2440    "correctly and passed back to a handler function");
2441
2442#if defined(__i386__) || defined(__x86_64__)
2443THREAD_CONCURRENT_TEST(thread_concurrent_breakpoints, TCSH_DISCARD,
2444    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, 0,
2445    "Verify that concurrent breakpoints are reported correctly");
2446THREAD_CONCURRENT_TEST(thread_concurrent_watchpoints, TCSH_DISCARD,
2447    0, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
2448    "Verify that concurrent breakpoints are reported correctly");
2449THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp, TCSH_DISCARD,
2450    THREAD_CONCURRENT_BREAKPOINT_NUM, 0, THREAD_CONCURRENT_WATCHPOINT_NUM,
2451    "Verify that concurrent breakpoints and watchpoints are reported "
2452    "correctly");
2453
2454THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig, TCSH_DISCARD,
2455    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2456    "Verify that concurrent breakpoints and signals are reported correctly");
2457THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_sig_ign, TCSH_SIG_IGN,
2458    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2459    "Verify that concurrent breakpoints and signals are reported correctly "
2460    "and passed back to SIG_IGN handler");
2461THREAD_CONCURRENT_TEST(thread_concurrent_bp_sig_handler, TCSH_HANDLER,
2462    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM, 0,
2463    "Verify that concurrent breakpoints and signals are reported correctly "
2464    "and passed back to a handler function");
2465
2466THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig, TCSH_DISCARD,
2467    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
2468    "Verify that concurrent watchpoints and signals are reported correctly");
2469THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_sig_ign, TCSH_SIG_IGN,
2470    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
2471    "Verify that concurrent watchpoints and signals are reported correctly "
2472    "and passed back to SIG_IGN handler");
2473THREAD_CONCURRENT_TEST(thread_concurrent_wp_sig_handler, TCSH_HANDLER,
2474    0, THREAD_CONCURRENT_SIGNALS_NUM, THREAD_CONCURRENT_WATCHPOINT_NUM,
2475    "Verify that concurrent watchpoints and signals are reported correctly "
2476    "and passed back to a handler function");
2477
2478THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig, TCSH_DISCARD,
2479    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
2480    THREAD_CONCURRENT_WATCHPOINT_NUM,
2481    "Verify that concurrent breakpoints, watchpoints and signals are reported "
2482    "correctly");
2483THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_sig_ign, TCSH_SIG_IGN,
2484    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
2485    THREAD_CONCURRENT_WATCHPOINT_NUM,
2486    "Verify that concurrent breakpoints, watchpoints and signals are reported "
2487    "correctly and passed back to SIG_IGN handler");
2488THREAD_CONCURRENT_TEST(thread_concurrent_bp_wp_sig_handler, TCSH_HANDLER,
2489    THREAD_CONCURRENT_BREAKPOINT_NUM, THREAD_CONCURRENT_SIGNALS_NUM,
2490    THREAD_CONCURRENT_WATCHPOINT_NUM,
2491    "Verify that concurrent breakpoints, watchpoints and signals are reported "
2492    "correctly and passed back to a handler function");
2493#endif
2494
2495#endif /*defined(TWAIT_HAVE_STATUS)*/
2496
2497/// ----------------------------------------------------------------------------
2498
2499#include "t_ptrace_register_wait.h"
2500#include "t_ptrace_syscall_wait.h"
2501#include "t_ptrace_step_wait.h"
2502#include "t_ptrace_kill_wait.h"
2503#include "t_ptrace_bytetransfer_wait.h"
2504#include "t_ptrace_clone_wait.h"
2505#include "t_ptrace_fork_wait.h"
2506#include "t_ptrace_signal_wait.h"
2507#include "t_ptrace_eventmask_wait.h"
2508#include "t_ptrace_lwp_wait.h"
2509
2510/// ----------------------------------------------------------------------------
2511
2512#include "t_ptrace_amd64_wait.h"
2513#include "t_ptrace_i386_wait.h"
2514#include "t_ptrace_x86_wait.h"
2515
2516/// ----------------------------------------------------------------------------
2517
2518#else
2519ATF_TC(dummy);
2520ATF_TC_HEAD(dummy, tc)
2521{
2522	atf_tc_set_md_var(tc, "descr", "A dummy test");
2523}
2524
2525ATF_TC_BODY(dummy, tc)
2526{
2527
2528	// Dummy, skipped
2529	// The ATF framework requires at least a single defined test.
2530}
2531#endif
2532
2533ATF_TP_ADD_TCS(tp)
2534{
2535	setvbuf(stdout, NULL, _IONBF, 0);
2536	setvbuf(stderr, NULL, _IONBF, 0);
2537
2538#ifdef ENABLE_TESTS
2539	ATF_TP_ADD_TC(tp, traceme_pid1_parent);
2540
2541	ATF_TP_ADD_TC(tp, traceme_vfork_exec);
2542	ATF_TP_ADD_TC(tp, traceme_vfork_signalmasked_exec);
2543	ATF_TP_ADD_TC(tp, traceme_vfork_signalignored_exec);
2544
2545	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sees_terminaton_before_the_parent);
2546	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_sysctl_lookup_without_duplicates);
2547	ATF_TP_ADD_TC_HAVE_PID(tp,
2548		unrelated_tracer_sees_terminaton_before_the_parent);
2549	ATF_TP_ADD_TC_HAVE_PID(tp, tracer_attach_to_unrelated_stopped_process);
2550
2551	ATF_TP_ADD_TC(tp, parent_attach_to_its_child);
2552	ATF_TP_ADD_TC(tp, parent_attach_to_its_stopped_child);
2553
2554	ATF_TP_ADD_TC(tp, child_attach_to_its_parent);
2555	ATF_TP_ADD_TC(tp, child_attach_to_its_stopped_parent);
2556
2557	ATF_TP_ADD_TC_HAVE_PID(tp,
2558		tracee_sees_its_original_parent_getppid);
2559	ATF_TP_ADD_TC_HAVE_PID(tp,
2560		tracee_sees_its_original_parent_sysctl_kinfo_proc2);
2561	ATF_TP_ADD_TC_HAVE_PID(tp,
2562		tracee_sees_its_original_parent_procfs_status);
2563
2564	ATF_TP_ADD_TC(tp, siginfo_set_unmodified);
2565	ATF_TP_ADD_TC(tp, siginfo_set_faked);
2566
2567	ATF_TP_ADD_TC(tp, traceme_exec);
2568	ATF_TP_ADD_TC(tp, traceme_signalmasked_exec);
2569	ATF_TP_ADD_TC(tp, traceme_signalignored_exec);
2570
2571	ATF_TP_ADD_TC(tp, trace_thread_nolwpevents);
2572	ATF_TP_ADD_TC(tp, trace_thread_lwpexit);
2573	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate);
2574	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit);
2575
2576	ATF_TP_ADD_TC(tp, trace_thread_lwpexit_masked_sigtrap);
2577	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_masked_sigtrap);
2578	ATF_TP_ADD_TC(tp, trace_thread_lwpcreate_and_exit_masked_sigtrap);
2579
2580	ATF_TP_ADD_TC(tp, threads_and_exec);
2581
2582	ATF_TP_ADD_TC(tp, suspend_no_deadlock);
2583
2584	ATF_TP_ADD_TC(tp, resume);
2585
2586	ATF_TP_ADD_TC(tp, user_va0_disable_pt_continue);
2587	ATF_TP_ADD_TC(tp, user_va0_disable_pt_syscall);
2588	ATF_TP_ADD_TC(tp, user_va0_disable_pt_detach);
2589
2590	ATF_TP_ADD_TC(tp, core_dump_procinfo);
2591
2592#if defined(TWAIT_HAVE_STATUS)
2593	ATF_TP_ADD_TC(tp, thread_concurrent_signals);
2594	ATF_TP_ADD_TC(tp, thread_concurrent_signals_sig_ign);
2595	ATF_TP_ADD_TC(tp, thread_concurrent_signals_handler);
2596#if defined(__i386__) || defined(__x86_64__)
2597	ATF_TP_ADD_TC(tp, thread_concurrent_breakpoints);
2598	ATF_TP_ADD_TC(tp, thread_concurrent_watchpoints);
2599	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp);
2600	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig);
2601	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_sig_ign);
2602	ATF_TP_ADD_TC(tp, thread_concurrent_bp_sig_handler);
2603	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig);
2604	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_sig_ign);
2605	ATF_TP_ADD_TC(tp, thread_concurrent_wp_sig_handler);
2606	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig);
2607	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_sig_ign);
2608	ATF_TP_ADD_TC(tp, thread_concurrent_bp_wp_sig_handler);
2609#endif
2610#endif
2611
2612	ATF_TP_ADD_TCS_PTRACE_WAIT_REGISTER();
2613	ATF_TP_ADD_TCS_PTRACE_WAIT_SYSCALL();
2614	ATF_TP_ADD_TCS_PTRACE_WAIT_STEP();
2615	ATF_TP_ADD_TCS_PTRACE_WAIT_KILL();
2616	ATF_TP_ADD_TCS_PTRACE_WAIT_BYTETRANSFER();
2617	ATF_TP_ADD_TCS_PTRACE_WAIT_CLONE();
2618	ATF_TP_ADD_TCS_PTRACE_WAIT_FORK();
2619	ATF_TP_ADD_TCS_PTRACE_WAIT_SIGNAL();
2620	ATF_TP_ADD_TCS_PTRACE_WAIT_EVENTMASK();
2621	ATF_TP_ADD_TCS_PTRACE_WAIT_LWP();
2622
2623	ATF_TP_ADD_TCS_PTRACE_WAIT_AMD64();
2624	ATF_TP_ADD_TCS_PTRACE_WAIT_I386();
2625	ATF_TP_ADD_TCS_PTRACE_WAIT_X86();
2626
2627#else
2628	ATF_TP_ADD_TC(tp, dummy);
2629#endif
2630
2631	return atf_no_error();
2632}
2633