Commit 24ecde77 authored by Robert Haas's avatar Robert Haas

Work around unfortunate getppid() behavior on BSD-ish systems.

On MacOS X, and apparently also on other BSD-derived systems, attaching
a debugger causes getppid() to return the pid of the debugging process
rather than the actual parent PID.  As a result, debugging the
autovacuum launcher, startup process, or WAL sender on such systems
causes it to exit, because the previous coding of PostmasterIsAlive()
detects postmaster death by testing whether getppid() == PostmasterPid.

Work around that behavior by checking the return value of getppid()
more carefully.  If it's PostmasterPid, the postmaster must be alive;
if it's 1, assume the postmaster is dead.  If it's any other value,
assume we've been debugged and fall through to the less-reliable
kill() test.

Review by Tom Lane.
parent f6a0863e
...@@ -260,22 +260,30 @@ PostmasterIsAlive(bool amDirectChild) ...@@ -260,22 +260,30 @@ PostmasterIsAlive(bool amDirectChild)
#ifndef WIN32 #ifndef WIN32
if (amDirectChild) if (amDirectChild)
{ {
pid_t ppid = getppid();
/* If the postmaster is still our parent, it must be alive. */
if (ppid == PostmasterPid)
return true;
/* If the init process is our parent, postmaster must be dead. */
if (ppid == 1)
return false;
/* /*
* If the postmaster is alive, we'll still be its child. If it's * If we get here, our parent process is neither the postmaster nor
* died, we'll be reassigned as a child of the init process. * init. This can occur on BSD and MacOS systems if a debugger has
*/ * been attached. We fall through to the less-reliable kill() method.
return (getppid() == PostmasterPid);
}
else
{
/*
* Use kill() to see if the postmaster is still alive. This can
* sometimes give a false positive result, since the postmaster's PID
* may get recycled, but it is good enough for existing uses by
* indirect children.
*/ */
return (kill(PostmasterPid, 0) == 0);
} }
/*
* Use kill() to see if the postmaster is still alive. This can
* sometimes give a false positive result, since the postmaster's PID
* may get recycled, but it is good enough for existing uses by
* indirect children and in debugging environments.
*/
return (kill(PostmasterPid, 0) == 0);
#else /* WIN32 */ #else /* WIN32 */
return (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT); return (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT);
#endif /* WIN32 */ #endif /* WIN32 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment