On Thu, Sep 18, 2025 at 11:33 AM Álvaro Herrera <[email protected]> wrote:

> > I'm not sure if it is a good idea to have translated backend description. 
> > The
> > init_ps_display() output is certainly used to obtain information (PID?) 
> > from a
> > process list. There is also the option %b from log_line_prefix that is used 
> > to
> > filter log messages per backend type. The same applies to backend_type 
> > column
> > from pg_stat_activity view.
>
> I should have let you know that I spent some time on this today as well
> to avoid duplicating efforts.  Here are my patches, incorporating your
> fixup -- I hadn't looked at your 0004 yet, so I wrote it differently,
> passing the BackendType enum directly to LogChildExit (as well as
> HandleChildCrash), so it is the former function that does the call to
> GetBackendTypeDesc() to obtain the string.  I think this is better
> because the untranslated part of the sentence is enclosed in quotes,
> which I think is better.  However it meant I had to add a bit of a hack
> to cope with the background worker separate bgw_type string.
>
> So I came up with things as attached, incorporating your 0003 fixup.
> What do you think?
>

The call to gettext_noop() was missing, hence, the translation for the
backends was
missing. I've attached a third commit to your patch adding the missing
gettext_noop()
and also adding the include directory to the nls.mk Makefile which
will add proctypelist.h
to the list of files used to generate the po.

I've tested the patch using `make -C src/backend update-po` and the
strings were added
properly.

Regards,
From 896a377a33a6e8035f39e3ccfbef8156cab51235 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
Date: Tue, 15 Jul 2025 18:19:27 +0200
Subject: [PATCH 1/3] Create a separate file listing backend types

Use our established coding pattern to reduce maintenance pain when
adding other per-process-type characteristics.

Like PG_KEYWORD, PG_CMDTAG, PG_RMGR.

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
---
 src/backend/postmaster/launch_backend.c | 32 ++------------
 src/backend/utils/init/miscinit.c       | 59 ++-----------------------
 src/include/postmaster/proctypelist.h   | 50 +++++++++++++++++++++
 3 files changed, 58 insertions(+), 83 deletions(-)
 create mode 100644 src/include/postmaster/proctypelist.h

diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c
index 79708e59259..976638a58ac 100644
--- a/src/backend/postmaster/launch_backend.c
+++ b/src/backend/postmaster/launch_backend.c
@@ -179,34 +179,10 @@ typedef struct
 } child_process_kind;
 
 static child_process_kind child_process_kinds[] = {
-	[B_INVALID] = {"invalid", NULL, false},
-
-	[B_BACKEND] = {"backend", BackendMain, true},
-	[B_DEAD_END_BACKEND] = {"dead-end backend", BackendMain, true},
-	[B_AUTOVAC_LAUNCHER] = {"autovacuum launcher", AutoVacLauncherMain, true},
-	[B_AUTOVAC_WORKER] = {"autovacuum worker", AutoVacWorkerMain, true},
-	[B_BG_WORKER] = {"bgworker", BackgroundWorkerMain, true},
-
-	/*
-	 * WAL senders start their life as regular backend processes, and change
-	 * their type after authenticating the client for replication.  We list it
-	 * here for PostmasterChildName() but cannot launch them directly.
-	 */
-	[B_WAL_SENDER] = {"wal sender", NULL, true},
-	[B_SLOTSYNC_WORKER] = {"slot sync worker", ReplSlotSyncWorkerMain, true},
-
-	[B_STANDALONE_BACKEND] = {"standalone backend", NULL, false},
-
-	[B_ARCHIVER] = {"archiver", PgArchiverMain, true},
-	[B_BG_WRITER] = {"bgwriter", BackgroundWriterMain, true},
-	[B_CHECKPOINTER] = {"checkpointer", CheckpointerMain, true},
-	[B_IO_WORKER] = {"io_worker", IoWorkerMain, true},
-	[B_STARTUP] = {"startup", StartupProcessMain, true},
-	[B_WAL_RECEIVER] = {"wal_receiver", WalReceiverMain, true},
-	[B_WAL_SUMMARIZER] = {"wal_summarizer", WalSummarizerMain, true},
-	[B_WAL_WRITER] = {"wal_writer", WalWriterMain, true},
-
-	[B_LOGGER] = {"syslogger", SysLoggerMain, false},
+#define PG_PROCTYPE(bktype, description, main_func, shmem_attach) \
+	[bktype] = {description, main_func, shmem_attach},
+#include "postmaster/proctypelist.h"
+#undef PG_PROCTYPE
 };
 
 const char *
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 545d1e90fbd..749fb502e95 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -266,62 +266,11 @@ GetBackendTypeDesc(BackendType backendType)
 
 	switch (backendType)
 	{
-		case B_INVALID:
-			backendDesc = gettext_noop("not initialized");
-			break;
-		case B_ARCHIVER:
-			backendDesc = gettext_noop("archiver");
-			break;
-		case B_AUTOVAC_LAUNCHER:
-			backendDesc = gettext_noop("autovacuum launcher");
-			break;
-		case B_AUTOVAC_WORKER:
-			backendDesc = gettext_noop("autovacuum worker");
-			break;
-		case B_BACKEND:
-			backendDesc = gettext_noop("client backend");
-			break;
-		case B_DEAD_END_BACKEND:
-			backendDesc = gettext_noop("dead-end client backend");
-			break;
-		case B_BG_WORKER:
-			backendDesc = gettext_noop("background worker");
-			break;
-		case B_BG_WRITER:
-			backendDesc = gettext_noop("background writer");
-			break;
-		case B_CHECKPOINTER:
-			backendDesc = gettext_noop("checkpointer");
-			break;
-		case B_IO_WORKER:
-			backendDesc = gettext_noop("io worker");
-			break;
-		case B_LOGGER:
-			backendDesc = gettext_noop("logger");
-			break;
-		case B_SLOTSYNC_WORKER:
-			backendDesc = gettext_noop("slotsync worker");
-			break;
-		case B_STANDALONE_BACKEND:
-			backendDesc = gettext_noop("standalone backend");
-			break;
-		case B_STARTUP:
-			backendDesc = gettext_noop("startup");
-			break;
-		case B_WAL_RECEIVER:
-			backendDesc = gettext_noop("walreceiver");
-			break;
-		case B_WAL_SENDER:
-			backendDesc = gettext_noop("walsender");
-			break;
-		case B_WAL_SUMMARIZER:
-			backendDesc = gettext_noop("walsummarizer");
-			break;
-		case B_WAL_WRITER:
-			backendDesc = gettext_noop("walwriter");
-			break;
+#define PG_PROCTYPE(bktype, description, main_func, shmem_attach) \
+		case bktype: backendDesc = gettext_noop(description); break;
+#include "postmaster/proctypelist.h"
+#undef PG_PROCTYPE
 	}
-
 	return backendDesc;
 }
 
