Changeset View
Changeset View
Standalone View
Standalone View
head/tests/sys/kern/ptrace_test.c
Show First 20 Lines • Show All 1,410 Lines • ▼ Show 20 Lines | ATF_TC_BODY(ptrace__siginfo, tc) | ||||
ATF_REQUIRE(WIFEXITED(status)); | ATF_REQUIRE(WIFEXITED(status)); | ||||
ATF_REQUIRE(WEXITSTATUS(status) == 0); | ATF_REQUIRE(WEXITSTATUS(status) == 0); | ||||
wpid = wait(&status); | wpid = wait(&status); | ||||
ATF_REQUIRE(wpid == -1); | ATF_REQUIRE(wpid == -1); | ||||
ATF_REQUIRE(errno == ECHILD); | ATF_REQUIRE(errno == ECHILD); | ||||
} | } | ||||
/* | |||||
* Verify that the expected ptrace events are reported for PTRACE_EXEC. | |||||
*/ | |||||
ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_disable); | |||||
ATF_TC_BODY(ptrace__ptrace_exec_disable, tc) | |||||
{ | |||||
pid_t fpid, wpid; | |||||
int events, status; | |||||
ATF_REQUIRE((fpid = fork()) != -1); | |||||
if (fpid == 0) { | |||||
trace_me(); | |||||
exec_thread(NULL); | |||||
} | |||||
/* The first wait() should report the stop from SIGSTOP. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(wpid == fpid); | |||||
ATF_REQUIRE(WIFSTOPPED(status)); | |||||
ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); | |||||
events = 0; | |||||
ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); | |||||
/* Should get one event at exit. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(WIFEXITED(status)); | |||||
ATF_REQUIRE(WEXITSTATUS(status) == 0); | |||||
wpid = wait(&status); | |||||
ATF_REQUIRE(wpid == -1); | |||||
ATF_REQUIRE(errno == ECHILD); | |||||
} | |||||
ATF_TC_WITHOUT_HEAD(ptrace__ptrace_exec_enable); | |||||
ATF_TC_BODY(ptrace__ptrace_exec_enable, tc) | |||||
{ | |||||
struct ptrace_lwpinfo pl; | |||||
pid_t fpid, wpid; | |||||
int events, status; | |||||
ATF_REQUIRE((fpid = fork()) != -1); | |||||
if (fpid == 0) { | |||||
trace_me(); | |||||
exec_thread(NULL); | |||||
} | |||||
/* The first wait() should report the stop from SIGSTOP. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(wpid == fpid); | |||||
ATF_REQUIRE(WIFSTOPPED(status)); | |||||
ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); | |||||
events = PTRACE_EXEC; | |||||
ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); | |||||
/* The next event should be for the child process's exec. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(WIFSTOPPED(status)); | |||||
ATF_REQUIRE(WSTOPSIG(status) == SIGTRAP); | |||||
ATF_REQUIRE(ptrace(PT_LWPINFO, wpid, (caddr_t)&pl, sizeof(pl)) != -1); | |||||
ATF_REQUIRE((pl.pl_flags & (PL_FLAG_EXEC | PL_FLAG_SCX)) == | |||||
(PL_FLAG_EXEC | PL_FLAG_SCX)); | |||||
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); | |||||
/* The last event should be for the child process's exit. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(WIFEXITED(status)); | |||||
ATF_REQUIRE(WEXITSTATUS(status) == 0); | |||||
wpid = wait(&status); | |||||
ATF_REQUIRE(wpid == -1); | |||||
ATF_REQUIRE(errno == ECHILD); | |||||
} | |||||
ATF_TC_WITHOUT_HEAD(ptrace__event_mask); | |||||
ATF_TC_BODY(ptrace__event_mask, tc) | |||||
{ | |||||
pid_t fpid, wpid; | |||||
int events, status; | |||||
ATF_REQUIRE((fpid = fork()) != -1); | |||||
if (fpid == 0) { | |||||
trace_me(); | |||||
exit(0); | |||||
} | |||||
/* The first wait() should report the stop from SIGSTOP. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(wpid == fpid); | |||||
ATF_REQUIRE(WIFSTOPPED(status)); | |||||
ATF_REQUIRE(WSTOPSIG(status) == SIGSTOP); | |||||
/* PT_FOLLOW_FORK should toggle the state of PTRACE_FORK. */ | |||||
ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 1) != -1); | |||||
ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(events & PTRACE_FORK); | |||||
ATF_REQUIRE(ptrace(PT_FOLLOW_FORK, fpid, NULL, 0) != -1); | |||||
ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(!(events & PTRACE_FORK)); | |||||
/* PT_LWP_EVENTS should toggle the state of PTRACE_LWP. */ | |||||
ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 1) != -1); | |||||
ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(events & PTRACE_LWP); | |||||
ATF_REQUIRE(ptrace(PT_LWP_EVENTS, fpid, NULL, 0) != -1); | |||||
ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, fpid, (caddr_t)&events, | |||||
sizeof(events)) == 0); | |||||
ATF_REQUIRE(!(events & PTRACE_LWP)); | |||||
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0); | |||||
/* Should get one event at exit. */ | |||||
wpid = waitpid(fpid, &status, 0); | |||||
ATF_REQUIRE(WIFEXITED(status)); | |||||
ATF_REQUIRE(WEXITSTATUS(status) == 0); | |||||
wpid = wait(&status); | |||||
ATF_REQUIRE(wpid == -1); | |||||
ATF_REQUIRE(errno == ECHILD); | |||||
} | |||||
ATF_TP_ADD_TCS(tp) | ATF_TP_ADD_TCS(tp) | ||||
{ | { | ||||
ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); | ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_trace_me); | ||||
ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); | ATF_TP_ADD_TC(tp, ptrace__parent_wait_after_attach); | ||||
ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); | ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_child_debugger); | ||||
ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); | ATF_TP_ADD_TC(tp, ptrace__parent_sees_exit_after_unrelated_debugger); | ||||
ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); | ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached); | ||||
ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); | ATF_TP_ADD_TC(tp, ptrace__follow_fork_child_detached); | ||||
ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); | ATF_TP_ADD_TC(tp, ptrace__follow_fork_parent_detached); | ||||
ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); | ATF_TP_ADD_TC(tp, ptrace__follow_fork_both_attached_unrelated_debugger); | ||||
ATF_TP_ADD_TC(tp, | ATF_TP_ADD_TC(tp, | ||||
ptrace__follow_fork_child_detached_unrelated_debugger); | ptrace__follow_fork_child_detached_unrelated_debugger); | ||||
ATF_TP_ADD_TC(tp, | ATF_TP_ADD_TC(tp, | ||||
ptrace__follow_fork_parent_detached_unrelated_debugger); | ptrace__follow_fork_parent_detached_unrelated_debugger); | ||||
ATF_TP_ADD_TC(tp, ptrace__getppid); | ATF_TP_ADD_TC(tp, ptrace__getppid); | ||||
ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); | ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_fork); | ||||
ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); | ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_vfork); | ||||
ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); | ATF_TP_ADD_TC(tp, ptrace__new_child_pl_syscall_code_thread); | ||||
ATF_TP_ADD_TC(tp, ptrace__lwp_events); | ATF_TP_ADD_TC(tp, ptrace__lwp_events); | ||||
ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); | ATF_TP_ADD_TC(tp, ptrace__lwp_events_exec); | ||||
ATF_TP_ADD_TC(tp, ptrace__siginfo); | ATF_TP_ADD_TC(tp, ptrace__siginfo); | ||||
ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_disable); | |||||
ATF_TP_ADD_TC(tp, ptrace__ptrace_exec_enable); | |||||
ATF_TP_ADD_TC(tp, ptrace__event_mask); | |||||
return (atf_no_error()); | return (atf_no_error()); | ||||
} | } |