Module Name:    src
Committed By:   kamil
Date:           Sat May 16 19:08:20 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:

 - posix_spawn_singalmasked
 - posix_spawn_singalignored
 - fork_singalmasked
 - fork_singalignored
 - vfork_singalmasked
 - vfork_singalignored
 - vforkdone_singalmasked
 - vforkdone_singalignored

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.3 -r1.4 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.3 src/tests/lib/libc/sys/t_ptrace_fork_wait.h:1.4
--- src/tests/lib/libc/sys/t_ptrace_fork_wait.h:1.3	Thu May 14 19:21:35 2020
+++ src/tests/lib/libc/sys/t_ptrace_fork_wait.h	Sat May 16 19:08:20 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_ptrace_fork_wait.h,v 1.3 2020/05/14 19:21:35 kamil Exp $	*/
+/*	$NetBSD: t_ptrace_fork_wait.h,v 1.4 2020/05/16 19:08:20 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2016, 2017, 2018, 2020 The NetBSD Foundation, Inc.
@@ -1250,6 +1250,7 @@ fork2_body(const char *fn, bool masked, 
 
 	int name[6];
 	const size_t namelen = __arraycount(name);
+	sigset_t set;
 	ki_sigset_t kp_sigmask;
 	ki_sigset_t kp_sigignore;
 
@@ -1341,6 +1342,19 @@ fork2_body(const char *fn, bool masked, 
 		event.pe_set_event |= PTRACE_VFORK_DONE;
 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &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, child, &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, child, (void *)1, 0) != -1);
@@ -1560,16 +1574,6 @@ fork2_body(const char *fn, bool masked, 
 		    wpid = TWAIT_GENERIC(child2, &status, 0));
 	}
 
-	DPRINTF("Before calling %s() for the child - expected stopped "
-	    "SIGCHLD\n", TWAIT_FNAME);
-	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
-
-	validate_status_stopped(status, SIGCHLD);
-
-	DPRINTF("Before resuming the child process where it left off and "
-	    "without signal to be sent\n");
-	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
-
 	DPRINTF("Before calling %s() for the child - expected exited\n",
 	    TWAIT_FNAME);
 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);

Reply via email to