Module Name:    src
Committed By:   kamil
Date:           Sat May 16 23:10:26 UTC 2020

Modified Files:
        src/tests/lib/libc/sys: t_ptrace_fork_wait.h

Log Message:
Ignore interception of SIGCHLD signals in the debugger

Set SIGPASS for SIGCHLD for the traced child in the following tests:
 - unrelated_tracer_fork*
 - unrelated_tracer_vfork*
 - unrelated_tracer_posix_spawn*

There is a race that SIGCHLD might be blocked during forking and dropped.

PR/55241 by Andreas Gustafsson


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/lib/libc/sys/t_ptrace_fork_wait.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/sys/t_ptrace_fork_wait.h
diff -u src/tests/lib/libc/sys/t_ptrace_fork_wait.h:1.5 src/tests/lib/libc/sys/t_ptrace_fork_wait.h:1.6
--- src/tests/lib/libc/sys/t_ptrace_fork_wait.h:1.5	Sat May 16 22:07:06 2020
+++ src/tests/lib/libc/sys/t_ptrace_fork_wait.h	Sat May 16 23:10:26 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_fork_wait.h,v 1.5 2020/05/16 22:07:06 kamil Exp $	*/
+/*	$NetBSD: t_ptrace_fork_wait.h,v 1.6 2020/05/16 23:10:26 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2016, 2017, 2018, 2020 The NetBSD Foundation, Inc.
@@ -337,6 +337,7 @@ unrelated_tracer_fork_body(const char *f
 	int status;
 #endif
 
+	sigset_t set;
 	struct ptrace_siginfo info;
 	ptrace_state_t state;
 	const int slen = sizeof(state);
@@ -453,6 +454,21 @@ unrelated_tracer_fork_body(const char *f
 		SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, tracee, &event, elen)
 		    != -1);
 
+		/*
+		 * Ignore interception of the SIGCHLD signals.
+		 *
+		 * SIGCHLD once blocked is discarded by the kernel as it has the
+		 * SA_IGNORE property. During the fork(2) operation all signals
+		 * can be shortly blocked and missed (unless there is a
+		 * registered signal handler in the traced child). This leads to
+		 * a race in this test if there would be an intention to catch
+		 * SIGCHLD.
+		 */
+		sigemptyset(&set);
+		sigaddset(&set, SIGCHLD);
+		SYSCALL_REQUIRE(ptrace(PT_SET_SIGPASS, tracee, &set,
+		    sizeof(set)) != -1);
+
 		DPRINTF("Before resuming the child process where it left off "
 		    "and without signal to be sent\n");
 		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
@@ -559,16 +575,6 @@ unrelated_tracer_fork_body(const char *f
 			    wpid = TWAIT_GENERIC(tracee2, &status, 0));
 		}
 
-		DPRINTF("Before calling %s() for the tracee - expected stopped "
-		    "SIGCHLD\n", TWAIT_FNAME);
-		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);
-
-		validate_status_stopped(status, SIGCHLD);
-
-		DPRINTF("Before resuming the tracee process where it left off and "
-		    "without signal to be sent\n");
-		SYSCALL_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1);
-
 		DPRINTF("Before calling %s() for the tracee - expected exited\n",
 		    TWAIT_FNAME);
 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, 0), tracee);

Reply via email to