Page MenuHomeFreeBSD

pfind, pfind_any: Correct zombie logic
ClosedPublic

Authored by jilles on Dec 28 2018, 12:35 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Nov 15, 8:32 AM
Unknown Object (File)
Sun, Nov 10, 8:23 PM
Unknown Object (File)
Sun, Nov 10, 7:47 PM
Unknown Object (File)
Thu, Oct 31, 4:38 AM
Unknown Object (File)
Oct 19 2024, 1:19 AM
Unknown Object (File)
Oct 19 2024, 1:19 AM
Unknown Object (File)
Oct 19 2024, 1:19 AM
Unknown Object (File)
Oct 19 2024, 12:49 AM
Subscribers

Details

Summary

SVN r340744 erroneously changed pfind() to return any process including
zombies and pfind_any() to return only non-zombie processes.

In particular, this caused kill() on a zombie process to fail with [ESRCH].
There is no direct test case for this but
/usr/tests/bin/sh/builtins/kill1.0 occasionally triggers it.

Conversely, returning zombies from pfind() seems likely to violate
invariants and cause panics, but I have not looked at this.

PR: 233646

Test Plan

On a buggy kernel

while sh /usr/tests/bin/sh/builtins/kill1.0; do :; done

fails within a few seconds with

kill: %1: No such process

With the fix, it runs for minutes without failing.

A more direct test case is:

#include	<sys/wait.h>

#include	<err.h>
#include	<signal.h>
#include	<stdio.h>
#include	<unistd.h>

int
main(int argc, char *argv[])
{
	pid_t child;

	switch (child = fork()) {
		case 0:
			_exit(0);
		case -1:
			err(1, "fork");
		default:
			break;
	}
	if (waitid(P_PID, child, NULL, WEXITED | WNOWAIT) == -1)
		err(1, "waitid");
	if (kill(child, SIGTERM) == -1)
		err(1, "kill zombie");

	return 0;
}

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable