citus/src/backend/distributed/utils/backtrace.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
}