debugger_on_self.patch
text/x-patch
Filename: debugger_on_self.patch
Type: text/x-patch
Part: 0
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index dca5efc..04cd900 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -5049,3 +5049,34 @@ InitPostmasterDeathWatchHandle(void)
(int) GetLastError())));
#endif /* WIN32 */
}
+
+/* Fork a gdb process such that it emits my stack trace to the logs */
+static void
+print_self_stack()
+{
+ char pid_buf[30];
+ int child_pid;
+
+ sprintf(pid_buf, "%d", getpid());
+ child_pid = fork();
+
+ if (child_pid == 0)
+ {
+ fprintf(stderr, "stack trace for %s pid=%s\n", my_exec_path, pid_buf);
+ execlp("gdb", "gdb", "--batch", "-n", "-ex", "bt", my_exec_path, pid_buf, NULL);
+ abort(); /* If gdb failed to start */
+ }
+ else
+ {
+ waitpid(child_pid,NULL,0);
+ }
+}
+
+/* SIGSEGV handler, controlled by GUC */
+void
+dump_stack(SIGNAL_ARGS)
+{
+ print_self_stack();
+
+ abort();
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5841631..7262839 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -40,6 +40,7 @@
#include "libpq/auth.h"
#include "libpq/be-fsstubs.h"
#include "libpq/pqformat.h"
+#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
#include "optimizer/geqo.h"
@@ -167,6 +168,10 @@ static bool call_enum_check_hook(struct config_enum * conf, int *newval,
static bool check_log_destination(char **newval, void **extra, GucSource source);
static void assign_log_destination(const char *newval, void *extra);
+bool dump_stack_on_crash = false;
+static bool check_dump_stack_on_crash(bool *newval, void **extra, GucSource source);
+static void assign_dump_stack_on_crash(bool newval, void *extra);
+
#ifdef HAVE_SYSLOG
static int syslog_facility = LOG_LOCAL0;
#else
@@ -1422,6 +1427,17 @@ static struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
+ {
+ {"dump_stack_on_crash", PGC_USERSET, ERROR_HANDLING_OPTIONS,
+ gettext_noop("Use GDB to dump the stack of a crashing backend process."),
+ gettext_noop("This requires that GDB be already installed and accessible to Postgres."),
+ },
+ "e_all_identifiers,
+ false,
+ check_dump_stack_on_crash, assign_dump_stack_on_crash, NULL
+ },
+
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
@@ -8672,4 +8688,35 @@ show_log_file_mode(void)
return buf;
}
+static bool
+check_dump_stack_on_crash(bool *newval, void **extra, GucSource source)
+{
+ /* TODO: Check if GDB is available. If not, then complain and return false */
+
+ char gdb_path[MAXPGPATH];
+
+ if (*newval == false)
+ return true;
+
+ Assert(*newval == true);
+
+ if (find_my_exec("gdb", gdb_path) < 0)
+ {
+ elog(WARNING, "Could not locate gdb.");
+
+ return false;
+ }
+ else
+ return true;
+}
+
+static void
+assign_dump_stack_on_crash(const bool newval, void *extra)
+{
+ if (newval)
+ pqsignal(SIGSEGV, dump_stack);
+ else
+ pqsignal(SIGSEGV, SIG_DFL);
+}
+
#include "guc-file.c"
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
index be4f8a7..f624d51 100644
--- a/src/include/postmaster/postmaster.h
+++ b/src/include/postmaster/postmaster.h
@@ -55,6 +55,8 @@ extern int SubPostmasterMain(int argc, char *argv[]);
extern Size ShmemBackendArraySize(void);
extern void ShmemBackendArrayAllocation(void);
+extern void dump_stack(SIGNAL_ARGS);
+
#endif
#endif /* _POSTMASTER_H */