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);

Reply via email to