diff --git a/src/include/postmaster/proctypelist.h b/src/include/postmaster/proctypelist.h
new file mode 100644
index 00000000000..919f00bb3a7
--- /dev/null
+++ b/src/include/postmaster/proctypelist.h
@@ -0,0 +1,50 @@
+/*-------------------------------------------------------------------------
+ *
+ * proctypelist.h
+ *
+ * The list of process types is kept on its own source file for use by
+ * automatic tools.  The exact representation of a process type is
+ * determined by the PG_PROCTYPE macro, which is not defined in this
+ * file; it can be defined by the caller for special purposes.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *	  src/include/postmaster/proctypelist.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* there is deliberately not an #ifndef PROCTYPELIST_H here */
+
+/*
+ * WAL senders start their life as regular backend processes, and change their
+ * type after authenticating the client for replication.  We list it here for
+ * PostmasterChildName() but cannot launch them directly.
+ */
+
+/*
+ * List of process types (symbol, description, Main function, shmem_attach)
+ * entries.
+ */
+
+/* bktype, description, main_func, shmem_attach */
+PG_PROCTYPE(B_ARCHIVER, "archiver", PgArchiverMain, true)
+PG_PROCTYPE(B_AUTOVAC_LAUNCHER, "autovacuum launcher", AutoVacLauncherMain, true)
+PG_PROCTYPE(B_AUTOVAC_WORKER, "autovacuum worker", AutoVacWorkerMain, true)
+PG_PROCTYPE(B_BACKEND, "client backend", BackendMain, true)
+PG_PROCTYPE(B_BG_WORKER, "background worker", BackgroundWorkerMain, true)
+PG_PROCTYPE(B_BG_WRITER, "background writer", BackgroundWriterMain, true)
+PG_PROCTYPE(B_CHECKPOINTER, "checkpointer", CheckpointerMain, true)
+PG_PROCTYPE(B_DEAD_END_BACKEND, "dead-end client backend", BackendMain, true)
+PG_PROCTYPE(B_INVALID, "unrecognized", NULL, false)
+PG_PROCTYPE(B_IO_WORKER, "io worker", IoWorkerMain, true)
+PG_PROCTYPE(B_LOGGER, "syslogger", SysLoggerMain, false)
+PG_PROCTYPE(B_SLOTSYNC_WORKER, "slotsync worker", ReplSlotSyncWorkerMain, true)
+PG_PROCTYPE(B_STANDALONE_BACKEND, "standalone backend", NULL, false)
+PG_PROCTYPE(B_STARTUP, "startup", StartupProcessMain, true)
+PG_PROCTYPE(B_WAL_RECEIVER, "walreceiver", WalReceiverMain, true)
+PG_PROCTYPE(B_WAL_SENDER, "walsender", NULL, true)
+PG_PROCTYPE(B_WAL_SUMMARIZER, "walsummarizer", WalSummarizerMain, true)
+PG_PROCTYPE(B_WAL_WRITER, "walwriter", WalWriterMain, true)
-- 
2.48.1

From a7e2bdced47635e0e3e4389c40a3ec486487a2c0 Mon Sep 17 00:00:00 2001
From: "Jonathan Gonzalez V." <[email protected]>
Date: Tue, 16 Sep 2025 16:53:39 +0200
Subject: [PATCH 3/3] Make translation-compatible

Previous patch was missing the gettext_noop() disabling the translation
for the backend descriptions, now is compatible and is added to the
translation files

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
---
 src/backend/nls.mk                    |  2 +-
 src/backend/utils/init/miscinit.c     |  4 +--
 src/include/postmaster/proctypelist.h | 37 ++++++++++++++-------------
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/src/backend/nls.mk b/src/backend/nls.mk
index b7d5dd46e45..698b1083f4b 100644
--- a/src/backend/nls.mk
+++ b/src/backend/nls.mk
@@ -28,7 +28,7 @@ GETTEXT_FLAGS    = $(BACKEND_COMMON_GETTEXT_FLAGS) \
                    error_cb:2:c-format
 
 gettext-files: generated-parser-sources generated-headers
-	find $(srcdir) $(srcdir)/../common $(srcdir)/../port -name '*.c' -print | LC_ALL=C sort >$@
+	find $(srcdir) $(srcdir)/../common $(srcdir)/../port $(srcdir)/../include/ \( -name '*.c' -o -name "proctypelist.h" \) -print | LC_ALL=C sort >$@
 
 my-clean:
 	rm -f gettext-files
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 749fb502e95..fec79992c8d 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -266,8 +266,8 @@ GetBackendTypeDesc(BackendType backendType)
 
 	switch (backendType)
 	{
-#define PG_PROCTYPE(bktype, description, main_func, shmem_attach) \
-		case bktype: backendDesc = gettext_noop(description); break;
+#define PG_PROCTYPE(bktype, description, main_func, shmem_attach)	\
+		case bktype: backendDesc = description; break;
 #include "postmaster/proctypelist.h"
 #undef PG_PROCTYPE
 	}
