Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/kernel Add regs[12345] in t_ptrace_wait{, 3, 4, 6, id, pid}
details: https://anonhg.NetBSD.org/src/rev/babd77f77186
branches: trunk
changeset: 349098:babd77f77186
user: kamil <kamil%NetBSD.org@localhost>
date: Thu Nov 24 04:08:37 2016 +0000
description:
Add regs[12345] in t_ptrace_wait{,3,4,6,id,pid}
Add new ATF tests for the general purpose register calls.
These tests require platforms to export all of the following macros:
- PT_GETREGS
- PT_SETREGS
- PTRACE_REG_PC
- PTRACE_REG_SET_PC
- PTRACE_REG_SP
- PTRACE_REG_INTRV
This has been done for the sake of C preprocessor magic simplicity.
There are ports without covering all of the above symbols -- skip them.
Added tests
===========
regs1:
Verify plain PT_GETREGS call without further steps
regs2:
Verify plain PT_GETREGS call and retrieve PC
regs3:
Verify plain PT_GETREGS call and retrieve SP
regs4:
Verify plain PT_GETREGS call and retrieve INTRV
regs5:
Verify PT_GETREGS and PT_SETREGS calls without changing regs
Sponsored by <The NetBSD Foundation>
diffstat:
tests/kernel/t_ptrace_wait.c | 313 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 311 insertions(+), 2 deletions(-)
diffs (truncated from 360 to 300 lines):
diff -r eacc7dbeedd6 -r babd77f77186 tests/kernel/t_ptrace_wait.c
--- a/tests/kernel/t_ptrace_wait.c Thu Nov 24 03:59:36 2016 +0000
+++ b/tests/kernel/t_ptrace_wait.c Thu Nov 24 04:08:37 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ptrace_wait.c,v 1.27 2016/11/23 23:30:50 kamil Exp $ */
+/* $NetBSD: t_ptrace_wait.c,v 1.28 2016/11/24 04:08:37 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.27 2016/11/23 23:30:50 kamil Exp $");
+__RCSID("$NetBSD: t_ptrace_wait.c,v 1.28 2016/11/24 04:08:37 kamil Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -36,6 +36,7 @@
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/wait.h>
+#include <machine/reg.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
@@ -181,6 +182,21 @@
} while (/*CONSTCOND*/0)
/*
+ * Simplify logic for functions using general purpose registers add HAVE_GPREGS
+ *
+ * For platforms that do not implement all needed calls for simplicity assume
+ * that they are unsupported at all.
+ */
+#if defined(PT_GETREGS) \
+ && defined(PT_SETREGS) \
+ && defined(PTRACE_REG_PC) \
+ && defined(PTRACE_REG_SET_PC) \
+ && defined(PTRACE_REG_SP) \
+ && defined(PTRACE_REG_INTRV)
+#define HAVE_GPREGS
+#endif
+
+/*
* If waitid(2) returns because one or more processes have a state change to
* report, 0 is returned. If an error is detected, a value of -1 is returned
* and errno is set to indicate the error. If WNOHANG is specified and there
@@ -4042,12 +4058,299 @@
TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
}
+#if defined(HAVE_GPREGS)
+ATF_TC(regs1);
+ATF_TC_HEAD(regs1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify plain PT_GETREGS call without further steps");
+}
+
+ATF_TC_BODY(regs1, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct reg r;
+
+ 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);
+
+ 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("Call GETREGS for the child process\n");
+ ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 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 child\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\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+#endif
+
+#if defined(HAVE_GPREGS)
+ATF_TC(regs2);
+ATF_TC_HEAD(regs2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify plain PT_GETREGS call and retrieve PC");
+}
+
+ATF_TC_BODY(regs2, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct reg r;
+
+ 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);
+
+ 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("Call GETREGS for the child process\n");
+ ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
+
+ printf("Retrieved PC=%" PRIxREGISTER "\n", PTRACE_REG_PC(&r));
+
+ 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\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\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+#endif
+
+#if defined(HAVE_GPREGS)
+ATF_TC(regs3);
+ATF_TC_HEAD(regs3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify plain PT_GETREGS call and retrieve SP");
+}
+
+ATF_TC_BODY(regs3, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct reg r;
+
+ 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);
+
+ 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("Call GETREGS for the child process\n");
+ ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
+
+ printf("Retrieved SP=%" PRIxREGISTER "\n", PTRACE_REG_SP(&r));
+
+ 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\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\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+#endif
+
+#if defined(HAVE_GPREGS)
+ATF_TC(regs4);
+ATF_TC_HEAD(regs4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify plain PT_GETREGS call and retrieve INTRV");
+}
+
+ATF_TC_BODY(regs4, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct reg r;
+
+ 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);
+
+ 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("Call GETREGS for the child process\n");
+ ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
+
+ printf("Retrieved INTRV=%" PRIxREGISTER "\n", PTRACE_REG_INTRV(&r));
+
+ 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\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\n", TWAIT_FNAME);
+ TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
+}
+#endif
+
+#if defined(HAVE_GPREGS)
+ATF_TC(regs5);
+ATF_TC_HEAD(regs5, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify PT_GETREGS and PT_SETREGS calls without changing regs");
+}
+
+ATF_TC_BODY(regs5, tc)
+{
+ const int exitval = 5;
+ const int sigval = SIGSTOP;
+ pid_t child, wpid;
+#if defined(TWAIT_HAVE_STATUS)
+ int status;
+#endif
+ struct reg r;
+
+ 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);
Home |
Main Index |
Thread Index |
Old Index