Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/kernel Add new test fork1 in t_ptrace_wait{4, 6, id, pid}



details:   https://anonhg.NetBSD.org/src/rev/b204283cc031
branches:  trunk
changeset: 348916:b204283cc031
user:      kamil <kamil%NetBSD.org@localhost>
date:      Tue Nov 15 19:30:28 2016 +0000

description:
Add new test fork1 in t_ptrace_wait{4,6,id,pid}

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>.

diffstat:

 tests/kernel/t_ptrace_wait.c |  130 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 128 insertions(+), 2 deletions(-)

diffs (157 lines):

diff -r 10567554cde3 -r b204283cc031 tests/kernel/t_ptrace_wait.c
--- a/tests/kernel/t_ptrace_wait.c      Tue Nov 15 17:01:12 2016 +0000
+++ b/tests/kernel/t_ptrace_wait.c      Tue Nov 15 19:30:28 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: t_ptrace_wait.c,v 1.15 2016/11/15 02:53:32 kamil Exp $ */
+/*     $NetBSD: t_ptrace_wait.c,v 1.16 2016/11/15 19:30:28 kamil Exp $ */
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace_wait.c,v 1.15 2016/11/15 02:53:32 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.16 2016/11/15 19:30:28 kamil Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -1598,6 +1598,130 @@
 }
 
 #if defined(TWAIT_HAVE_PID)
+ATF_TC(fork1);
+ATF_TC_HEAD(fork1, tc)
+{
+       atf_tc_set_md_var(tc, "descr",
+           "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK "
+           "set to PTRACE_FORK");
+}
+
+ATF_TC_BODY(fork1, tc)
+{
+       const int exitval = 5;
+       const int exitval2 = 15;
+       const int sigval = SIGSTOP;
+       pid_t child, child2, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+       int status;
+#endif
+       ptrace_state_t state;
+       const int slen = sizeof(state);
+       ptrace_event_t event;
+       const int elen = sizeof(event);
+
+       printf("Before forking process PID=%d\n", getpid());
+       child = atf_utils_fork();
+       if (child == 0) {
+               printf("Before calling PT_TRACE_ME from child %d\n", getpid());
+               FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
+
+               printf("Before raising %s from child\n", strsignal(sigval));
+               FORKEE_ASSERT(raise(sigval) == 0);
+
+               FORKEE_ASSERT((child2 = fork()) != 1);
+
+               if (child2 == 0)
+                       _exit(exitval2);
+
+               FORKEE_REQUIRE_SUCCESS
+                   (wpid = TWAIT_GENERIC(child2, &status, 0), child2);
+
+               forkee_status_exited(status, exitval2);
+
+               printf("Before exiting of the child process\n");
+               _exit(exitval);
+       }
+       printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
+
+       printf("Before calling %s() for the child\n", TWAIT_FNAME);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+       validate_status_stopped(status, sigval);
+
+       printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child);
+       event.pe_set_event = PTRACE_FORK;
+       ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
+
+       printf("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("Before calling %s() for the child %d\n", TWAIT_FNAME, child);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+       validate_status_stopped(status, SIGTRAP);
+
+       ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
+       ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
+
+       child2 = state.pe_other_pid;
+       printf("Reported PTRACE_FORK event with forkee %d\n", child2);
+
+       printf("Before calling %s() for the forkee %d of the child %d\n",
+           TWAIT_FNAME, child2, child);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
+           child2);
+
+       validate_status_stopped(status, SIGTRAP);
+
+       ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1);
+       ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK);
+       ATF_REQUIRE_EQ(state.pe_other_pid, child);
+
+       printf("Before resuming the forkee process where it left off and "
+           "without signal to be sent\n");
+       ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1);
+
+       printf("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("Before calling %s() for the forkee - expected exited\n",
+           TWAIT_FNAME);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0),
+           child2);
+
+       validate_status_exited(status, exitval2);
+
+       printf("Before calling %s() for the forkee - expected no process\n",
+           TWAIT_FNAME);
+       TWAIT_REQUIRE_FAILURE(ECHILD,
+           wpid = TWAIT_GENERIC(child2, &status, 0));
+
+       printf("Before calling %s() for the child - expected stopped "
+           "SIGCHLD\n", TWAIT_FNAME);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+       validate_status_stopped(status, SIGCHLD);
+
+       printf("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("Before calling %s() for the child - expected exited\n",
+           TWAIT_FNAME);
+       TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
+
+       validate_status_exited(status, exitval);
+
+       printf("Before calling %s() for the child - expected no process\n",
+           TWAIT_FNAME);
+       TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+#endif
+
+#if defined(TWAIT_HAVE_PID)
 #define ATF_TP_ADD_TC_HAVE_PID(a,b)    ATF_TP_ADD_TC(a,b)
 #else
 #define ATF_TP_ADD_TC_HAVE_PID(a,b)
@@ -1623,5 +1747,7 @@
        ATF_TP_ADD_TC(tp, eventmask1);
        ATF_TP_ADD_TC(tp, eventmask2);
 
+       ATF_TP_ADD_TC_HAVE_PID(tp, fork1);
+
        return atf_no_error();
 }



Home | Main Index | Thread Index | Old Index