diff --git a/src/include/postmaster/proctypelist.h b/src/include/postmaster/proctypelist.h
index 919f00bb3a7..242862451d8 100644
--- a/src/include/postmaster/proctypelist.h
+++ b/src/include/postmaster/proctypelist.h
@@ -29,22 +29,23 @@
  * entries.
  */
 
+
 /* bktype, description, main_func, shmem_attach */
-PG_PROCTYPE(B_ARCHIVER, "archiver", PgArchiverMain, true)
-PG_PROCTYPE(B_AUTOVAC_LAUNCHER, "autovacuum launcher", AutoVacLauncherMain, true)
-PG_PROCTYPE(B_AUTOVAC_WORKER, "autovacuum worker", AutoVacWorkerMain, true)
-PG_PROCTYPE(B_BACKEND, "client backend", BackendMain, true)
-PG_PROCTYPE(B_BG_WORKER, "background worker", BackgroundWorkerMain, true)
-PG_PROCTYPE(B_BG_WRITER, "background writer", BackgroundWriterMain, true)
-PG_PROCTYPE(B_CHECKPOINTER, "checkpointer", CheckpointerMain, true)
-PG_PROCTYPE(B_DEAD_END_BACKEND, "dead-end client backend", BackendMain, true)
-PG_PROCTYPE(B_INVALID, "unrecognized", NULL, false)
-PG_PROCTYPE(B_IO_WORKER, "io worker", IoWorkerMain, true)
-PG_PROCTYPE(B_LOGGER, "syslogger", SysLoggerMain, false)
-PG_PROCTYPE(B_SLOTSYNC_WORKER, "slotsync worker", ReplSlotSyncWorkerMain, true)
-PG_PROCTYPE(B_STANDALONE_BACKEND, "standalone backend", NULL, false)
-PG_PROCTYPE(B_STARTUP, "startup", StartupProcessMain, true)
-PG_PROCTYPE(B_WAL_RECEIVER, "walreceiver", WalReceiverMain, true)
-PG_PROCTYPE(B_WAL_SENDER, "walsender", NULL, true)
-PG_PROCTYPE(B_WAL_SUMMARIZER, "walsummarizer", WalSummarizerMain, true)
-PG_PROCTYPE(B_WAL_WRITER, "walwriter", WalWriterMain, true)
+PG_PROCTYPE(B_ARCHIVER, gettext_noop("archiver"), PgArchiverMain, true)
+PG_PROCTYPE(B_AUTOVAC_LAUNCHER, gettext_noop("autovacuum launcher"), AutoVacLauncherMain, true)
+PG_PROCTYPE(B_AUTOVAC_WORKER, gettext_noop("autovacuum worker"), AutoVacWorkerMain, true)
+PG_PROCTYPE(B_BACKEND, gettext_noop("client backend"), BackendMain, true)
+PG_PROCTYPE(B_BG_WORKER, gettext_noop("background worker"), BackgroundWorkerMain, true)
+PG_PROCTYPE(B_BG_WRITER, gettext_noop("background writer"), BackgroundWriterMain, true)
+PG_PROCTYPE(B_CHECKPOINTER, gettext_noop("checkpointer"), CheckpointerMain, true)
+PG_PROCTYPE(B_DEAD_END_BACKEND, gettext_noop("dead-end client backend"), BackendMain, true)
+PG_PROCTYPE(B_INVALID, gettext_noop("unrecognized"), NULL, false)
+PG_PROCTYPE(B_IO_WORKER, gettext_noop("io worker"), IoWorkerMain, true)
+PG_PROCTYPE(B_LOGGER, gettext_noop("syslogger"), SysLoggerMain, false)
+PG_PROCTYPE(B_SLOTSYNC_WORKER, gettext_noop("slotsync worker"), ReplSlotSyncWorkerMain, true)
+PG_PROCTYPE(B_STANDALONE_BACKEND, gettext_noop("standalone backend"), NULL, false)
+PG_PROCTYPE(B_STARTUP, gettext_noop("startup"), StartupProcessMain, true)
+PG_PROCTYPE(B_WAL_RECEIVER, gettext_noop("walreceiver"), WalReceiverMain, true)
+PG_PROCTYPE(B_WAL_SENDER, gettext_noop("walsender"), NULL, true)
+PG_PROCTYPE(B_WAL_SUMMARIZER, gettext_noop("walsummarizer"), WalSummarizerMain, true)
+PG_PROCTYPE(B_WAL_WRITER, gettext_noop("walwriter"), WalWriterMain, true)
-- 
2.48.1

