Changeset View
Changeset View
Standalone View
Standalone View
tests/sys/kern/ptrace_test.c
Show All 22 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/cpuset.h> | #include <sys/cpuset.h> | ||||
#include <sys/elf.h> | |||||
#include <sys/event.h> | #include <sys/event.h> | ||||
#include <sys/file.h> | #include <sys/file.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/procctl.h> | #include <sys/procctl.h> | ||||
#include <sys/procdesc.h> | #include <sys/procdesc.h> | ||||
#define _WANT_MIPS_REGNUM | #define _WANT_MIPS_REGNUM | ||||
#include <sys/ptrace.h> | #include <sys/ptrace.h> | ||||
#include <sys/procfs.h> | |||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/runq.h> | #include <sys/runq.h> | ||||
#include <sys/syscall.h> | #include <sys/syscall.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/user.h> | #include <sys/user.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
▲ Show 20 Lines • Show All 3,145 Lines • ▼ Show 20 Lines | ATF_TC_BODY(ptrace__PT_CONTINUE_with_signal_thread_sigmask, tc) | ||||
ATF_REQUIRE(WIFEXITED(status)); | ATF_REQUIRE(WIFEXITED(status)); | ||||
REQUIRE_EQ(WEXITSTATUS(status), 1); | REQUIRE_EQ(WEXITSTATUS(status), 1); | ||||
wpid = wait(&status); | wpid = wait(&status); | ||||
REQUIRE_EQ(wpid, -1); | REQUIRE_EQ(wpid, -1); | ||||
REQUIRE_EQ(errno, ECHILD); | REQUIRE_EQ(errno, ECHILD); | ||||
} | } | ||||
/* | |||||
* Verify that PT_GETREGSET returns registers and PT_SETREGSET updates them. | |||||
*/ | |||||
ATF_TC_WITHOUT_HEAD(ptrace__PT_REGSET); | |||||
ATF_TC_BODY(ptrace__PT_REGSET, tc) | |||||
{ | |||||
struct prstatus prstatus; | |||||
struct iovec vec; | |||||
pid_t child, wpid; | |||||
int status; | |||||
ATF_REQUIRE((child = fork()) != -1); | |||||
if (child == 0) { | |||||
trace_me(); | |||||
exit(1); | |||||
} | |||||
/* The first wait() should report the stop from SIGSTOP. */ | |||||
wpid = waitpid(child, &status, 0); | |||||
REQUIRE_EQ(wpid, child); | |||||
ATF_REQUIRE(WIFSTOPPED(status)); | |||||
REQUIRE_EQ(WSTOPSIG(status), SIGSTOP); | |||||
/* Check the size is returned when vec.iov_base is NULL */ | |||||
vec.iov_base = NULL; | |||||
vec.iov_len = 0; | |||||
ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != | |||||
-1); | |||||
ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); | |||||
ATF_REQUIRE(vec.iov_base == NULL); | |||||
/* Read the registers. */ | |||||
memset(&prstatus, 0, sizeof(prstatus)); | |||||
vec.iov_base = &prstatus; | |||||
ATF_REQUIRE(ptrace(PT_GETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != | |||||
-1); | |||||
ATF_REQUIRE(vec.iov_len == sizeof(prstatus)); | |||||
ATF_REQUIRE(vec.iov_base == &prstatus); | |||||
ATF_REQUIRE(prstatus.pr_statussz == sizeof(prstatus)); | |||||
/* Write the registers back. */ | |||||
ATF_REQUIRE(ptrace(PT_SETREGSET, wpid, (caddr_t)&vec, NT_PRSTATUS) != | |||||
-1); | |||||
REQUIRE_EQ(ptrace(PT_CONTINUE, child, (caddr_t)1, 0), 0); | |||||
/* The second wait() should report the exit status. */ | |||||
wpid = waitpid(child, &status, 0); | |||||
REQUIRE_EQ(wpid, child); | |||||
ATF_REQUIRE(WIFEXITED(status)); | |||||
REQUIRE_EQ(WEXITSTATUS(status), 1); | |||||
/* The child should no longer exist. */ | |||||
wpid = waitpid(child, &status, 0); | |||||
REQUIRE_EQ(wpid, -1); | |||||
REQUIRE_EQ(errno, ECHILD); | |||||
} | |||||
static void * | static void * | ||||
raise_sigstop_thread(void *arg __unused) | raise_sigstop_thread(void *arg __unused) | ||||
{ | { | ||||
raise(SIGSTOP); | raise(SIGSTOP); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,090 Lines • ▼ Show 20 Lines | #endif | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_masked_full_sigqueue); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_change_sig); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigtrap_system_call_entry); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_mix); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_kqueue); | ||||
ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); | ATF_TP_ADD_TC(tp, ptrace__killed_with_sigmask); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_sigmask); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); | ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_with_signal_thread_sigmask); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_REGSET); | |||||
ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); | ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop1); | ||||
ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); | ATF_TP_ADD_TC(tp, ptrace__parent_terminate_with_pending_sigstop2); | ||||
ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); | ATF_TP_ADD_TC(tp, ptrace__event_mask_sigkill_discard); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); | ATF_TP_ADD_TC(tp, ptrace__PT_ATTACH_with_SBDRY_thread); | ||||
ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); | ATF_TP_ADD_TC(tp, ptrace__PT_STEP_with_signal); | ||||
#ifdef HAVE_BREAKPOINT | #ifdef HAVE_BREAKPOINT | ||||
ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); | ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo); | ||||
#endif | #endif | ||||
Show All 12 Lines |