From d7ecde678fb61cc8b56d9b10507ee98506c2bd11 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 7 Jan 2025 20:22:36 -0500
Subject: [PATCH v1 2/4] postmaster: Improve logging of signals sent by
 postmaster

Previously many, in some cases important, signals we never logged. In other
cases the signal name was only included numerically.

Also move from direct use of kill() to signal the av launcher to
signal_child(). There doesn't seem to be a reason for directly using kill().

Author:
Reviewed-by:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/backend/postmaster/postmaster.c | 61 ++++++++++++++++++++++++-----
 1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 9d23c3482ae..d57fee54e0d 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -419,6 +419,7 @@ static int	BackendStartup(ClientSocket *client_sock);
 static void report_fork_failure_to_client(ClientSocket *client_sock, int errnum);
 static CAC_state canAcceptConnections(BackendType backend_type);
 static void signal_child(PMChild *pmchild, int signal);
+static void signal_child_ext(PMChild *pmchild, int signal, int elevel);
 static void sigquit_child(PMChild *pmchild);
 static bool SignalChildren(int signal, BackendTypeMask targetMask);
 static void TerminateChildren(int signal);
@@ -1693,7 +1694,7 @@ ServerLoop(void)
 		{
 			avlauncher_needs_signal = false;
 			if (AutoVacLauncherPMChild != NULL)
-				kill(AutoVacLauncherPMChild->pid, SIGUSR2);
+				signal_child(AutoVacLauncherPMChild, SIGUSR2);
 		}
 
 #ifdef HAVE_PTHREAD_IS_THREADED_NP
@@ -3255,6 +3256,37 @@ LaunchMissingBackgroundProcesses(void)
 		maybe_start_bgworkers();
 }
 
+/*
+ * Return string representation of signal.
+ *
+ * Because this is only implemented in signals we already rely on in this file
+ * we don't need to deal with unimplemented or same-numeric-value signals (as
+ * we'd e.g. have to for EWOULDBLOCK / EAGAIN).
+ */
+static const char *
+pm_signame(int signal)
+{
+#define PM_CASE(state) case state: return #state
+	switch (signal)
+	{
+			PM_CASE(SIGABRT);
+			PM_CASE(SIGCHLD);
+			PM_CASE(SIGHUP);
+			PM_CASE(SIGINT);
+			PM_CASE(SIGKILL);
+			PM_CASE(SIGQUIT);
+			PM_CASE(SIGTERM);
+			PM_CASE(SIGUSR1);
+			PM_CASE(SIGUSR2);
+		default:
+			/* all signals sent by postmaster should be listed here */
+			Assert(false);
+			return "(unknown)";
+	}
+#undef PM_CASE
+	pg_unreachable();
+}
+
 /*
  * Send a signal to a postmaster child process
  *
@@ -3272,10 +3304,16 @@ LaunchMissingBackgroundProcesses(void)
  * child twice will not cause any problems.
  */
 static void
-signal_child(PMChild *pmchild, int signal)
+signal_child_ext(PMChild *pmchild, int signal, int elevel)
 {
 	pid_t		pid = pmchild->pid;
 
+	ereport(elevel,
+			(errmsg_internal("sending signal %d/%s to %s process %d",
+							 signal, pm_signame(signal),
+							 GetBackendTypeDesc(pmchild->bkend_type),
+							 (int) pmchild->pid)));
+
 	if (kill(pid, signal) < 0)
 		elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
 #ifdef HAVE_SETSID
@@ -3295,6 +3333,15 @@ signal_child(PMChild *pmchild, int signal)
 #endif
 }
 
+/*
+ * Like signal_child_ext(), but with a default debug level.
+ */
+static void
+signal_child(PMChild *pmchild, int signal)
+{
+	signal_child_ext(pmchild, signal, DEBUG4);
+}
+
 /*
  * Convenience function for killing a child process after a crash of some
  * other child process.  We log the action at a higher level than we would
@@ -3306,11 +3353,8 @@ signal_child(PMChild *pmchild, int signal)
 static void
 sigquit_child(PMChild *pmchild)
 {
-	ereport(DEBUG2,
-			(errmsg_internal("sending %s to process %d",
-							 (send_abort_for_crash ? "SIGABRT" : "SIGQUIT"),
-							 (int) pmchild->pid)));
-	signal_child(pmchild, (send_abort_for_crash ? SIGABRT : SIGQUIT));
+	signal_child_ext(pmchild, (send_abort_for_crash ? SIGABRT : SIGQUIT),
+					 DEBUG2);
 }
 
 /*
@@ -3341,9 +3385,6 @@ SignalChildren(int signal, BackendTypeMask targetMask)
 		if (!btmask_contains(targetMask, bp->bkend_type))
 			continue;
 
-		ereport(DEBUG4,
-				(errmsg_internal("sending signal %d to %s process %d",
-								 signal, GetBackendTypeDesc(bp->bkend_type), (int) bp->pid)));
 		signal_child(bp, signal);
 		signaled = true;
 	}
-- 
2.45.2.746.g06e570c0df.dirty

