From b26a2631e66dccdb822ecbcfef88b940e97898ec Mon Sep 17 00:00:00 2001
From: "suyu.cmj" <mengjuan.cmj@alibaba-inc.com>
Date: Fri, 3 Sep 2021 12:11:50 +0800
Subject: [PATCH] Add guc parameter to enable send SIGSTOP to peers when
 backend exits abnormally

---
 src/backend/postmaster/postmaster.c | 25 ++++++++++++++++++++++---
 src/backend/utils/misc/guc.c        | 18 ++++++++++++++++++
 src/include/postmaster/postmaster.h |  1 +
 src/include/utils/guc.h             |  2 ++
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 9c2c98614a..183c16606f 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -223,7 +223,7 @@ static pgsocket ListenSocket[MAXLISTEN];
 /*
  * These globals control the behavior of the postmaster in case some
  * backend dumps core.  Normally, it kills all peers of the dead backend
- * and reinitializes shared memory.  By specifying -s or -n, we can have
+ * and reinitializes shared memory.  By specifying -T or -n, we can have
  * the postmaster stop (rather than kill) peers and not reinitialize
  * shared data structures.  (Reinit is currently dead code, though.)
  */
@@ -816,6 +816,12 @@ PostmasterMain(int argc, char *argv[])
 				 * post_hacker collect core dumps from everyone.
 				 */
 				SendStop = true;
+				/* 
+				 * set guc parameter enable_send_stop at the same time when specified -T on command line.
+				 * avoid the value of SendStop being reset by enable_send_stop in postgresql.conf
+				 * the priority of setting guc parameter by command line is higher than that by postgresql.conf
+				 */
+				SetConfigOption("enable_send_stop", "true", PGC_POSTMASTER, PGC_S_ARGV);
 				break;
 
 			case 't':
@@ -3501,7 +3507,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 			 *
 			 * SIGQUIT is the special signal that says exit without proc_exit
 			 * and let the user know what's going on. But if SendStop is set
-			 * (-T on command line), then we send SIGSTOP instead, so that we
+			 * (-T on command line or set guc parameter enable_send_stop), 
+			 * then we send SIGSTOP instead, so that we
 			 * can get core dumps from all backends by hand.
 			 */
 			if (take_action)
@@ -3544,7 +3551,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
 			 *
 			 * SIGQUIT is the special signal that says exit without proc_exit
 			 * and let the user know what's going on. But if SendStop is set
-			 * (-T on command line), then we send SIGSTOP instead, so that we
+			 * (-T on command line or set guc parameter enable_send_stop), 
+			 * then we send SIGSTOP instead, so that we
 			 * can get core dumps from all backends by hand.
 			 *
 			 * We could exclude dead_end children here, but at least in the
@@ -6616,3 +6624,14 @@ InitPostmasterDeathWatchHandle(void)
 								 GetLastError())));
 #endif							/* WIN32 */
 }
+
+
+/*
+ * set value of SendStop according to guc parameter enable_send_stop
+ * so that it can be set not only by specifying -T when start postgres
+ */
+void
+assign_enable_send_stop(bool newval, void *extra)
+{
+	SendStop = newval;
+}
\ No newline at end of file
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 29851119f1..a6ca8511b4 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -584,6 +584,7 @@ char	   *event_source;
 
 bool		row_security;
 bool		check_function_bodies = true;
+bool		enable_send_stop = false;
 
 /*
  * This GUC exists solely for backward compatibility, check its definition for
@@ -2116,6 +2117,23 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	/*
+	 * In the event that some backend dumps core, send SIGSTOP rather than SIGQUIT
+	 * to all its peers, this lets the wily post_hacker collect core dumps from everyone.
+	 * in original way, this is set with -T parameter when start postgres
+	 * changes to set via guc parameter enable_send_stop
+	 */
+	{
+		{"enable_send_stop", PGC_SIGHUP, UNGROUPED,
+			gettext_noop("Enable to send SIGSTOP to all peers when some backend exit abnormally"),
+			NULL,
+			GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL
+		},
+		&enable_send_stop,
+		false,
+		NULL, assign_enable_send_stop, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index 0efdd7c232..77056f7a6e 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -54,6 +54,7 @@ extern void InitProcessGlobals(void);
 extern int	MaxLivePostmasterChildren(void);
 
 extern bool PostmasterMarkPIDForWorkerNotify(int);
+extern void assign_enable_send_stop(bool newval, void *extra);
 
 #ifdef EXEC_BACKEND
 extern pid_t postmaster_forkexec(int argc, char *argv[]);
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index a7c3a4958e..feec65cb16 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -282,6 +282,8 @@ extern int	tcp_user_timeout;
 extern bool trace_sort;
 #endif
 
+extern bool enable_send_stop;
+
 /*
  * Functions exported by guc.c
  */
-- 
2.24.3 (Apple Git-128)

