NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/59175: posix_spawn hang, hanging other process too



The following reply was made to PR kern/59175; it has been noted by GNATS.

From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: wiz%NetBSD.org@localhost
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: kern/59175: posix_spawn hang, hanging other process too
Date: Fri, 14 Mar 2025 01:23:53 +0000

 This is a multi-part message in MIME format.
 --=_UO/DuVWULAgwAF6z8mwyycn6j85jhood
 
 The attached program appears to reproduce the issue.
 
 make waitrace
 ./waitraice &
 while :; do kill -INFO %1; sleep 1; done
 
 At some point, it will stop printing numbers because it is stuck.
 
 This is probably some deadlock between some combination of p_reflock,
 exec_lock, proc_lock, and who knows what other horrible lock
 shenanigans posix_spawn gets itself into.
 
 --=_UO/DuVWULAgwAF6z8mwyycn6j85jhood
 Content-Type: text/plain; charset="ISO-8859-1"; name="waitrace"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="waitrace.c"
 
 #include <sys/sysctl.h>
 #include <sys/wait.h>
 
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <spawn.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 
 unsigned long long n;
 
 static void
 info(int signo)
 {
 	char buf[32];
 
 	snprintf_ss(buf, sizeof(buf), "%llu\n", n);
 	(void)write(STDOUT_FILENO, buf, strlen(buf));
 }
 
 int
 main(int argc, char **argv)
 {
 	static char buf[65536];
 	int mib[] =3D {CTL_KERN, KERN_PROC_ARGS, /*pid*/-1, KERN_PROC_NARGV};
 	sigset_t mask, omask;
 
 	if (argc =3D=3D 2) {
 		ssize_t nread;
 
 		nread =3D read(STDIN_FILENO, (char[]){0}, 1);
 		if (nread =3D=3D -1)
 			err(1, "read");
 		if (nread =3D=3D 0)
 			errx(1, "premature eof");
 		return 0;
 	}
 
 	if (sigemptyset(&mask) =3D=3D -1)
 		err(1, "sigemptyset");
 	if (sigaddset(&mask, SIGINFO) =3D=3D -1)
 		err(1, "sigaddset");
 	if (signal(SIGINFO, &info) =3D=3D SIG_ERR)
 		err(1, "signal(SIGINFO)");
 
 	for (;;) {
 		char *const nargv[] =3D {argv[0], "stuff", NULL};
 		int waitpipe[2];
 		posix_spawn_file_actions_t fa;
 		pid_t pid;
 		size_t buflen;
 		int status, error;
 
 		if (pipe2(waitpipe, O_CLOEXEC) =3D=3D -1)
 			err(1, "pipe2");
 
 		error =3D posix_spawn_file_actions_init(&fa);
 		if (error)
 			err(1, "posix_spawn_file_actions_init");
 
 		error =3D posix_spawn_file_actions_adddup2(&fa, waitpipe[0],
 		    STDIN_FILENO);
 		if (error)
 			err(1, "posix_spawn_file_actions_adddup2");
 
 		error =3D posix_spawn(&pid, nargv[0], &fa, NULL, nargv, NULL);
 		if (error)
 			err(1, "posix_spawn");
 
 		mib[2] =3D (int)pid;
 		buflen =3D sizeof(buf);
 		while (sysctl(mib, __arraycount(mib), buf, &buflen, NULL, 0)
 		    =3D=3D -1) {
 			if (errno =3D=3D EBUSY)
 				continue;
 			err(1, "sysctl kern.proc_args.%d.nargv", mib[2]);
 		}
 
 		if (close(waitpipe[0]) =3D=3D -1)
 			err(1, "close");
 		if (write(waitpipe[1], (char[]){0}, 1) =3D=3D -1)
 			err(1, "write");
 		if (close(waitpipe[1]))
 			err(1, "write");
 
 		error =3D posix_spawn_file_actions_destroy(&fa);
 		if (error)
 			err(1, "posix_spawn_file_actions_destroy");
 
 		if (waitpid(pid, &status, 0) =3D=3D -1)
 			err(1, "waitpid");
 		if (status !=3D 0)
 			errx(1, "status=3D0x%x", status);
 
 		if (sigprocmask(SIG_BLOCK, &mask, &omask) =3D=3D -1)
 			err(1, "sigprocmask(SIG_BLOCK)");
 		n++;
 		if (sigprocmask(SIG_SETMASK, &omask, NULL) =3D=3D -1)
 			err(1, "sigprocmask(SIG_SETMASK)");
 	}
 	printf("%llu\n", n);
 	fflush(stdout);
 	return ferror(stdout);
 }
 
 --=_UO/DuVWULAgwAF6z8mwyycn6j85jhood--
 


Home | Main Index | Thread Index | Old Index