From 2678b810ad212ae36a28d481ace180ca05d498bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <[email protected]>
Date: Mon, 28 Jul 2025 20:56:20 +0200
Subject: [PATCH 2/3] LogChildExit / HandleChildCrash support

(Didn't actually test that bgworkers are doing the expected thing!)

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
---
 src/backend/postmaster/postmaster.c           | 121 +++++++++---------
 src/test/perl/PostgreSQL/Test/Cluster.pm      |   2 +-
 .../postmaster/t/002_connection_limits.pl     |   2 +-
 3 files changed, 63 insertions(+), 62 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index e1d643b013d..83cea73fb6c 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -428,8 +428,8 @@ static void process_pm_reload_request(void);
 static void process_pm_shutdown_request(void);
 static void dummy_handler(SIGNAL_ARGS);
 static void CleanupBackend(PMChild *bp, int exitstatus);
-static void HandleChildCrash(int pid, int exitstatus, const char *procname);
-static void LogChildExit(int lev, const char *procname,
+static void HandleChildCrash(int pid, int exitstatus, BackendType proctype, const char *addtype);
+static void LogChildExit(int lev, BackendType proctype, const char *addtype,
 						 int pid, int exitstatus);
 static void PostmasterStateMachine(void);
 static void UpdatePMState(PMState newState);
@@ -2288,8 +2288,7 @@ process_pm_child_exit(void)
 				StartupStatus != STARTUP_SIGNALED &&
 				!EXIT_STATUS_0(exitstatus))
 			{
-				LogChildExit(LOG, _("startup process"),
-							 pid, exitstatus);
+				LogChildExit(LOG, B_STARTUP, NULL, pid, exitstatus);
 				ereport(LOG,
 						(errmsg("aborting startup due to startup process failure")));
 				ExitPostmaster(1);
@@ -2323,8 +2322,7 @@ process_pm_child_exit(void)
 				}
 				else
 					StartupStatus = STARTUP_CRASHED;
-				HandleChildCrash(pid, exitstatus,
-								 _("startup process"));
+				HandleChildCrash(pid, exitstatus, B_STARTUP, NULL);
 				continue;
 			}
 
@@ -2368,8 +2366,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(BgWriterPMChild);
 			BgWriterPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("background writer process"));
+				HandleChildCrash(pid, exitstatus, B_BG_WRITER, NULL);
 			continue;
 		}
 
@@ -2401,8 +2398,7 @@ process_pm_child_exit(void)
 				 * Any unexpected exit of the checkpointer (including FATAL
 				 * exit) is treated as a crash.
 				 */
-				HandleChildCrash(pid, exitstatus,
-								 _("checkpointer process"));
+				HandleChildCrash(pid, exitstatus, B_CHECKPOINTER, NULL);
 			}
 
 			continue;
@@ -2418,8 +2414,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(WalWriterPMChild);
 			WalWriterPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("WAL writer process"));
+				HandleChildCrash(pid, exitstatus, B_WAL_WRITER, NULL);
 			continue;
 		}
 
@@ -2434,8 +2429,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(WalReceiverPMChild);
 			WalReceiverPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("WAL receiver process"));
+				HandleChildCrash(pid, exitstatus, B_WAL_RECEIVER, NULL);
 			continue;
 		}
 
@@ -2449,8 +2443,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(WalSummarizerPMChild);
 			WalSummarizerPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("WAL summarizer process"));
+				HandleChildCrash(pid, exitstatus, B_WAL_SUMMARIZER, NULL);
 			continue;
 		}
 
