diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 53aa9aaf70adfaea4a6ead05f33974cdf2322247..d2d6fa46877598f8a642d5a354e82c51934e6590 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 */