From 816cfc93d9e7123a77759e63edeb87832a258fc2 Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig.ringer@2ndquadrant.com>
Date: Wed, 9 Sep 2020 12:54:01 +0800
Subject: [PATCH v999 2/3] Show that it's not special casing of sigjmp_buf by
 using a wrapper struct

---
 src/backend/postmaster/autovacuum.c   |  8 ++++----
 src/backend/postmaster/bgworker.c     |  4 ++--
 src/backend/postmaster/bgwriter.c     |  4 ++--
 src/backend/postmaster/checkpointer.c |  4 ++--
 src/backend/postmaster/walwriter.c    |  4 ++--
 src/backend/tcop/postgres.c           |  4 ++--
 src/backend/utils/error/elog.c        |  5 +++--
 src/include/utils/elog.h              | 15 +++++++++++----
 8 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 1b8cd7bacd..c01953c642 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -431,7 +431,7 @@ StartAutoVacLauncher(void)
 NON_EXEC_STATIC void
 AutoVacLauncherMain(int argc, char *argv[])
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 
 	am_autovacuum_launcher = true;
 
@@ -496,7 +496,7 @@ AutoVacLauncherMain(int argc, char *argv[])
 	 *
 	 * This code is a stripped down version of PostgresMain error recovery.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
@@ -1502,7 +1502,7 @@ StartAutoVacWorker(void)
 NON_EXEC_STATIC void
 AutoVacWorkerMain(int argc, char *argv[])
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	Oid			dbid;
 
 	am_autovacuum_worker = true;
@@ -1552,7 +1552,7 @@ AutoVacWorkerMain(int argc, char *argv[])
 	 *
 	 * See notes in postgres.c about the design of this coding.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index d043ced686..d83c0c5309 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -679,7 +679,7 @@ bgworker_sigusr1_handler(SIGNAL_ARGS)
 void
 StartBackgroundWorker(void)
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	BackgroundWorker *worker = MyBgworkerEntry;
 	bgworker_main_type entrypt;
 
@@ -745,7 +745,7 @@ StartBackgroundWorker(void)
 	 *
 	 * We just need to clean up, report the error, and go away.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* Since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 069e27e427..14770c037b 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -93,7 +93,7 @@ static XLogRecPtr last_snapshot_lsn = InvalidXLogRecPtr;
 void
 BackgroundWriterMain(void)
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	MemoryContext bgwriter_context;
 	bool		prev_hibernate;
 	WritebackContext wb_context;
@@ -142,7 +142,7 @@ BackgroundWriterMain(void)
 	 *
 	 * See notes in postgres.c about the design of this coding.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* Since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 624a3238b8..259b57544b 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -182,7 +182,7 @@ static void ReqCheckpointHandler(SIGNAL_ARGS);
 void
 CheckpointerMain(void)
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	MemoryContext checkpointer_context;
 
 	CheckpointerShmem->checkpointer_pid = MyProcPid;
@@ -233,7 +233,7 @@ CheckpointerMain(void)
 	 *
 	 * See notes in postgres.c about the design of this coding.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* Since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 45a2757969..c96e37c7ad 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -87,7 +87,7 @@ int			WalWriterFlushAfter = 128;
 void
 WalWriterMain(void)
 {
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	MemoryContext walwriter_context;
 	int			left_till_hibernate;
 	bool		hibernating;
@@ -131,7 +131,7 @@ WalWriterMain(void)
 	 *
 	 * This code is heavily based on bgwriter.c, q.v.
 	 */
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/* Since not using PG_TRY, must reset error stack by hand */
 		error_context_stack = NULL;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c9424f167c..ab8a732d04 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -3780,7 +3780,7 @@ PostgresMain(int argc, char *argv[],
 {
 	int			firstchar;
 	StringInfoData input_message;
-	sigjmp_buf	local_sigjmp_buf;
+	PG_sigjmp_buf	local_sigjmp_buf;
 	volatile bool send_ready_for_query = true;
 	bool		disable_idle_in_transaction_timeout = false;
 
@@ -4039,7 +4039,7 @@ PostgresMain(int argc, char *argv[],
 	 * were inside a transaction.
 	 */
 
-	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
+	if (sigsetjmp(local_sigjmp_buf.buf, 1) != 0)
 	{
 		/*
 		 * NOTE: if you are tempted to add more code in this if-block,
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index d0b368530e..9af7155171 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -91,7 +91,7 @@
 /* Global variables */
 ErrorContextCallback *error_context_stack = NULL;
 
-sigjmp_buf *PG_exception_stack = NULL;
+PG_sigjmp_buf *PG_exception_stack = NULL;
 
 extern bool redirection_done;
 
@@ -589,6 +589,7 @@ errfinish(const char *filename, int lineno, const char *funcname)
 		 */
 		fflush(stdout);
 		fflush(stderr);
+
 		abort();
 	}
 
@@ -1714,7 +1715,7 @@ pg_re_throw(void)
 {
 	/* If possible, throw the error to the next outer setjmp handler */
 	if (PG_exception_stack != NULL)
-		siglongjmp(*PG_exception_stack, 1);
+		siglongjmp(PG_exception_stack->buf, 1);
 	else
 	{
 		/*
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 1e09ee0541..fe82225dbe 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -292,13 +292,20 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
  * warnings are just about entirely useless for catching such oversights.
  *----------
  */
+
+/* HACK for PoC with scan-build NOT FOR COMMIT */
+typedef struct PG_sigjmp_buf
+{
+	sigjmp_buf buf;
+} PG_sigjmp_buf;
+
 #define PG_TRY()  \
 	do { \
-		sigjmp_buf *_save_exception_stack = PG_exception_stack; \
+		PG_sigjmp_buf *_save_exception_stack = PG_exception_stack; \
 		ErrorContextCallback *_save_context_stack = error_context_stack; \
-		sigjmp_buf _local_sigjmp_buf; \
+		PG_sigjmp_buf _local_sigjmp_buf; \
 		bool _do_rethrow = false; \
-		if (sigsetjmp(_local_sigjmp_buf, 0) == 0) \
+		if (sigsetjmp(_local_sigjmp_buf.buf, 0) == 0) \
 		{ \
 			PG_exception_stack = &_local_sigjmp_buf
 
@@ -337,7 +344,7 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack;
 	(pg_re_throw(), pg_unreachable())
 #endif
 
-extern PGDLLIMPORT sigjmp_buf *PG_exception_stack;
+extern PGDLLIMPORT PG_sigjmp_buf *PG_exception_stack;
 
 
 /* Stuff that error handlers might want to use */
-- 
2.26.2