@@ -2465,8 +2458,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(AutoVacLauncherPMChild);
 			AutoVacLauncherPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("autovacuum launcher process"));
+				HandleChildCrash(pid, exitstatus, B_AUTOVAC_LAUNCHER, NULL);
 			continue;
 		}
 
@@ -2481,8 +2473,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(PgArchPMChild);
 			PgArchPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("archiver process"));
+				HandleChildCrash(pid, exitstatus, B_ARCHIVER, NULL);
 			continue;
 		}
 
@@ -2497,8 +2488,7 @@ process_pm_child_exit(void)
 				StartSysLogger();
 
 			if (!EXIT_STATUS_0(exitstatus))
-				LogChildExit(LOG, _("system logger process"),
-							 pid, exitstatus);
+				LogChildExit(LOG, B_LOGGER, NULL, pid, exitstatus);
 			continue;
 		}
 
@@ -2514,8 +2504,7 @@ process_pm_child_exit(void)
 			ReleasePostmasterChildSlot(SlotSyncWorkerPMChild);
 			SlotSyncWorkerPMChild = NULL;
 			if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
-				HandleChildCrash(pid, exitstatus,
-								 _("slot sync worker process"));
+				HandleChildCrash(pid, exitstatus, B_SLOTSYNC_WORKER, NULL);
 			continue;
 		}
 
@@ -2523,7 +2512,7 @@ process_pm_child_exit(void)
 		if (maybe_reap_io_worker(pid))
 		{
 			if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
-				HandleChildCrash(pid, exitstatus, _("io worker"));
+				HandleChildCrash(pid, exitstatus, B_IO_WORKER, NULL);
 
 			maybe_adjust_io_workers();
 			continue;
@@ -2545,9 +2534,9 @@ process_pm_child_exit(void)
 		else
 		{
 			if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
-				HandleChildCrash(pid, exitstatus, _("untracked child process"));
+				HandleChildCrash(pid, exitstatus, B_INVALID, NULL);
 			else
-				LogChildExit(LOG, _("untracked child process"), pid, exitstatus);
+				LogChildExit(LOG, B_INVALID, NULL, pid, exitstatus);
 		}
 	}							/* loop over pending child-death reports */
 
