diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 46a778f0917..73450fe437e 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -300,22 +300,18 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
 		 */
 		if (ProcDiePending)
 		{
-			/*
-			 * ProcDieSenderPid/Uid are read directly from the globals here
-			 * rather than copied to locals first; a second SIGTERM could
-			 * change them between reads, but that is harmless because the
-			 * process is about to die anyway.  The signal sender detail is
-			 * inlined rather than using a separate errdetail() call because
-			 * it must be appended to the existing detail message.
-			 */
-			ereport(WARNING,
-					(errcode(ERRCODE_ADMIN_SHUTDOWN),
-					 errmsg("canceling the wait for synchronous replication and terminating connection due to administrator command"),
-					 errdetail("The transaction has already committed locally, but might not have been replicated to the standby.%s",
-							   ProcDieSenderPid == 0 ? "" :
-							   psprintf("\nSignal sent by PID %d, UID %d.",
-										(int) ProcDieSenderPid,
-										(int) ProcDieSenderUid))));
+			if (ProcDieSenderPid != 0)
+				ereport(WARNING,
+						(errcode(ERRCODE_ADMIN_SHUTDOWN),
+						 errmsg("canceling the wait for synchronous replication and terminating connection due to administrator command"),
+						 errdetail("The transaction has already committed locally, but might not have been replicated to the standby.  Signal sent by PID %d, UID %d.",
+								   (int) ProcDieSenderPid,
+								   (int) ProcDieSenderUid)));
+			else
+				ereport(WARNING,
+						(errcode(ERRCODE_ADMIN_SHUTDOWN),
+						 errmsg("canceling the wait for synchronous replication and terminating connection due to administrator command"),
+						 errdetail("The transaction has already committed locally, but might not have been replicated to the standby.")));
 			whereToSendOutput = DestNone;
 			SyncRepCancelWait();
 			break;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 14a061599bc..a9140492dcb 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3024,6 +3024,20 @@ die(SIGNAL_ARGS)
 	/* Don't joggle the elbow of proc_exit */
 	if (!proc_exit_inprogress)
 	{
+		int			sender_pid;
+		int			sender_uid;
+
+		if (pqsignal_get_sender(postgres_signal_arg, &sender_pid, &sender_uid))
+		{
+			ProcDieSenderPid = sender_pid;
+			ProcDieSenderUid = sender_uid;
+		}
+		else
+		{
+			ProcDieSenderPid = 0;
+			ProcDieSenderUid = 0;
+		}
+
 		InterruptPending = true;
 		ProcDiePending = true;
 	}
diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h
index 9f494a1fdf9..2ca32aee59e 100644
--- a/src/include/libpq/pqsignal.h
+++ b/src/include/libpq/pqsignal.h
@@ -50,5 +50,8 @@ extern PGDLLIMPORT sigset_t BlockSig;
 extern PGDLLIMPORT sigset_t StartupBlockSig;
 
 extern void pqinitmask(void);
+#ifndef FRONTEND
+extern bool pqsignal_get_sender(int signo, int *sender_pid, int *sender_uid);
+#endif
 
 #endif							/* PQSIGNAL_H */
diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c
index 8841464b5cb..8cb609e58d8 100644
--- a/src/port/pqsignal.c
+++ b/src/port/pqsignal.c
@@ -70,6 +70,11 @@ StaticAssertDecl(SIGTERM < PG_NSIG, "SIGTERM >= PG_NSIG");
 StaticAssertDecl(SIGALRM < PG_NSIG, "SIGALRM >= PG_NSIG");
 
 static volatile pqsigfunc pqsignal_handlers[PG_NSIG];
+#if !defined(FRONTEND) && defined(HAVE_SA_SIGINFO)
+static volatile sig_atomic_t pqsignal_has_sender[PG_NSIG];
+static volatile sig_atomic_t pqsignal_sender_pid[PG_NSIG];
+static volatile sig_atomic_t pqsignal_sender_uid[PG_NSIG];
+#endif
 
 /*
  * Except when called with SIG_IGN or SIG_DFL, pqsignal() sets up this function
@@ -116,16 +121,22 @@ wrapper_handler(SIGNAL_ARGS)
 	}
 
 #ifdef HAVE_SA_SIGINFO
-	if (signo == SIGTERM && info)
+	if (info)
 	{
-		ProcDieSenderPid = info->si_pid;
-		ProcDieSenderUid = info->si_uid;
+		pqsignal_has_sender[postgres_signal_arg] = 1;
+		pqsignal_sender_pid[postgres_signal_arg] = info->si_pid;
+		pqsignal_sender_uid[postgres_signal_arg] = info->si_uid;
 	}
+	else
+		pqsignal_has_sender[postgres_signal_arg] = 0;
 #endif
 #endif
 
 	(*pqsignal_handlers[postgres_signal_arg]) (postgres_signal_arg);
 
+#if !defined(FRONTEND) && defined(HAVE_SA_SIGINFO)
+	pqsignal_has_sender[postgres_signal_arg] = 0;
+#endif
 	errno = save_errno;
 }
 
@@ -180,3 +191,25 @@ pqsignal(int signo, pqsigfunc func)
 		Assert(false);			/* probably indicates coding error */
 #endif
 }
+
+/*
+ * Return sender PID/UID for currently-dispatched signal if available.
+ */
+#ifndef FRONTEND
+bool
+pqsignal_get_sender(int signo, int *sender_pid, int *sender_uid)
+{
+#ifdef HAVE_SA_SIGINFO
+	if (signo <= 0 || signo >= PG_NSIG || !pqsignal_has_sender[signo])
+		return false;
+
+	if (sender_pid)
+		*sender_pid = (int) pqsignal_sender_pid[signo];
+	if (sender_uid)
+		*sender_uid = (int) pqsignal_sender_uid[signo];
+	return true;
+#else
+	return false;
+#endif
+}
+#endif
