mirror of https://github.com/citusdata/citus.git
76 lines
1.9 KiB
C
76 lines
1.9 KiB
C
/*
|
|
* backtrace.c
|
|
*
|
|
* Utilities related to backtrace
|
|
*
|
|
* Copyright (c) Citus Data, Inc.
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
#include "backtrace.h"
|
|
#include "backtrace-supported.h"
|
|
#include "lib/stringinfo.h"
|
|
|
|
#include "distributed/backtrace.h"
|
|
|
|
#define BACKTRACE_HEADER "\nBACKTRACE:\n"
|
|
#define BACKTRACE_SKIP 2
|
|
|
|
static int BacktraceFullCallback(void *data, uintptr_t pc,
|
|
const char *filename, int lineno,
|
|
const char *function);
|
|
|
|
static void BacktraceErrorCallback(void *data, const char *msg, int errnum);
|
|
static void InitBackTrace(void);
|
|
static bool ShouldLogBacktrace(int elevel);
|
|
static char* GenerateBackTrace(void);
|
|
|
|
static struct backtrace_state* backTracestate;
|
|
|
|
static void InitBackTrace(void) {
|
|
const char* filename = NULL;
|
|
void* data = NULL;
|
|
backTracestate = backtrace_create_state(filename, BACKTRACE_SUPPORTS_THREADS,
|
|
BacktraceErrorCallback, data);
|
|
}
|
|
|
|
static bool ShouldLogBacktrace(int elevel) {
|
|
return elevel >= ERROR;
|
|
}
|
|
|
|
|
|
void Backtrace(int elevel) {
|
|
if (!ShouldLogBacktrace(elevel)) {
|
|
return;
|
|
}
|
|
errdetail("%s", GenerateBackTrace());
|
|
}
|
|
|
|
static char* GenerateBackTrace(void) {
|
|
if (backTracestate == NULL) {
|
|
InitBackTrace();
|
|
}
|
|
StringInfo msgWithBacktrace = makeStringInfo();
|
|
|
|
appendStringInfoString(msgWithBacktrace, BACKTRACE_HEADER);
|
|
backtrace_full(backTracestate, BACKTRACE_SKIP, BacktraceFullCallback,
|
|
BacktraceErrorCallback, msgWithBacktrace);
|
|
|
|
return msgWithBacktrace->data;
|
|
}
|
|
|
|
static int BacktraceFullCallback(void *data, uintptr_t pc, const char *filename, int lineno,
|
|
const char *function) {
|
|
|
|
StringInfo str = (StringInfo) data;
|
|
if (function && filename) {
|
|
appendStringInfo(str, "%s:%s:%d\n",filename, function, lineno);
|
|
}
|
|
/* returning 0 means we will continue the backtrace */
|
|
return 0;
|
|
}
|
|
|
|
static void BacktraceErrorCallback(void *data, const char *msg, int errnum) {
|
|
// currently NO-OP
|
|
}
|