From 21b342dd03237e48389096b9181bf95075c6c28d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 4 Dec 2019 16:34:41 +0100
Subject: [PATCH v2] Print backtrace on SIGABRT, SIGBUS, SIGSEGV

This removes the backtrace code from the assertion handling, since
that is now also handled by the SIGABRT signal handler.
---
 src/backend/postmaster/postmaster.c | 35 +++++++++++++++++++++++++++++
 src/backend/utils/error/assert.c    | 14 ------------
 2 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index bb22b13ade..b90aa62fb2 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -77,6 +77,14 @@
 #include <netdb.h>
 #include <limits.h>
 
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
 #ifdef USE_BONJOUR
 #include <dns_sd.h>
 #endif
@@ -419,6 +427,7 @@ static void process_pm_child_exit(void);
 static void process_pm_reload_request(void);
 static void process_pm_shutdown_request(void);
 static void dummy_handler(SIGNAL_ARGS);
+static void abort_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,
@@ -547,6 +556,10 @@ PostmasterMain(int argc, char *argv[])
 	pqsignal(SIGUSR2, dummy_handler);	/* unused, reserve for children */
 	pqsignal(SIGCHLD, handle_pm_child_exit_signal);
 
+	pqsignal(SIGABRT, abort_handler);
+	pqsignal(SIGBUS, abort_handler);
+	pqsignal(SIGSEGV, abort_handler);
+
 	/* This may configure SIGURG, depending on platform. */
 	InitializeLatchSupport();
 	InitProcessLocalLatch();
@@ -3820,6 +3833,28 @@ process_pm_pmsignal(void)
 	}
 }
 
+/*
+ * Signal handler for SIGABRT, SIGBUS, SIGSEGV
+ *
+ * If supported, print stack trace, then continue with normal signal handler.
+ */
+static void
+abort_handler(SIGNAL_ARGS)
+{
+#ifdef HAVE_BACKTRACE_SYMBOLS
+	{
+		void	   *buf[100];
+		int			nframes;
+
+		nframes = backtrace(buf, lengthof(buf));
+		backtrace_symbols_fd(buf, nframes, fileno(stderr));
+	}
+#endif
+
+	pqsignal(postgres_signal_arg, SIG_DFL);
+	raise(postgres_signal_arg);
+}
+
 /*
  * Dummy signal handler
  *
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
index 84b94f5e5f..3570648d7e 100644
--- a/src/backend/utils/error/assert.c
+++ b/src/backend/utils/error/assert.c
@@ -15,9 +15,6 @@
 #include "postgres.h"
 
 #include <unistd.h>
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
 
 /*
  * ExceptionalCondition - Handles the failure of an Assert()
@@ -43,17 +40,6 @@ ExceptionalCondition(const char *conditionName,
 	/* Usually this shouldn't be needed, but make sure the msg went out */
 	fflush(stderr);
 
-	/* If we have support for it, dump a simple backtrace */
-#ifdef HAVE_BACKTRACE_SYMBOLS
-	{
-		void	   *buf[100];
-		int			nframes;
-
-		nframes = backtrace(buf, lengthof(buf));
-		backtrace_symbols_fd(buf, nframes, fileno(stderr));
-	}
-#endif
-
 	/*
 	 * If configured to do so, sleep indefinitely to allow user to attach a
 	 * debugger.  It would be nice to use pg_usleep() here, but that can sleep
-- 
2.39.5 (Apple Git-154)

