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 t_ptrace_attach3 in t_ptrace
details: https://anonhg.NetBSD.org/src/rev/ae98d4cda53a
branches: trunk
changeset: 348849:ae98d4cda53a
user: kamil <kamil%NetBSD.org@localhost>
date: Fri Nov 11 12:01:14 2016 +0000
description:
Add new test t_ptrace_attach3 in t_ptrace
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>.
diffstat:
tests/kernel/t_ptrace_wait.c | 87 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 85 insertions(+), 2 deletions(-)
diffs (115 lines):
diff -r aa939f27c214 -r ae98d4cda53a tests/kernel/t_ptrace_wait.c
--- a/tests/kernel/t_ptrace_wait.c Fri Nov 11 11:34:51 2016 +0000
+++ b/tests/kernel/t_ptrace_wait.c Fri Nov 11 12:01:14 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ptrace_wait.c,v 1.2 2016/11/10 18:33:52 kamil Exp $ */
+/* $NetBSD: t_ptrace_wait.c,v 1.3 2016/11/11 12:01:14 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.2 2016/11/10 18:33:52 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.3 2016/11/11 12:01:14 kamil Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -808,6 +808,88 @@
}
#endif
+ATF_TC(attach3);
+ATF_TC_HEAD(attach3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Assert that tracer parent can PT_ATTACH to its child");
+}
+
+ATF_TC_BODY(attach3, tc)
+{
+ int fds_totracee[2], fds_fromtracee[2];
+ int rv;
+ const int exitval_tracee = 5;
+ pid_t tracee, wpid;
+ uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+
+ /* PT_ATTACH from a parent is unreliable */
+ atf_tc_expect_fail("PR kern/51621");
+
+ printf("Spawn tracee\n");
+ ATF_REQUIRE(pipe(fds_totracee) == 0);
+ ATF_REQUIRE(pipe(fds_fromtracee) == 0);
+ tracee = atf_utils_fork();
+ if (tracee == 0) {
+ FORKEE_ASSERT(close(fds_totracee[1]) == 0);
+ FORKEE_ASSERT(close(fds_fromtracee[0]) == 0);
+
+ /* Wait for message from the parent */
+ rv = read(fds_totracee[0], &msg, sizeof(msg));
+ FORKEE_ASSERT(rv == sizeof(msg));
+
+ printf("Parent should now attach to tracee\n");
+
+ /* Wait for message from the parent */
+ rv = write(fds_fromtracee[1], &msg, sizeof(msg));
+ FORKEE_ASSERT(rv == sizeof(msg));
+
+ _exit(exitval_tracee);
+ }
+ ATF_REQUIRE(close(fds_totracee[0]) == 0);
+ ATF_REQUIRE(close(fds_fromtracee[1]) == 0);
+
+ printf("Wait for the tracee to become ready\n");
+ rv = write(fds_totracee[1], &msg, sizeof(msg));
+ ATF_REQUIRE(rv == sizeof(msg));
+
+ printf("Before calling PT_ATTACH for tracee %d\n", tracee);
+ ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1);
+
+ printf("Wait for the stopped tracee process with %s()\n",
+ TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(
+ wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
+
+ validate_status_stopped(status, SIGTRAP);
+
+ printf("Resume tracee with PT_CONTINUE\n");
+ ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
+
+ printf("Let the tracee exit now\n");
+ rv = read(fds_fromtracee[0], &msg, sizeof(msg));
+ ATF_REQUIRE(rv == sizeof(msg));
+
+ printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_SUCCESS(
+ wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
+
+ validate_status_exited(status, exitval_tracee);
+
+ printf("Before calling %s() for tracee\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD,
+ wpid = TWAIT_GENERIC(tracee, &status, 0));
+
+ printf("fds_fromtracee is no longer needed - close it\n");
+ ATF_REQUIRE(close(fds_fromtracee[0]) == 0);
+
+ printf("fds_totracee is no longer needed - close it\n");
+ ATF_REQUIRE(close(fds_totracee[1]) == 0);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, traceme1);
@@ -819,6 +901,7 @@
ATF_TP_ADD_TC(tp, attach1);
ATF_TP_ADD_TC(tp, attach2);
#endif
+ ATF_TP_ADD_TC(tp, attach3);
#if defined(TWAIT_WAIT4TYPE)
/* TODO */
Home |
Main Index |
Thread Index |
Old Index