@@ -2568,8 +2557,8 @@ static void
 CleanupBackend(PMChild *bp,
 			   int exitstatus)	/* child's exit status. */
 {
-	char		namebuf[MAXPGPATH];
-	const char *procname;
+	char  		namebuf[MAXPGPATH];
+	char	   *procname;
 	bool		crashed = false;
 	bool		logged = false;
 	pid_t		bp_pid;
@@ -2578,14 +2567,13 @@ CleanupBackend(PMChild *bp,
 	RegisteredBgWorker *rw;
 
 	/* Construct a process name for the log message */
-	if (bp->bkend_type == B_BG_WORKER)
+	if (bp && bp->bkend_type == B_BG_WORKER && bp->rw)
 	{
-		snprintf(namebuf, MAXPGPATH, _("background worker \"%s\""),
-				 bp->rw->rw_worker.bgw_type);
+		strlcpy(namebuf, bp->rw->rw_worker.bgw_type, MAXPGPATH);
 		procname = namebuf;
 	}
 	else
-		procname = _(GetBackendTypeDesc(bp->bkend_type));
+		procname = NULL;
 
 	/*
 	 * If a backend dies in an ugly way then we must signal all other backends
@@ -2607,7 +2595,7 @@ CleanupBackend(PMChild *bp,
 	 */
 	if (exitstatus == ERROR_WAIT_NO_CHILDREN)
 	{
-		LogChildExit(LOG, procname, bp->pid, exitstatus);
+		LogChildExit(LOG, bp->bkend_type, procname, bp->pid, exitstatus);
 		logged = true;
 		crashed = false;
 	}
@@ -2642,7 +2630,7 @@ CleanupBackend(PMChild *bp,
 	 */
 	if (crashed)
 	{
-		HandleChildCrash(bp_pid, exitstatus, procname);
+		HandleChildCrash(bp_pid, exitstatus, bp_bkend_type, procname);
 		return;
 	}
 
@@ -2680,7 +2668,7 @@ CleanupBackend(PMChild *bp,
 		if (!logged)
 		{
 			LogChildExit(EXIT_STATUS_0(exitstatus) ? DEBUG1 : LOG,
-						 procname, bp_pid, exitstatus);
+						 bp_bkend_type, procname, bp_pid, exitstatus);
 			logged = true;
 		}
 
@@ -2689,7 +2677,7 @@ CleanupBackend(PMChild *bp,
 	}
 
 	if (!logged)
-		LogChildExit(DEBUG2, procname, bp_pid, exitstatus);
+		LogChildExit(DEBUG2, bp_bkend_type, procname, bp_pid, exitstatus);
 }
 
 /*
@@ -2781,8 +2769,8 @@ HandleFatalError(QuitSignalReason reason, bool consider_sigabrt)
 }
 
 /*
- * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer,
- * walwriter, autovacuum, archiver, slot sync worker, or background worker.
+ * HandleChildCrash -- cleanup after failed backend or certain auxiliary
+ * processes.
  *
  * The objectives here are to clean up our local state about the child
  * process, and to signal all other remaining children to quickdie.
@@ -2790,7 +2778,7 @@ HandleFatalError(QuitSignalReason reason, bool consider_sigabrt)
  * The caller has already released its PMChild slot.
  */
 static void
-HandleChildCrash(int pid, int exitstatus, const char *procname)
+HandleChildCrash(int pid, int exitstatus, BackendType proctype, const char *addtype)
 {
 	/*
 	 * We only log messages and send signals if this is the first process
@@ -2802,7 +2790,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 	if (FatalError || Shutdown == ImmediateShutdown)
 		return;
 
-	LogChildExit(LOG, procname, pid, exitstatus);
+	LogChildExit(LOG, proctype, addtype, pid, exitstatus);
 	ereport(LOG,
 			(errmsg("terminating any other active server processes")));
 
@@ -2815,9 +2803,13 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 
 /*
  * Log the death of a child process.
+ *
+ * 'addtype' is an additional word or short phrase that describes the process,
+ * such as a background worker 'type'.
  */
 static void
-LogChildExit(int lev, const char *procname, int pid, int exitstatus)
+LogChildExit(int lev, BackendType proctype, const char *addtype, int pid,
+			 int exitstatus)
 {
 	/*
 	 * size of activity_buffer is arbitrary, but set equal to default
@@ -2832,14 +2824,13 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
 													   sizeof(activity_buffer));
 
 	if (WIFEXITED(exitstatus))
-		ereport(lev,
+		ereport(lev, addtype ?
+				errmsg("\"%s\" process of type \"%s\" (PID %d) exited with exit code %d",
+					   GetBackendTypeDesc(proctype), addtype, pid, WEXITSTATUS(exitstatus)) :
+				errmsg("process of type \"%s\" (PID %d) exited with exit code %d",
+					   GetBackendTypeDesc(proctype), pid, WEXITSTATUS(exitstatus)),
 
-		/*------
-		  translator: %s is a noun phrase describing a child process, such as
-		  "server process" */
-				(errmsg("%s (PID %d) exited with exit code %d",
-						procname, pid, WEXITSTATUS(exitstatus)),
-				 activity ? errdetail("Failed process was running: %s", activity) : 0));
+				activity ? errdetail("Failed process was running: %s", activity) : 0);
 	else if (WIFSIGNALED(exitstatus))
 	{
 #if defined(WIN32)
@@ -2848,20 +2839,27 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
 		/*------
 		  translator: %s is a noun phrase describing a child process, such as
 		  "server process" */
-				(errmsg("%s (PID %d) was terminated by exception 0x%X",
-						procname, pid, WTERMSIG(exitstatus)),
-				 errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
-				 activity ? errdetail("Failed process was running: %s", activity) : 0));
+				addtype ?
+				errmsg("\"%s\" process of type \"%s\" (PID %d) was terminated by exception 0x%X",
+					   GetBackendTypeDesc(proctype), addtype, pid, WTERMSIG(exitstatus)) :
+				errmsg("\"%s\" process (PID %d) was terminated by exception 0x%X",
+					   GetBackendTypeDesc(proctype), addtype, pid, WTERMSIG(exitstatus)),
+				errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
+				activity ? errdetail("Failed process was running: %s", activity) : 0);
 #else
 		ereport(lev,
 
 		/*------
 		  translator: %s is a noun phrase describing a child process, such as
 		  "server process" */
-				(errmsg("%s (PID %d) was terminated by signal %d: %s",
-						procname, pid, WTERMSIG(exitstatus),
-						pg_strsignal(WTERMSIG(exitstatus))),
-				 activity ? errdetail("Failed process was running: %s", activity) : 0));
+				addtype ?
+				errmsg("\"%s\" process of type \"%s\" (PID %d) was terminated by signal %d: %s",
+					   GetBackendTypeDesc(proctype), addtype, pid, WTERMSIG(exitstatus),
+					   pg_strsignal(WTERMSIG(exitstatus))) :
+				errmsg("\"%s\" process (PID %d) was terminated by signal %d: %s",
+					   GetBackendTypeDesc(proctype), pid, WTERMSIG(exitstatus),
+					   pg_strsignal(WTERMSIG(exitstatus))),
+				activity ? errdetail("Failed process was running: %s", activity) : 0);
 #endif
 	}
 	else
