Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/kernel Extend ATF tests in t_trapsignal.s...
details: https://anonhg.NetBSD.org/src/rev/8df80804ba58
branches: trunk
changeset: 319221:8df80804ba58
user: kamil <kamil%NetBSD.org@localhost>
date: Tue May 22 04:32:56 2018 +0000
description:
Extend ATF tests in t_trapsignal.sh to verify software breakpoint traps
There are at least four types of SIGTRAP events:
- software/hardware single step (trace trap)
- software breakpoint
- hardware breakpoint/watchpoint
- kernel event (exec, fork, vfork, vfork-done, lwp-create, lwp-exit)
A program can execute software breakpoint without the context of being
traced and this is a regular crash signal emitting SIGTRAP (TRAP_BRKPT).
Rename original trap_* tests (trap_simple, trap_handle, trap_mask,
trap_handle_recurse and trap_ignore) to segv_* tests and restrict them for
SIGSEGV.
Add new tests: trap_* testing the same scenarios as segv_ ones, however
verifying the software breakpoint trap (SIGTRAP).
Keep the original name of h_segv.c, and extend it for software breakpoint
events.
The purpose of these tests is to verify SIGTRAP kernel paths without the
ptrace(2) context.
All tests pass.
Sponsored by <The NetBSD Foundation>
diffstat:
tests/kernel/h_segv.c | 57 +++++++++++++++++----
tests/kernel/t_trapsignal.sh | 110 +++++++++++++++++++++++++++++++++++-------
2 files changed, 138 insertions(+), 29 deletions(-)
diffs (truncated from 303 to 300 lines):
diff -r bea691e1dbcd -r 8df80804ba58 tests/kernel/h_segv.c
--- a/tests/kernel/h_segv.c Tue May 22 03:07:50 2018 +0000
+++ b/tests/kernel/h_segv.c Tue May 22 04:32:56 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: h_segv.c,v 1.3 2018/05/21 08:49:03 kamil Exp $ */
+/* $NetBSD: h_segv.c,v 1.4 2018/05/22 04:32:56 kamil Exp $ */
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: h_segv.c,v 1.3 2018/05/21 08:49:03 kamil Exp $");
+__RCSID("$NetBSD: h_segv.c,v 1.4 2018/05/22 04:32:56 kamil Exp $");
+#include <sys/types.h>
+#include <sys/ptrace.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -57,21 +59,41 @@
{ "ignore", F_IGNORE }
};
+static int sig;
+static struct {
+ const char *n;
+ int v;
+} sn[] = {
+ { "segv", SIGSEGV },
+ { "trap", SIGTRAP }
+};
+
static void
foo(int s)
{
char buf[64];
int i = snprintf(buf, sizeof(buf), "got %d\n", s);
write(2, buf, i);
- if (flags & F_RECURSE)
- *p = 0;
+ if (flags & F_RECURSE) {
+ if (sig == SIGSEGV)
+ *p = 0;
+ else if (sig == SIGTRAP) {
+#ifdef PTRACE_BREAKPOINT_ASM
+ PTRACE_BREAKPOINT_ASM;
+#else
+ /* port me */
+#endif
+ }
+ }
exit(EXIT_SUCCESS);
}
static __dead void
usage(void)
{
- fprintf(stderr, "Usage: %s recurse|mask|handle ...\n", getprogname());
+ const char *pname = getprogname();
+
+ fprintf(stderr, "Usage: %s recurse|mask|handle|ignore ...\n", pname);
exit(EXIT_FAILURE);
}
@@ -83,16 +105,21 @@
for (int i = 1; i < argc; i++) {
size_t j;
- for (j = 0; j < __arraycount(nv); j++)
+ for (j = 0; j < __arraycount(nv); j++) {
if (strcmp(nv[j].n, argv[i]) == 0) {
flags |= nv[j].v;
break;
}
+ if (strcmp(sn[j].n, argv[i]) == 0) {
+ sig = sn[j].v;
+ break;
+ }
+ }
if (j == __arraycount(nv))
usage();
}
- if (flags == 0)
+ if (flags == 0 || sig == 0)
usage();
if (flags & F_HANDLE) {
@@ -101,7 +128,7 @@
sa.sa_flags = SA_RESTART;
sa.sa_handler = foo;
sigemptyset(&sa.sa_mask);
- if (sigaction(SIGSEGV, &sa, NULL) == -1)
+ if (sigaction(sig, &sa, NULL) == -1)
err(EXIT_FAILURE, "sigaction");
}
@@ -109,7 +136,7 @@
sigset_t set;
sigemptyset(&set);
- sigaddset(&set, SIGSEGV);
+ sigaddset(&set, sig);
if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
err(EXIT_FAILURE, "sigprocmask");
}
@@ -120,10 +147,18 @@
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
- if (sigaction(SIGSEGV, &sa, NULL) == -1)
+ if (sigaction(sig, &sa, NULL) == -1)
err(EXIT_FAILURE, "sigaction");
}
- *p = 1;
+ if (sig == SIGSEGV)
+ *p = 1;
+ else if (sig == SIGTRAP) {
+#ifdef PTRACE_BREAKPOINT_ASM
+ PTRACE_BREAKPOINT_ASM;
+#else
+ /* port me */
+#endif
+ }
return EXIT_SUCCESS;
}
diff -r bea691e1dbcd -r 8df80804ba58 tests/kernel/t_trapsignal.sh
--- a/tests/kernel/t_trapsignal.sh Tue May 22 03:07:50 2018 +0000
+++ b/tests/kernel/t_trapsignal.sh Tue May 22 04:32:56 2018 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: t_trapsignal.sh,v 1.2 2018/05/21 08:49:03 kamil Exp $
+# $NetBSD: t_trapsignal.sh,v 1.3 2018/05/22 04:32:56 kamil Exp $
#
# Copyright (c) 2017 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -29,60 +29,128 @@
#
HELPER=$(atf_get_srcdir)/h_segv
+atf_test_case segv_simple
+segv_simple()
+{
+ atf_set "descr" "Test unhandled SIGSEGV with the right exit code"
+}
+segv_simple_body()
+{
+ atf_check -s signal:11 -o "inline:" -e "inline:" \
+ ${HELPER} segv recurse
+}
+
+atf_test_case segv_handle
+segv_handle()
+{
+ atf_set "descr" "Test handled SIGSEGV traps call the signal handler"
+}
+segv_handle_body()
+{
+ atf_check -s exit:0 -o "inline:" -e "inline:got 11\n" \
+ ${HELPER} segv handle
+}
+
+atf_test_case segv_mask
+segv_mask()
+{
+ atf_set "descr" "Test that masking SIGSEGV get reset"
+}
+segv_mask_body()
+{
+ atf_check -s signal:11 -o "inline:" -e "inline:" \
+ ${HELPER} segv mask
+}
+
+atf_test_case segv_handle_mask
+segv_handle_mask()
+{
+ atf_set "descr" "Test handled and masked SIGSEGV traps get reset"
+}
+segv_handle_mask_body()
+{
+ atf_check -s signal:11 -o "inline:" -e "inline:" \
+ ${HELPER} segv mask handle
+}
+
+atf_test_case segv_handle_recurse
+segv_handle_recurse()
+{
+ atf_set "descr" "Test that receiving SIGSEGV in the handler resets"
+}
+
+segv_handle_recurse_body()
+{
+ atf_check -s signal:11 -o "inline:" -e "inline:got 11\n" \
+ ${HELPER} segv handle recurse
+}
+
+atf_test_case segv_ignore
+segv_ignore()
+{
+ atf_set "descr" "Test ignored SIGSEGV trap with right exit code"
+}
+
+segv_ignore_body()
+{
+ atf_check -s signal:11 -o "inline:" -e "inline:" \
+ ${HELPER} segv ignore
+}
+
atf_test_case trap_simple
trap_simple()
{
- atf_set "descr" "Test unhandled traps exit with the right exit code"
+ atf_set "descr" "Test unhandled SIGTRAP with the right exit code"
}
trap_simple_body()
{
- atf_check -s signal:11 -o "inline:" -e "inline:" \
- ${HELPER} recurse
+ atf_check -s signal:5 -o "inline:" -e "inline:" \
+ ${HELPER} trap recurse
}
atf_test_case trap_handle
trap_handle()
{
- atf_set "descr" "Test handled traps call the signal handler"
+ atf_set "descr" "Test handled SIGTRAP traps call the signal handler"
}
trap_handle_body()
{
- atf_check -s exit:0 -o "inline:" -e "inline:got 11\n" \
- ${HELPER} handle
+ atf_check -s exit:0 -o "inline:" -e "inline:got 5\n" \
+ ${HELPER} trap handle
}
atf_test_case trap_mask
trap_mask()
{
- atf_set "descr" "Test that masking the trapped signal get reset"
+ atf_set "descr" "Test that masking the trapped SIGTRAP signal get reset"
}
trap_mask_body()
{
- atf_check -s signal:11 -o "inline:" -e "inline:" \
- ${HELPER} mask
+ atf_check -s signal:5 -o "inline:" -e "inline:" \
+ ${HELPER} trap mask
}
atf_test_case trap_handle_mask
trap_handle_mask()
{
- atf_set "descr" "Test handled and masked traps get reset"
+ atf_set "descr" "Test handled and masked SIGTRAP traps get reset"
}
trap_handle_mask_body()
{
- atf_check -s signal:11 -o "inline:" -e "inline:" \
- ${HELPER} mask handle
+ atf_check -s signal:5 -o "inline:" -e "inline:" \
+ ${HELPER} trap mask handle
}
atf_test_case trap_handle_recurse
trap_handle_recurse()
{
- atf_set "descr" "Test that receiving the trap in the handler resets"
+ atf_set "descr" "Test that receiving SIGTRAP in the handler resets"
}
trap_handle_recurse_body()
{
- atf_check -s signal:11 -o "inline:" -e "inline:got 11\n" \
- ${HELPER} handle recurse
+ atf_check -s signal:5 -o "inline:" -e "inline:got 5\n" \
+ ${HELPER} trap handle recurse
}
atf_test_case trap_ignore
@@ -93,12 +161,18 @@
trap_ignore_body()
{
- atf_check -s signal:11 -o "inline:" -e "inline:" \
- ${HELPER} ignore
+ atf_check -s signal:5 -o "inline:" -e "inline:" \
+ ${HELPER} trap ignore
}
atf_init_test_cases()
{
+ atf_add_test_case segv_simple
+ atf_add_test_case segv_handle
+ atf_add_test_case segv_mask
+ atf_add_test_case segv_handle_recurse
+ atf_add_test_case segv_ignore
+
Home |
Main Index |
Thread Index |
Old Index