Add two tests for TRAP_* signal codes for SIGTRAP.
- ptrace__breakpoint_siginfo tests that a SIGTRAP for a software breakpoint in userland triggers a SIGTRAP with a signal code of TRAP_BRKPT. - ptrace__step_siginfo tests that a SIGTRAP reported for a step after stepping via PT_STEP or PT_SETSTEP has a signal code of TRAP_TRACE.
This commit is contained in:
parent
bd061c3998
commit
643ce7de72
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332908
@ -3488,6 +3488,110 @@ ATF_TC_BODY(ptrace__PT_STEP_with_signal, tc)
|
||||
ATF_REQUIRE(errno == ECHILD);
|
||||
}
|
||||
|
||||
#ifdef HAVE_BREAKPOINT
|
||||
/*
|
||||
* Verify that a SIGTRAP event with the TRAP_BRKPT code is reported
|
||||
* for a breakpoint trap.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(ptrace__breakpoint_siginfo);
|
||||
ATF_TC_BODY(ptrace__breakpoint_siginfo, tc)
|
||||
{
|
||||
struct ptrace_lwpinfo pl;
|
||||
pid_t fpid, wpid;
|
||||
int status;
|
||||
|
||||
ATF_REQUIRE((fpid = fork()) != -1);
|
||||
if (fpid == 0) {
|
||||
trace_me();
|
||||
breakpoint();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Continue the child ignoring the SIGSTOP. */
|
||||
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1, 0) == 0);
|
||||
|
||||
/* The second wait() should report hitting the breakpoint. */
|
||||
wpid = waitpid(fpid, &status, 0);
|
||||
ATF_REQUIRE(wpid == fpid);
|
||||
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_SI) != 0);
|
||||
ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP);
|
||||
ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_BRKPT);
|
||||
|
||||
/* Kill the child process. */
|
||||
ATF_REQUIRE(ptrace(PT_KILL, fpid, 0, 0) == 0);
|
||||
|
||||
/* The last wait() should report the SIGKILL. */
|
||||
wpid = waitpid(fpid, &status, 0);
|
||||
ATF_REQUIRE(wpid == fpid);
|
||||
ATF_REQUIRE(WIFSIGNALED(status));
|
||||
ATF_REQUIRE(WTERMSIG(status) == SIGKILL);
|
||||
|
||||
wpid = wait(&status);
|
||||
ATF_REQUIRE(wpid == -1);
|
||||
ATF_REQUIRE(errno == ECHILD);
|
||||
}
|
||||
#endif /* HAVE_BREAKPOINT */
|
||||
|
||||
/*
|
||||
* Verify that a SIGTRAP event with the TRAP_TRACE code is reported
|
||||
* for a single-step trap from PT_STEP.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(ptrace__step_siginfo);
|
||||
ATF_TC_BODY(ptrace__step_siginfo, tc)
|
||||
{
|
||||
struct ptrace_lwpinfo pl;
|
||||
pid_t fpid, wpid;
|
||||
int status;
|
||||
|
||||
ATF_REQUIRE((fpid = fork()) != -1);
|
||||
if (fpid == 0) {
|
||||
trace_me();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Step the child ignoring the SIGSTOP. */
|
||||
ATF_REQUIRE(ptrace(PT_STEP, fpid, (caddr_t)1, 0) == 0);
|
||||
|
||||
/* The second wait() should report a single-step trap. */
|
||||
wpid = waitpid(fpid, &status, 0);
|
||||
ATF_REQUIRE(wpid == fpid);
|
||||
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_SI) != 0);
|
||||
ATF_REQUIRE(pl.pl_siginfo.si_signo == SIGTRAP);
|
||||
ATF_REQUIRE(pl.pl_siginfo.si_code == TRAP_TRACE);
|
||||
|
||||
/* Continue the child process. */
|
||||
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) == 1);
|
||||
|
||||
wpid = wait(&status);
|
||||
ATF_REQUIRE(wpid == -1);
|
||||
ATF_REQUIRE(errno == ECHILD);
|
||||
}
|
||||
|
||||
#if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK)
|
||||
static void *
|
||||
continue_thread(void *arg __unused)
|
||||
@ -3713,6 +3817,10 @@ ATF_TP_ADD_TCS(tp)
|
||||
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_STEP_with_signal);
|
||||
#ifdef HAVE_BREAKPOINT
|
||||
ATF_TP_ADD_TC(tp, ptrace__breakpoint_siginfo);
|
||||
#endif
|
||||
ATF_TP_ADD_TC(tp, ptrace__step_siginfo);
|
||||
#if defined(HAVE_BREAKPOINT) && defined(SKIP_BREAK)
|
||||
ATF_TP_ADD_TC(tp, ptrace__PT_CONTINUE_different_thread);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user