Add interface in ptrace(2) to track thread (LWP) events:
- birth,
- termination.
The purpose of this thread is to keep track of the current thread state in
a tracee and apply e.g. per-thread designed hardware assisted watchpoints.
This interface reuses the EVENT_MASK and PROCESS_STATE interface, and
shares it with PTRACE_FORK, PTRACE_VFORK and PTRACE_VFORK_DONE.
Change the following structure:
typedef struct ptrace_state {
int pe_report_event;
pid_t pe_other_pid;
} ptrace_state_t;
to
typedef struct ptrace_state {
int pe_report_event;
union {
pid_t _pe_other_pid;
lwpid_t _pe_lwp;
} _option;
} ptrace_state_t;
#define pe_other_pid _option._pe_other_pid
#define pe_lwp _option._pe_lwp
This keeps size of ptrace_state_t unchanged as both pid_t and lwpid_t are
defined as int32_t-like integer. This change does not break existing
prebuilt software and has minimal effect on necessity for source-code
changes. In summary, this change should be binary compatible and shouldn't
break build of existing software.
Introduce new siginfo(5) type for LWP events under the SIGTRAP signal:
TRAP_LWP. This change will help debuggers to distinguish exact source of
SIGTRAP.
Add two basic t_ptrace_wait* tests:
lwp_create1:
Verify that 1 LWP creation is intercepted by ptrace(2) with
EVENT_MASK set to PTRACE_LWP_CREATE
lwp_exit1:
Verify that 1 LWP creation is intercepted by ptrace(2) with
EVENT_MASK set to PTRACE_LWP_EXIT
All tests are passing.
Surfing the previous kernel ABI bump to 7.99.59 for PTRACE_VFORK{,_DONE}.
Sponsored by <The NetBSD Foundation>
eventmask3:
Verify that PTRACE_VFORK in EVENT_MASK is preserved
eventmask4:
Verify that PTRACE_VFORK_DONE in EVENT_MASK is preserved
Currently eventmask3 is failing and marked with PR kern/51630
Sponsored by <The NetBSD Foundation>
PTRACE_VFORK and PTRACE_VFORK_DONE are now parts of <sys/ptrace.h>.
PTRACE_VFORK tests are still failing as the support for it is currently
a stub.
Sponsored by <The NetBSD Foundation>
vforkdone1:
Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK
set to PTRACE_VFORK_DONE
vforkdone2:
Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK
set to PTRACE_FORK | PTRACE_VFORK_DONE
As of now PTRACE_VFORK_DONE is undefined in <sys/ptrace.h>.
Sponsored by <The NetBSD Foundation>
siginfo5:
Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK
set to PTRACE_FORK and reports correct signal information
Sponsored by <The NetBSD Foundation>
siginfo4:
Detect SIGTRAP TRAP_EXEC from tracee
This test is currently disabled and it will be enabled once
PT_[SG]ET_SIGINFO will land the sources.
Sponsored by <The NetBSD Foundation>
These tests are for the proposed PT_[GS]ET_SIGINFO interface for ptrace(2),
accessors for signal information that caused tracee to be interrupted.
siginfo1:
Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee
siginfo2:
Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without
modification of SIGINT from tracee
siginfo3:
Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with
setting signal to new value
New tests are protected with #ifded and currently disabled in the HEAD branch.
They will be automatically enabled once the final implementation will land the
sources.
Sponsored by <The NetBSD Foundation>
Addedd tests:
- watchpoint_count
- watchpoint_read
- watchpoint_write_unmodified
- watchpoint_trap_code[0123]
- watchpoint_trap_data_write[0123]
- watchpoint_trap_data_rw[0123]
These code will be reused later for i386 and moved to a common place like
tests/kernel/arch/x86.
These tests are x86 specific only. The same API but different private
ptrace_watchpoint MD part has to be used on other ports.
All tests pass on amd64.
Sponsored by <The NetBSD Foundation>
Add new symbol ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS() to be protected with
the __HAVE_PTRACE_WATCHPOINTS guard.
XXX:
Mark check_happy() with __attribute__((optimize("O0"))).
Disabled optimization is required to make tests for hardware assisted
traps in .text functional.
Tested with GCC 5.4 on NetBSD 7.99.47 amd64
Sponsored by <The NetBSD Foundation>
CPU Debug Registers won't be exposed as is to userland.
Hardware Watchpoints will be exported to userland dedicated interface
through the ptrace(2) interface.
Sponsored by <The NetBSD Foundation>
CPU Debug Registers won't be exposed as is to userland.
Hardware Watchpoints will be exported to userland dedicated interface
through the ptrace(2) interface.
Sponsored by <The NetBSD Foundation>
Reported error:
src/tests/kernel/t_ptrace_wait.c:4401:33:
error: missing field 'pl_event' initializer
[-Werror,-Wmissing-field-initializers]
Line in the code:
struct ptrace_lwpinfo info = {0};
Appease it with initializing info to {0, 0}.
Sponsored by <The NetBSD Foundation>
Switch from:
child = atf_utils_fork();
to:
ATF_REQUIRE((child = fork()) != -1);
Prefer the latter as working as intended and not outputing to files with
danger to overwrite files' content after each fork in test-suite.
Discussed with Christos Zoulas.
Sponsored by <The NetBSD Foundation>
Remove atf_tc_expect_fail() linked with PR kern/51685.
Issue fixed by Christsos Zoulas in src/sys/kern/kern_sig.c r. 1.331
Sponsored by <The NetBSD Foundation>
Add new preliminary tests for testing that CPU Debug Registers can be used
to trap on a variable (write operation).
dbregs_dr0_trap_variable:
Verify that setting trap with DR0 triggers SIGTRAP
dbregs_dr1_trap_variable:
Verify that setting trap with DR1 triggers SIGTRAP
dbregs_dr2_trap_variable:
Verify that setting trap with DR2 triggers SIGTRAP
dbregs_dr3_trap_variable:
Verify that setting trap with DR3 triggers SIGTRAP
Sponsored by <The NetBSD Foundation>
lwpinfo1:
Verify baic LWPINFO call for single thread (PT_TRACE_ME)
lwpinfo2:
Verify baic LWPINFO call for single thread (PT_ATTACH from tracer)
Both tests are marked as expected failure PR kern/51685:
ptrace(2): Signal does not set PL_EVENT_SIGNAL in
(struct ptrace_lwpinfo.)pl_event
Sponsored by <The NetBSD Foundation>
Rename dbregs1 to dbregs_print
Rename dbregs[2345] to dbregs_preserve_dr[0123]
Add new tests dbregs_preserve_dr[0123]_yield.
dbregs_preserve_dr0_yield:
Verify that setting DR0 is preserved across ptrace(2) calls with
scheduler yield
dbregs_preserve_dr1_yield:
Verify that setting DR1 is preserved across ptrace(2) calls with
scheduler yield
dbregs_preserve_dr2_yield:
Verify that setting DR2 is preserved across ptrace(2) calls with
scheduler yield
dbregs_preserve_dr3_yield:
Verify that setting DR3 is preserved across ptrace(2) calls with
scheduler yield
Add new tests dbregs_preserve_dr[0123]_continued.
dbregs_preserve_dr0_continued:
Verify that setting DR0 is preserved across ptrace(2) calls and with
continued child
dbregs_preserve_dr1_continued:
Verify that setting DR1 is preserved across ptrace(2) calls and with
continued child
dbregs_preserve_dr2_continued:
Verify that setting DR2 is preserved across ptrace(2) calls and with
continued child
dbregs_preserve_dr3_continued:
Verify that setting DR3 is preserved across ptrace(2) calls and with
continued child
Use more meaningful names for these tests as they are MD specific and
testing precise functionality. Also there will be a growing number of
tests in this category and prefixing everything with plain dbregs and
trailing with a number cannot be verbose.
Sponsored by <The NetBSD Foundation>
dbregs2:
Verify that setting DR0 is preserved across ptrace(2) calls
dbregs3:
Verify that setting DR1 is preserved across ptrace(2) calls
dbregs4:
Verify that setting DR2 is preserved across ptrace(2) calls
dbregs5:
Verify that setting DR3 is preserved across ptrace(2) calls
These tests are deliberately fine-grained as they are expected to penetrate
precisely each functional aspect of CPU Debug Registers on amd64 one after
another.
These tests (and MI ones) might be generated or merged with helper
functions, however in order to copy-and-paste them out of a test-suite and
quickly port to other platform (in order to compare results) it's useful to
keep them as stand-alone as they are.
Code from these tests might be shared with other ports in future, for the
same reason keep them currently as they are.
Sponsored by <The NetBSD Foundation>
Rename
- tests/kernel/t_ptrace_amd64_wait.c
to
- tests/kernel/arch/amd64/t_ptrace_wait.c
and adapt appropriate files accordingly.
New directory will be used for more amd64-specific tests, verifying the
MD parts of the kernel.
Remove old entries from distrib/sets/lists as they were added a while ago.
Sponsored by <The NetBSD Foundation>
Clone t_ptrace_wait.c to t_ptrace_amd64_wait.c and put common parts to
t_ptrace_wait.h.
The t_ptrace_amd64_wait.c file is dedicated to hold amd64-specific tests
for the ptrace(2) interface.
Add new basic test dbreg1 in t_ptrace_amd64_wait{,3,4,6,id,pid}:
Verify plain PT_GETDBREGS with printing Debug Registers
Fix evbarm64-aarch64 issue pointed by <christos>, kill1 and kill2 tests
must be defined without PT_STEP guards.
Sponsored by <The NetBSD Foundation>
New tests verify that PT_CONTINUE with SIGKILL is equivalent to PT_KILL.
kill1:
Verify that PT_CONTINUE with SIGKILL terminates child
kill2:
Verify that PT_KILL terminates child
Sponsored by <The NetBSD Foundation>
dbregs1:
Verify plain PT_GETDBREGS call without further steps
dbregs2:
Verify PT_GETDBREGS and PT_SETDBREGS calls without changing regs
These tests are to be used to verify CPU Debug Register accessors in the
ptrace(2) interface.
Additionally fix also fpregs2 test to really call PT_SETFPREGS.
Sponsored by <The NetBSD Foundation>
step2:
Verify PT_STEP called twice
step3:
Verify PT_STEP called three times
step4:
Verify PT_STEP called four times
The purpose of these tests is to assert that PT_STEP can be called more
than once and it sill works.
Sponsored by <The NetBSD Foundation>
step1:
Verify single PT_STEP call.
This function is calculating happy numbers just to consume CPU cycles for
the test purpose.
PT_STEP raises SIGTRAP to by caught by a debugger.
Sponsored by <The NetBSD Foundation>
# if used with o, x or X specifiers the value is preceeded with 0, 0x or 0X
respectively for values different than zero.
Noted by <christos>
Sponsored by <The NetBSD Foundation>
fpregs1:
Verify plain PT_GETFPREGS call without further steps
fpregs2:
Verify PT_GETFPREGS and PT_SETFPREGS calls without changing regs
Sponsored by <The NetBSD Foundation>
Add new ATF tests for the general purpose register calls.
These tests require platforms to export all of the following macros:
- PT_GETREGS
- PT_SETREGS
- PTRACE_REG_PC
- PTRACE_REG_SET_PC
- PTRACE_REG_SP
- PTRACE_REG_INTRV
This has been done for the sake of C preprocessor magic simplicity.
There are ports without covering all of the above symbols -- skip them.
Added tests
===========
regs1:
Verify plain PT_GETREGS call without further steps
regs2:
Verify plain PT_GETREGS call and retrieve PC
regs3:
Verify plain PT_GETREGS call and retrieve SP
regs4:
Verify plain PT_GETREGS call and retrieve INTRV
regs5:
Verify PT_GETREGS and PT_SETREGS calls without changing regs
Sponsored by <The NetBSD Foundation>
New tests are direct counterparts to the existing ones {,io_}read_d[1234].
PT_READ_D and PIOD_READ_D (from PT_IO) are traditionally used to transfer
data segment. New tests make use of PT_READ_I and PIOD_READ_I (from PT_IO)
in order to copy text segment from traced process.
Traditionally, ptrace() has
allowed for machines with distinct address spaces for
instruction and data, which is why there are two requests:
conceptually, PT_READ_I reads from the instruction space
and PT_READ_D reads from the data space. In the current
NetBSD implementation, these two requests are completely
identical.
--- ptrace(2)
New tests follow the traditional convention and copy only instructions from
dummy functions.
There are no new tests copying data to .text regions from the traced
process, as this is violating mprotect restrictions. This limitation may be
addressed in future, as there are dedicated sysctl(7) handlers for
debuggers (currently mainly gdb(1)).
Tests verifying identical behavior of PT_READ_I and PT_READ_D are not
planned.
Sponsored by <The NetBSD Foundation>
Rename io_read_write_handshake to io_read_d_write_d_handshake1.
io_read_d_write_d_handshake2:
Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake
This new test first writes and later reads data.
io_read_d_write_d_handshake1 first reads and later writes.
Sponsored by <The NetBSD Foundation>
read1:
Verify PT_READ_D called once
read2:
Verify PT_READ_D called twice
read3:
Verify PT_READ_D called three times
read4:
Verify PT_READ_D called four times
Sponsored by <The NetBSD Foundation>
write1:
Verify PT_WRITE_D called once
write2:
Verify PT_WRITE_D called twice
write3:
Verify PT_WRITE_D called three times
write4:
Verify PT_WRITE_D called four times
Sponsored by <The NetBSD Foundation>
io_write_d1:
Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)
io_write_d2:
Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)
io_write_d3:
Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)
io_write_d4:
Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)
Sponsored by <The NetBSD Foundation>
io_read_d1:
Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)
io_read_d2:
Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)
io_read_d3:
Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)
io_read_d4:
Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)
Sponsored by <The NetBSD Foundation>
These tests are exact clones for fork1 and fork2, however testing vfork(2).
vfork1:
Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK set to
PTRACE_VFORK.
vfork2:
Verify that vfork(2) is not intercepted by ptrace(2) with empty
EVENT_MASK.
vfork1 is supposed to test currently unimplemented PTRACE_VFORK option in
EVENT_MASK, marked as failure and linked with PR kern/51630.
Sponsored by <The NetBSD Foundation>
Verify that fork(2) is not intercepted by ptrace(2) with empty EVENT_MASK.
This test works with all wait(2)-like functions.
Debugger receives only SIGCHLD from tracee, when its the child of tracee
exits. Tracer notes nothing about fork(2) events.
Sponsored by <The NetBSD Foundation>
Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK set to
PTRACE_FORK.
In this test tracee calls fork(2) and this event is noted by tracer, both
for forker and forkee with PT_GET_PROCESS_STATE reporting pe_report_event
equal to PTRACE_FORK and pe_other_pid as forkee for forker and forker for
forkee.
The fork(2) event in the current implementation stops forker and forkee
with the SIGTRAP signal.
Exited forkee stops forker with the SIGCHLD signal.
Sponsored by <The NetBSD Foundation>.
Add basic tests verifying that value between PT_SET_EVENT_MASK and
PT_GET_EVENT_MASK is preserved between two ptrace(2) calls.
eventmask1: Verify that empty EVENT_MASK is preserved
eventmask2: Verify that PTRACE_FORK in EVENT_MASK is preserved
Currently the only supported event in ptrace(2) is PTRACE_FORK.
These tests are appropriate for all wait(2)-like functions.
Sponsored by <The NetBSD Foundation>
Remove trailing white space
Remove fflush(3) calls [previously added for debugging purposes]
Correct comment /proc/curproc/stat -> /proc/curpros/status
The status file is native for NetBSD, stat for Linux compatibility
No functional change.
Sponsored by <The NetBSD Foundation>
attach6:
Assert that tracer sees its parent when attached to tracer (check
sysctl(7) and struct kinfo_proc2)
attach7:
Assert that tracer sees its parent when attached to tracer (check
/proc/curproc/status 3rd column).
Currently these tests fail as getppid() and parent id obtained in these
alternative ways differ.
Sponsored by <The NetBSD Foundation>
The write(2) call does not block and there is need to perform handshake, in
order to wait on the read(2) call.
The pipe(2) interface for IPC purposes is quite difficult to design and get
right. It might be refactored and with added new helper functions, although
it would be better to switch to some other mechanism rather. But as it
works now quite well in the current set of tests, do not touch it.
Sponsored by <The NetBSD Foundation>.
Set SIGSTOP as expected signal in attach3, is it is preferred in general.
Not just because FreeBSD and Linux work this way, but to make it consistent
and regardless of relation between tracee and tracer always get the same
signal.
attach3 tests parent attaching with PT_ATTACH to its child
Sponsored by <The NetBSD Foundation>
tracer got a chance to run before we trace it.
- Unbuffer stdout and stderr, because the tracee ends up with with the tracers
unflushed buffers, and that confuses things.
Assert that tracer sees its parent when attached to tracer.
This test is designed only for wait(2) members with ability to specify the
PID value. This propery excludes wait(2) and wait3(2).
Add new helper macro ATF_TP_ADD_TC_HAVE_PID() enabing tests when
TWAIT_HAVE_PID is defined.
This test fails and is linked with the following issue: PR kern/51624.
Sponsored by <The NetBSD Foundation>.
Assert that tracer parent can PT_ATTACH to its child.
This test is for all members of the wait(2) family.
Currently it is marked as an explicit failure PR kern/51621.
I faced the following issues (noted and discussed in the bug report):
- PT_ATTACH seems to work, but waiting for stopped status and signal from the
child results in getting SIGTRAP, not SIGSTOP like in Linux and FreeBSD. This
might be by design, I'm unsure. However, so far I was getting SIGSTOP from a
tracer process that was not the parent. SIGSTOP vs SIGTRAP logic also
complicates the things up as tracer must check whether is a parent for tracee
or not - this shouldn't be needed.
- PT_CONTINUE seems to have no effect at all, the child hangs. This operation
works on Linux and FreeBSD and in the end, test passes correctly.
- Debugging this with gdb(1) results in receiving SIGABRT from the GNU
debugger (in the moment of raising/receiving SIGTRAP). This is making the
things harder in general.
Sponsored by <The NetBSD Foundation>.
This test asserts that any tracer sees process termination before its
parent.
This test is not applicable for wait(2) and wait(3) as these interfaces
cannot get specified process id argument (PID).
Sponsored by <The NetBSD Foundation>.
Assert that a debugger cannot trace another process unless the process's
root directory is at or below the tracing process's root.
Sponsored by <The NetBSD Foundation>.
Assert that a debugger cannot attach to self (as it's nonsense).
NetBSD returs here EINVAL.
Clean up unused header includes.
Sponsored by <The NetBSD Foundation>.
Move out wait(2) specific tests from t_ptrace and put them to t_ptrace_wait
Add generic code fragments to reuse the same source-code for every member
of the wait(2) family, namely:
- wait(2)
- waitpid(2)
- waitid(2)
- wait3(2)
- wait4(2)
- wait6(2)
Currently in the new test-suite there are the following tests:
- traceme1
- traceme2
- traceme3
- traceme4
- attach1
Not all tests are possible to be executed against every wait(2)-like
interface, therefore they will be disabled in such case. Currently this
limits attach1 to waitpid(2), waitid(2), wait4(2), wait6(2), while the
other tests (traceme 1-4) run with all of the interfaces.
The construct of this file is dedicated for addition of new tests in the
close future.
As of now all of the tests pass correctly.
Thanks for Robert Elz for suggestions on improving the code (earlier draft
of this new form).
Sponsored by <The NetBSD Foundation>.
Add in ATF_TC_HEAD() of attach_pid1 the following code to run it as
non-root: atf_tc_set_md_var(tc, "require.user", "unprivileged");
Solution pointed out by Nicolas Joly.
Sponsored by <The NetBSD Foundation>.
attach_pid0 asserts that it is not valid to attach PID 0 as it is a special
kernel process.
assert_pid1 asserts that non-root user cannot attach to PID 1 as it is the
/dev/init process. This tests is skipped if run as root.
Sponsored by <The NetBSD Foundation>.
Christos Zoulas fixed the issue that a parent sees termination of its child
before a tracer observing it for its tracee.
Many thanks to Christs for his help, he makes progress with tests so quick.
Closes PR kern/51600
Sponsored by <The NetBSD Foundation>.
This test asserts that tracer sees process termination before the parent
Currently this is not true for NetBSD.
The problem has been reported in gnats as kern/51600.
Originally an early version of this test triggered kernel panic, that
was fixed by Christos Zoulas -- thanks! Appropriate fixes are as follows:
http://mail-index.netbsd.org/source-changes/2016/11/04/msg078868.htmlhttp://mail-index.netbsd.org/source-changes/2016/11/04/msg078869.html
Mark this test as expected failure and linked with proper PR.
As an interesting note, this test uses pipe(2) to perform IPC. Use for
messages uint8_t message to be sure that it will never by transmitted
partially from a caller to a callee, this assumption simplifies the code.
Add local function await_zombie() that takes process identifier (pid).
This function uses the sysctl(7) interface to probe p_stat of a requested
process and compares it with LSZOMB.
Try to keep closing all unneeded file descriptors for pipes in order to not
run out of fds later.
Sponsored by <The NetBSD Foundation>.
A child process cannot call atf functions and expect them to magically
work like in the parent.
The printf(3) messaging from a child will not work out of the box as well
without estabilishing a communication protocol with its parent. To not
overcomplicate the tests - do not log from a child and use err(3)/errx(3)
wrapped with FORKEE_ASSERT()/FORKEE_ASSERTX() as that is guaranteed to work.
Simplify and cleanup code of the tests.
Sponsored by <The NetBSD Foundation>.
Raising SIGCONT from a ptrace(2)d child should be catched with waidpid(2)
as WIFCONTINUED() false and WIFSTOPPED() true; not both true as it does not
make much sense.
PR kern/51596
Change requested by <kre>
Checked by <christos>
Sponsored by <The NetBSD Foundation>
This test verifies calling raise(2) with the SIGCONT argument in the child.
The parent is notified with it and asserts that WIFCONTINUED() and
WIFSTOPPED() are both set.
XXX: This behavior is surprising. Linux for the same code-path returns false
for WIFCONTINUED() and true for WIFSTOPPED().
Include <stdlib.h> for EXIT_FAILURE.
This code covers (uncovers issues?) WIFCONTINUED() and is the last planned
test in the ptraceme category.
Sponsored by <The NetBSD Foundation>.
For future reference and convenience, an out-of-ATF test is as follows:
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define ATF_REQUIRE(a) assert(a)
#if defined(linux)
#define WALLSIG __WALL
#define sys_signame sys_siglist
#endif
int main(int argc, char **argv)
{
int status;
const int exitval = 5;
const int sigval = SIGSTOP, sigsent = SIGCONT;
pid_t child, wpid;
printf("1: Before forking process PID=%d\n", getpid());
ATF_REQUIRE((child = fork()) != -1);
if (child == 0) {
/* printf(3) messages from a child aren't intercepted by ATF */
/* "2: Child process PID=%d\n", getpid() */
/* "2: Before calling ptrace(PT_TRACE_ME, ...)\n" */
if (ptrace(PT_TRACE_ME, 0, NULL, 0) == -1) {
/* XXX: Is it safe to use ATF functions in a child? */
err(EXIT_FAILURE, "2: ptrace(2) call failed with "
"status %s", sys_errlist[errno]);
}
/* "2: Before raising SIGSTOP\n" */
raise(sigval);
/* "2: Before raising SIGCONT\n" */
raise(sigsent);
/* "2: Before calling _exit(%d)\n", exitval */
_exit(exitval);
} else {
printf("1: Parent process PID=%d, child's PID=%d\n", getpid(),
child);
printf("1: Before calling waitpid() for the child\n");
wpid = waitpid(child, &status, 0);
printf("1: Validating child's PID (expected %d, got %d)\n",
child, wpid);
ATF_REQUIRE(child == wpid);
printf("1: Ensuring that the child has not been exited\n");
ATF_REQUIRE(!WIFEXITED(status));
printf("1: Ensuring that the child has not been continued\n");
ATF_REQUIRE(!WIFCONTINUED(status));
printf("1: Ensuring that the child has not been terminated "
"with a signal\n");
ATF_REQUIRE(!WIFSIGNALED(status));
printf("1: Ensuring that the child has been stopped\n");
ATF_REQUIRE(WIFSTOPPED(status));
printf("1: Verifying that he child has been stopped with the"
" %s signal (received %s)\n", sys_signame[sigval],
sys_signame[WSTOPSIG(status)]);
ATF_REQUIRE(WSTOPSIG(status) == sigval);
printf("1: Before resuming the child process where it left "
"off and without signal to be sent\n");
ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0)
!= -1);
printf("1: Before calling waitpid() for the child\n");
wpid = waitpid(child, &status, WALLSIG);
printf("1: Validating that child's PID is still there\n");
ATF_REQUIRE(wpid == child);
printf("1: Ensuring that the child has not been exited\n");
ATF_REQUIRE(!WIFEXITED(status));
printf("1: Ensuring that the child has been continued\n");
ATF_REQUIRE(WIFCONTINUED(status));
printf("1: Ensuring that the child has not been terminated "
"with a signal\n");
ATF_REQUIRE(!WIFSIGNALED(status));
printf("1: Ensuring that the child has not been stopped\n");
ATF_REQUIRE(WIFSTOPPED(status));
printf("1: Before resuming the child process where it left "
"off and without signal to be sent\n");
ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
printf("1: Before calling waitpid() for the child\n");
wpid = waitpid(child, &status, 0);
printf("1: Validating that child's PID is still there\n");
ATF_REQUIRE(wpid == child);
printf("1: Ensuring that the child has been exited\n");
ATF_REQUIRE(WIFEXITED(status));
printf("1: Ensuring that the child has not been continued\n");
ATF_REQUIRE(!WIFCONTINUED(status));
printf("1: Ensuring that the child has not been terminated "
"with a signal\n");
ATF_REQUIRE(!WIFSIGNALED(status));
printf("1: Ensuring that the child has not been stopped\n");
ATF_REQUIRE(!WIFSTOPPED(status));
printf("1: Verifying that he child has exited with the "
"%d status (received %d)\n", exitval, WEXITSTATUS(status));
ATF_REQUIRE(WEXITSTATUS(status) == exitval);
printf("1: Before calling waitpid() for the exited child\n");
wpid = waitpid(child, &status, 0);
printf("1: Validating that child's PID no longer exists\n");
ATF_REQUIRE(wpid == -1);
printf("1: Validating that errno is set to %s (got %s)\n",
sys_errlist[ECHILD], sys_errlist[errno]);
ATF_REQUIRE(errno == ECHILD);
}
}
This test is modeled after traceme1 and traceme2 with the goal to test if
the child was terminated with a received signal passed with PT_CONTINUE.
Currently the three traceme tests verifies three possible status values from
waitpid(2) called by the parent:
- WIFEXITED(status),
- WIFSIGNALED(status),
- WIFSTOPPED(status)
with associated macros:
- WEXITSTATUS(status),
- WTERMSIG(status),
- WCOREDUMP(status),
- WSTOPSIG(status).
In traceme3 has been assumed that Ctrl-C (SIGINT) does not emit core(5).
Sponsored by <The NetBSD Foundation>.
This test is a clone of traceme2 with ptrace(2) calling PT_CONTINUE
with signal to be passed to the child: SIGINT. traceme1 sends no signals.
Sponsored by <The NetBSD Foundation>.
This test is a placeholder for further checks of the native ptrace(2)
function calls.
XXX: Is it safe to call ATF functions from a child? FreeBSD seems to
construct dedicated asserts for them.
XXX: printf(3) calls from a child are not intercepted by atf-run(1)
Sponsored by <The NetBSD Foundation>.
be able to restore it to its old value later due to running at securelevel
above 0.
Previously this would fail and leave curtain enabled untill next reboot (but
causing further runs of the test to suceed, just to maximize confusion).
This went unnoticed initial since most modular test kernels run with options
INSECURE to allow exercising the kernel module loader.
The only way to pass global state from the body to the cleanup is via the
file system.
Fixes leaks of global system resources (in all cases, given that the body
does not by itself clean things up).
reduce the pass-count from 100 to 50; this is more than enough to prove
that the test is working, and helps reduce the ever-increasing time it's
taking to run the entire test suite.
get started before trying to ptrace(ATTACH). Otherwise, the traced
process doesn't seem to resume properly upon ptrace(DETACH) and on the
next pass the ptrace(ATTACH) just hangs forever, causing the test to
time-out.
XXX The failure-to-resume-properly might actually be a kernel bug that
we need to follow up on. But for now, let's make the test work as
intended.
Factor out the generation of token_keys to a separate routine, called
from each test case. And make sure we remove the mkdtemp()-created
directory after we're finished with it.