diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c
index 46a778f0917..896ba45412d 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 4fb18741dc5..e02125e720e 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3025,6 +3025,8 @@ die(SIGNAL_ARGS)
 	{
 		InterruptPending = true;
 		ProcDiePending = true;
+		ProcDieSenderPid = SignalSenderPid;
+		ProcDieSenderUid = SignalSenderUid;
 	}
 
 	/* for the cumulative stats system */
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index ba8cd99d98d..bc517b009cb 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -43,6 +43,8 @@ volatile sig_atomic_t IdleStatsUpdateTimeoutPending = false;
 volatile uint32 InterruptHoldoffCount = 0;
 volatile uint32 QueryCancelHoldoffCount = 0;
 volatile uint32 CritSectionCount = 0;
+volatile int SignalSenderPid = 0;
+volatile int SignalSenderUid = 0;
 volatile int ProcDieSenderPid = 0;
 volatile int ProcDieSenderUid = 0;
 
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index b6f625e10a6..655b42103ca 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -90,6 +90,8 @@
 extern PGDLLIMPORT volatile sig_atomic_t InterruptPending;
 extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending;
 extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending;
+extern PGDLLIMPORT volatile int SignalSenderPid;
+extern PGDLLIMPORT volatile int SignalSenderUid;
 extern PGDLLIMPORT volatile int ProcDieSenderPid;
 extern PGDLLIMPORT volatile int ProcDieSenderUid;
 extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending;
diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c
index 8841464b5cb..07985e704d5 100644
--- a/src/port/pqsignal.c
+++ b/src/port/pqsignal.c
@@ -84,17 +84,13 @@ static volatile pqsigfunc pqsignal_handlers[PG_NSIG];
  */
 #if !defined(FRONTEND) && defined(HAVE_SA_SIGINFO)
 static void
-wrapper_handler(int signo, siginfo_t * info, void *context)
+wrapper_handler(int postgres_signal_arg, siginfo_t *info, void *context)
 #else
 static void
 wrapper_handler(SIGNAL_ARGS)
 #endif
 {
 	int			save_errno = errno;
-#if !defined(FRONTEND) && defined(HAVE_SA_SIGINFO)
-	/* SA_SIGINFO signature uses signo, not SIGNAL_ARGS macro */
-	int			postgres_signal_arg = signo;
-#endif
 
 	Assert(postgres_signal_arg > 0);
 	Assert(postgres_signal_arg < PG_NSIG);
@@ -116,10 +112,21 @@ wrapper_handler(SIGNAL_ARGS)
 	}
 
 #ifdef HAVE_SA_SIGINFO
-	if (signo == SIGTERM && info)
+	/*
+	 * Record the signal sender's PID and UID so that individual signal
+	 * handlers can use them if they wish.  These are only valid for the
+	 * duration of the handler call and will be overwritten by the next
+	 * signal.
+	 */
+	if (info)
 	{
-		ProcDieSenderPid = info->si_pid;
-		ProcDieSenderUid = info->si_uid;
+		SignalSenderPid = info->si_pid;
+		SignalSenderUid = info->si_uid;
+	}
+	else
+	{
+		SignalSenderPid = 0;
+		SignalSenderUid = 0;
 	}
 #endif
 #endif