@@ -2870,9 +2868,12 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus)
 		/*------
 		  translator: %s is a noun phrase describing a child process, such as
 		  "server process" */
-				(errmsg("%s (PID %d) exited with unrecognized status %d",
-						procname, pid, exitstatus),
-				 activity ? errdetail("Failed process was running: %s", activity) : 0));
+				addtype ?
+				errmsg("\"%s\" process of type \"%s\" (PID %d) exited with unrecognized status %d",
+					   GetBackendTypeDesc(proctype), addtype, pid, exitstatus) :
+				errmsg("\"%s\" process (PID %d) exited with unrecognized status %d",
+					   GetBackendTypeDesc(proctype), pid, exitstatus),
+				activity ? errdetail("Failed process was running: %s", activity) : 0);
 }
 
 /*
diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm
index 35413f14019..92c5b06868f 100644
--- a/src/test/perl/PostgreSQL/Test/Cluster.pm
+++ b/src/test/perl/PostgreSQL/Test/Cluster.pm
@@ -2696,7 +2696,7 @@ sub connect_fails
 	if (defined($params{log_like}) or defined($params{log_unlike}))
 	{
 		$self->wait_for_log(
-			qr/DEBUG:  (?:00000: )?forked new client backend, pid=(\d+) socket.*DEBUG:  (?:00000: )?client backend \(PID \1\) exited with exit code \d/s,
+			qr/DEBUG:  (?:00000: )?forked new client backend, pid=(\d+) socket.*DEBUG:  (?:00000: )?process of type \"client backend\" \(PID \1\) exited with exit code \d/s,
 			$log_location);
 
 		$self->log_check($test_name, $log_location, %params);
diff --git a/src/test/postmaster/t/002_connection_limits.pl b/src/test/postmaster/t/002_connection_limits.pl
index 4a7fb16261f..a67ae77d59a 100644
--- a/src/test/postmaster/t/002_connection_limits.pl
+++ b/src/test/postmaster/t/002_connection_limits.pl
@@ -69,7 +69,7 @@ sub connect_fails_wait
 
 	$node->connect_fails($connstr, $test_name, %params);
 	$node->wait_for_log(
-		qr/DEBUG:  (00000: )?client backend.*exited with exit code 1/,
+		qr/DEBUG:  (00000: )?process of type "client backend".*exited with exit code 1/,
 		$log_location);
 	ok(1, "$test_name: client backend process exited");
 }
-- 
2.48.1

Reply via email to