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-case "traceme2" in t_ptrace
details: https://anonhg.NetBSD.org/src/rev/c93319831f92
branches: trunk
changeset: 348690:c93319831f92
user: kamil <kamil%NetBSD.org@localhost>
date: Wed Nov 02 22:18:04 2016 +0000
description:
Add new test-case "traceme2" in t_ptrace
This test is a clone of traceme2 with ptrace(2) calling PT_CONTINUE
with signal to be passed to the child: SIGINT. traceme1 sends no signals.
Sponsored by <The NetBSD Foundation>.
diffstat:
tests/kernel/t_ptrace.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 133 insertions(+), 2 deletions(-)
diffs (159 lines):
diff -r 0ccb00498b6d -r c93319831f92 tests/kernel/t_ptrace.c
--- a/tests/kernel/t_ptrace.c Wed Nov 02 17:19:53 2016 +0000
+++ b/tests/kernel/t_ptrace.c Wed Nov 02 22:18:04 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ptrace.c,v 1.1 2016/11/02 12:51:22 kamil Exp $ */
+/* $NetBSD: t_ptrace.c,v 1.2 2016/11/02 22:18:04 kamil Exp $ */
/*-
* Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_ptrace.c,v 1.1 2016/11/02 12:51:22 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace.c,v 1.2 2016/11/02 22:18:04 kamil Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -144,9 +144,140 @@
}
+ATF_TC(traceme2);
+ATF_TC_HEAD(traceme2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify SIGSTOP followed by _exit(2) in a child");
+}
+
+static int traceme2_catched = 0;
+
+static void
+traceme2_sighandler(int sig)
+{
+ if (sig != SIGINT)
+ errx(EXIT_FAILURE, "sighandler: Unexpected signal received: "
+ "%s, expected SIGINT", sys_signame[sig]);
+
+ ++traceme2_catched;
+}
+
+ATF_TC_BODY(traceme2, tc)
+{
+ int status;
+ const int exitval = 5;
+ const int sigval = SIGSTOP, sigsent = SIGINT;
+ pid_t child, wpid;
+ struct sigaction sa;
+
+ printf("1: Before forking process PID=%d\n", getpid());
+ ATF_REQUIRE((child = fork()) != -1);
+ if (child == 0) {
+ /* printf(3) messages from a child aren't intercepted by ATF */
+ /* "2: Child process PID=%d\n", getpid() */
+
+ /* "2: Before calling ptrace(PT_TRACE_ME, ...)\n" */
+ if (ptrace(PT_TRACE_ME, 0, NULL, 0) == -1) {
+ /* XXX: Is it safe to use ATF functions in a child? */
+ err(EXIT_FAILURE, "2: ptrace(2) call failed with "
+ "status %s", sys_errlist[errno]);
+ }
+
+ /* "2: Setup sigaction(2) in the child" */
+ sa.sa_handler = traceme2_sighandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+
+ if (sigaction(sigsent, &sa, NULL) == -1)
+ err(EXIT_FAILURE, "2: sigaction(2) call failed with "
+ "status %s", sys_errlist[errno]);
+
+ /* "2: Before raising SIGSTOP\n" */
+ raise(sigval);
+
+ if (traceme2_catched != 1)
+ errx(EXIT_FAILURE, "2: signal handler not called? "
+ "traceme2_catched (equal to %d) != 1",
+ traceme2_catched);
+
+ /* "2: Before calling _exit(%d)\n", exitval */
+ _exit(exitval);
+ } else {
+ printf("1: Parent process PID=%d, child's PID=%d\n", getpid(),
+ child);
+
+ printf("1: Before calling waitpid() for the child\n");
+ wpid = waitpid(child, &status, 0);
+
+ printf("1: Validating child's PID (expected %d, got %d)\n",
+ child, wpid);
+ ATF_REQUIRE(child == wpid);
+
+ printf("1: Ensuring that the child has not been exited\n");
+ ATF_REQUIRE(!WIFEXITED(status));
+
+ printf("1: Ensuring that the child has not been continued\n");
+ ATF_REQUIRE(!WIFCONTINUED(status));
+
+ printf("1: Ensuring that the child has not been terminated "
+ "with a signal\n");
+ ATF_REQUIRE(!WIFSIGNALED(status));
+
+ printf("1: Ensuring that the child has been stopped\n");
+ ATF_REQUIRE(WIFSTOPPED(status));
+
+ printf("1: Verifying that he child has been stopped with the"
+ " %s signal (received %s)\n", sys_signame[sigval],
+ sys_signame[WSTOPSIG(status)]);
+ ATF_REQUIRE(WSTOPSIG(status) == sigval);
+
+ printf("1: Before resuming the child process where it left "
+ "off and with signal %s to be sent\n",
+ sys_signame[sigsent]);
+ ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent)
+ != -1);
+
+ printf("1: Before calling waitpid() for the child\n");
+ wpid = waitpid(child, &status, 0);
+
+ printf("1: Validating that child's PID is still there\n");
+ ATF_REQUIRE(wpid == child);
+
+ printf("1: Ensuring that the child has been exited\n");
+ ATF_REQUIRE(WIFEXITED(status));
+
+ printf("1: Ensuring that the child has not been continued\n");
+ ATF_REQUIRE(!WIFCONTINUED(status));
+
+ printf("1: Ensuring that the child has not been terminated "
+ "with a signal\n");
+ ATF_REQUIRE(!WIFSIGNALED(status));
+
+ printf("1: Ensuring that the child has not been stopped\n");
+ ATF_REQUIRE(!WIFSTOPPED(status));
+
+ printf("1: Verifying that he child has exited with the "
+ "%d status (received %d)\n", exitval, WEXITSTATUS(status));
+ ATF_REQUIRE(WEXITSTATUS(status) == exitval);
+
+ printf("1: Before calling waitpid() for the exited child\n");
+ wpid = waitpid(child, &status, 0);
+
+ printf("1: Validating that child's PID no longer exists\n");
+ ATF_REQUIRE(wpid == -1);
+
+ printf("1: Validating that errno is set to %s (got %s)\n",
+ sys_errlist[ECHILD], sys_errlist[errno]);
+ ATF_REQUIRE(errno == ECHILD);
+ }
+
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, traceme1);
+ ATF_TP_ADD_TC(tp, traceme2);
return atf_no_error();
}
Home |
Main Index |
Thread Index |
Old Index