aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2010-12-21 06:30:32 -0500
committerRobert Haas <rhaas@postgresql.org>2010-12-21 06:30:32 -0500
commit24ecde7742cd4d7c781e6890b07571fff42b25dc (patch)
treebeef3e35e6b59ba7371f9e8dd8f00e957e85f723 /src
parentf6a0863e3cb72763490ceca2c558d5ef2dddd5f2 (diff)
downloadpostgresql-24ecde7742cd4d7c781e6890b07571fff42b25dc.tar.gz
postgresql-24ecde7742cd4d7c781e6890b07571fff42b25dc.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/pmsignal.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 53aa9aaf70a..d2d6fa46877 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -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.
- */
- 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.
+ * 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 (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 */