Module Name: src Committed By: kamil Date: Sun May 20 03:51:32 UTC 2018
Modified Files: src/sys/kern: sys_ptrace_common.c src/tests/lib/libc/sys: t_ptrace_wait.c Log Message: Fix and enable traceme_signal_nohandler2 in ATF ptrace(2) tests traceme_signal_nohandler2 checks emitting SIGSTOP to a traced process with the PT_CONTINUE operation. The expected behavior is to simulate a behavior of receiving SIGSTOP, generating SIGCHLD to its parent (in this case the debugger) and ability to call wait(2)-like function receiving the stopped child event. The previous behavior was unstopping the process and it has been adjusted in the kernel code. FreeBSD keeps unstopping a process for emitting SIGSTOP. Linux handles this scenario in the same way as NetBSD now. While there, implement the missing bits in the userland ATF test for traceme_signal_nohandler2: receiving and validating 2nd SIGSTOP event and continuing the process, followed by its normal termination. Sponsored by <The NetBSD Foundation> To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/kern/sys_ptrace_common.c cvs rdiff -u -r1.47 -r1.48 src/tests/lib/libc/sys/t_ptrace_wait.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/sys_ptrace_common.c diff -u src/sys/kern/sys_ptrace_common.c:1.40 src/sys/kern/sys_ptrace_common.c:1.41 --- src/sys/kern/sys_ptrace_common.c:1.40 Tue May 1 16:37:23 2018 +++ src/sys/kern/sys_ptrace_common.c Sun May 20 03:51:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_ptrace_common.c,v 1.40 2018/05/01 16:37:23 kamil Exp $ */ +/* $NetBSD: sys_ptrace_common.c,v 1.41 2018/05/20 03:51:31 kamil Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -118,7 +118,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.40 2018/05/01 16:37:23 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.41 2018/05/20 03:51:31 kamil Exp $"); #ifdef _KERNEL_OPT #include "opt_ptrace.h" @@ -865,7 +865,16 @@ ptrace_sendsig(struct proc *t, struct lw * an LWP runs to see it. */ t->p_xsig = signo; - if (resume_all) + + /* + * signo > 0 check precents a potential panic, as + * sigismember(&...,0) is invalid check and signo + * can be equal to 0 as a special case of no-signal. + */ + if (signo > 0 && sigismember(&stopsigmask, signo)) { + t->p_waited = 0; + child_psignal(t, 0); + } else if (resume_all) proc_unstop(t); else lwp_unstop(lt); Index: src/tests/lib/libc/sys/t_ptrace_wait.c diff -u src/tests/lib/libc/sys/t_ptrace_wait.c:1.47 src/tests/lib/libc/sys/t_ptrace_wait.c:1.48 --- src/tests/lib/libc/sys/t_ptrace_wait.c:1.47 Sat May 19 05:25:21 2018 +++ src/tests/lib/libc/sys/t_ptrace_wait.c Sun May 20 03:51:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: t_ptrace_wait.c,v 1.47 2018/05/19 05:25:21 kamil Exp $ */ +/* $NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 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.47 2018/05/19 05:25:21 kamil Exp $"); +__RCSID("$NetBSD: t_ptrace_wait.c,v 1.48 2018/05/20 03:51:31 kamil Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -299,6 +299,7 @@ traceme_signal_nohandler(int sigsent) switch (sigsent) { case SIGCONT: + case SIGSTOP: _exit(exitval); default: /* NOTREACHED */ @@ -332,6 +333,30 @@ traceme_signal_nohandler(int sigsent) TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); switch (sigsent) { + case SIGSTOP: + validate_status_stopped(status, sigsent); + DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for " + "child\n"); + SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, + sizeof(info)) != -1); + + DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); + DPRINTF("Signal properties: si_signo=%#x si_code=%#x " + "si_errno=%#x\n", + info.psi_siginfo.si_signo, info.psi_siginfo.si_code, + info.psi_siginfo.si_errno); + + ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); + ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); + + DPRINTF("Before resuming the child process where it left off " + "and with signal %s to be sent\n", strsignal(sigsent)); + SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); + + DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); + TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), + child); + /* FALLTHROUGH */ case SIGCONT: validate_status_exited(status, exitval); break; @@ -360,7 +385,7 @@ ATF_TC_BODY(test, tc) \ } TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler1, SIGKILL) /* non-maskable */ -//TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */ +TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler2, SIGSTOP) /* non-maskable */ TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler3, SIGABRT) /* abort trap */ TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler4, SIGHUP) /* hangup */ TRACEME_SIGNAL_NOHANDLER(traceme_signal_nohandler5, SIGCONT) /* continued? */ @@ -7113,7 +7138,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, traceme_sighandler_catch3); ATF_TP_ADD_TC(tp, traceme_signal_nohandler1); -// ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); // not yet + ATF_TP_ADD_TC(tp, traceme_signal_nohandler2); ATF_TP_ADD_TC(tp, traceme_signal_nohandler3); ATF_TP_ADD_TC(tp, traceme_signal_nohandler4); ATF_TP_ADD_TC(tp, traceme_signal_nohandler5);