mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
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.
This commit is contained in:
@ -260,22 +260,30 @@ PostmasterIsAlive(bool amDirectChild)
|
||||
#ifndef WIN32
|
||||
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
|
||||
* died, we'll be reassigned as a child of the init process.
|
||||
* If we get here, our parent process is neither the postmaster nor
|
||||
* 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 */
|
||||
return (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT);
|
||||
#endif /* WIN32 */
|
||||
|
Reference in New Issue
Block a user