trap sigsegv and add backtrace

pull/4044/head
Sait Talha Nisanci 2020-07-21 12:29:27 +03:00
parent ea83823437
commit 8088fa9f36
4 changed files with 20 additions and 8 deletions

View File

@ -27,6 +27,7 @@
#include "commands/explain.h" #include "commands/explain.h"
#include "executor/executor.h" #include "executor/executor.h"
#include "distributed/backend_data.h" #include "distributed/backend_data.h"
#include "distributed/backtrace.h"
#include "distributed/citus_nodefuncs.h" #include "distributed/citus_nodefuncs.h"
#include "distributed/citus_safe_lib.h" #include "distributed/citus_safe_lib.h"
#include "distributed/commands.h" #include "distributed/commands.h"
@ -82,6 +83,8 @@
#include "utils/guc_tables.h" #include "utils/guc_tables.h"
#include "utils/varlena.h" #include "utils/varlena.h"
#include <signal.h>
/* marks shared object as one loadable by the postgres version compiled against */ /* marks shared object as one loadable by the postgres version compiled against */
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
@ -90,6 +93,7 @@ static char *CitusVersion = CITUS_VERSION;
void _PG_init(void); void _PG_init(void);
void handler(int sig);
static void ResizeStackToMaximumDepth(void); static void ResizeStackToMaximumDepth(void);
static void multi_log_hook(ErrorData *edata); static void multi_log_hook(ErrorData *edata);
@ -189,7 +193,10 @@ static const struct config_enum_entry multi_shard_modify_connection_options[] =
/* *INDENT-ON* */ /* *INDENT-ON* */
void handler(int sig) {
SignalBacktrace();
exit(1);
}
/* shared library initialization function */ /* shared library initialization function */
void void
_PG_init(void) _PG_init(void)
@ -292,6 +299,7 @@ _PG_init(void)
SetConfigOption("allow_system_table_mods", "true", PGC_POSTMASTER, SetConfigOption("allow_system_table_mods", "true", PGC_POSTMASTER,
PGC_S_OVERRIDE); PGC_S_OVERRIDE);
} }
signal(SIGSEGV, handler);
} }
@ -345,7 +353,6 @@ ResizeStackToMaximumDepth(void)
#endif #endif
} }
/* /*
* multi_log_hook intercepts postgres log commands. We use this to override * multi_log_hook intercepts postgres log commands. We use this to override
* postgres error messages when they're not specific enough for the users. * postgres error messages when they're not specific enough for the users.

View File

@ -22,7 +22,7 @@ static int BacktraceFullCallback(void *data, uintptr_t pc,
static void BacktraceErrorCallback(void *data, const char *msg, int errnum); static void BacktraceErrorCallback(void *data, const char *msg, int errnum);
static void InitBackTrace(void); static void InitBackTrace(void);
static bool ShouldLogBacktrace(int elevel); static bool ShouldLogBacktrace(int elevel);
static char * GenerateBackTrace(void); static char * GenerateBackTrace(int);
static struct backtrace_state *backTracestate; static struct backtrace_state *backTracestate;
@ -50,17 +50,22 @@ Backtrace(int elevel)
{ {
return; return;
} }
errdetail("%s", GenerateBackTrace()); errdetail("%s", GenerateBackTrace(BACKTRACE_SKIP));
} }
void AssertBacktrace(void) { void AssertBacktrace(void) {
const char * backtrace = GenerateBackTrace(); const char * backtrace = GenerateBackTrace(BACKTRACE_SKIP);
ereport(ERROR, (errmsg("%s", backtrace))); ereport(ERROR, (errmsg("%s", backtrace)));
} }
void SignalBacktrace(void) {
const char * backtrace = GenerateBackTrace(BACKTRACE_SKIP + 1);
ereport(WARNING, (errmsg("%s", backtrace)));
}
static char * static char *
GenerateBackTrace(void) GenerateBackTrace(int skipAmount)
{ {
if (backTracestate == NULL) if (backTracestate == NULL)
{ {
@ -69,7 +74,7 @@ GenerateBackTrace(void)
StringInfo msgWithBacktrace = makeStringInfo(); StringInfo msgWithBacktrace = makeStringInfo();
appendStringInfoString(msgWithBacktrace, BACKTRACE_HEADER); appendStringInfoString(msgWithBacktrace, BACKTRACE_HEADER);
backtrace_full(backTracestate, BACKTRACE_SKIP, BacktraceFullCallback, backtrace_full(backTracestate, skipAmount, BacktraceFullCallback,
BacktraceErrorCallback, msgWithBacktrace); BacktraceErrorCallback, msgWithBacktrace);
return msgWithBacktrace->data; return msgWithBacktrace->data;

View File

@ -13,5 +13,6 @@
void Backtrace(int elevel); void Backtrace(int elevel);
void AssertBacktrace(void); void AssertBacktrace(void);
void SignalBacktrace(void);
#endif #endif

View File

@ -70,7 +70,6 @@ extern char * HashLogMessage(const char *text);
#define Trap(condition, errorType) \ #define Trap(condition, errorType) \
do { \ do { \
if (condition) { \ if (condition) { \
AssertBacktrace(); \
ExceptionalCondition(CppAsString(condition), (errorType), \ ExceptionalCondition(CppAsString(condition), (errorType), \
__FILE__, __LINE__); \ __FILE__, __LINE__); \
} \ } \