Merge pull request #328 from EQ-Alpha/backtrace_for_alpine
Backtrace for alpine using libunwind Former-commit-id: 83d878f11183d8cd54fb34bceb7f839f73599ab1
This commit is contained in:
commit
31e2a22b6f
14
src/Makefile
14
src/Makefile
@ -127,7 +127,7 @@ ifneq ($(uname_S),Darwin)
|
|||||||
endif
|
endif
|
||||||
# Linux ARM32 needs -latomic at linking time
|
# Linux ARM32 needs -latomic at linking time
|
||||||
ifneq (,$(findstring armv,$(uname_M)))
|
ifneq (,$(findstring armv,$(uname_M)))
|
||||||
FINAL_LIBS+=-latomic
|
FINAL_LIBS+=-latomic
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ ifeq ($(uname_S),OpenBSD)
|
|||||||
FINAL_CXXFLAGS+= -DUSE_BACKTRACE -I/usr/local/include
|
FINAL_CXXFLAGS+= -DUSE_BACKTRACE -I/usr/local/include
|
||||||
FINAL_LDFLAGS+= -L/usr/local/lib
|
FINAL_LDFLAGS+= -L/usr/local/lib
|
||||||
FINAL_LIBS+= -lexecinfo
|
FINAL_LIBS+= -lexecinfo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
else
|
else
|
||||||
ifeq ($(uname_S),NetBSD)
|
ifeq ($(uname_S),NetBSD)
|
||||||
@ -187,7 +187,7 @@ ifeq ($(uname_S),NetBSD)
|
|||||||
FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/pkg/include
|
FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/pkg/include
|
||||||
FINAL_LDFLAGS+= -L/usr/pkg/lib
|
FINAL_LDFLAGS+= -L/usr/pkg/lib
|
||||||
FINAL_LIBS+= -lexecinfo
|
FINAL_LIBS+= -lexecinfo
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
ifeq ($(uname_S),FreeBSD)
|
ifeq ($(uname_S),FreeBSD)
|
||||||
# FreeBSD
|
# FreeBSD
|
||||||
@ -316,6 +316,14 @@ else
|
|||||||
endef
|
endef
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Alpine OS doesn't have support for the execinfo backtrace library we use for debug, so we provide an alternate implementation using libwunwind.
|
||||||
|
OS := $(shell cat /etc/os-release | grep ID= | head -n 1 | cut -d'=' -f2)
|
||||||
|
ifeq ($(OS),alpine)
|
||||||
|
FINAL_CXXFLAGS+=-DUNW_LOCAL_ONLY
|
||||||
|
FINAL_LIBS += -lunwind
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS)
|
REDIS_CC=$(QUIET_CC)$(CC) $(FINAL_CFLAGS)
|
||||||
REDIS_CXX=$(QUIET_CC)$(CXX) $(FINAL_CXXFLAGS)
|
REDIS_CXX=$(QUIET_CC)$(CXX) $(FINAL_CXXFLAGS)
|
||||||
KEYDB_AS=$(QUIET_CC) as --64 -g
|
KEYDB_AS=$(QUIET_CC) as --64 -g
|
||||||
|
@ -51,6 +51,12 @@ typedef ucontext_t sigcontext_t;
|
|||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
#endif /* HAVE_BACKTRACE */
|
#endif /* HAVE_BACKTRACE */
|
||||||
|
|
||||||
|
//UNW_LOCAL_ONLY being set means we use libunwind for backtraces instead of execinfo
|
||||||
|
#ifdef UNW_LOCAL_ONLY
|
||||||
|
#include <libunwind.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
#ifndef SA_ONSTACK
|
#ifndef SA_ONSTACK
|
||||||
#define SA_ONSTACK 0x08000000
|
#define SA_ONSTACK 0x08000000
|
||||||
@ -947,7 +953,7 @@ void _serverAssert(const char *estr, const char *file, int line) {
|
|||||||
serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
|
serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr);
|
||||||
|
|
||||||
if (g_pserver->crashlog_enabled) {
|
if (g_pserver->crashlog_enabled) {
|
||||||
#ifdef HAVE_BACKTRACE
|
#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY
|
||||||
logStackTrace(NULL, 1);
|
logStackTrace(NULL, 1);
|
||||||
#endif
|
#endif
|
||||||
printCrashReport();
|
printCrashReport();
|
||||||
@ -1044,7 +1050,7 @@ void _serverPanic(const char *file, int line, const char *msg, ...) {
|
|||||||
serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",fmtmsg,file,line);
|
serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",fmtmsg,file,line);
|
||||||
|
|
||||||
if (g_pserver->crashlog_enabled) {
|
if (g_pserver->crashlog_enabled) {
|
||||||
#ifdef HAVE_BACKTRACE
|
#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY
|
||||||
logStackTrace(NULL, 1);
|
logStackTrace(NULL, 1);
|
||||||
#endif
|
#endif
|
||||||
printCrashReport();
|
printCrashReport();
|
||||||
@ -1599,6 +1605,65 @@ void safe_write(int fd, const void *pv, ssize_t cb)
|
|||||||
} while (offset < cb);
|
} while (offset < cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNW_LOCAL_ONLY
|
||||||
|
|
||||||
|
/* Logs the stack trace using the libunwind call.
|
||||||
|
* The eip argument is unused as libunwind only gets local context.
|
||||||
|
* The uplevel argument indicates how many of the calling functions to skip.
|
||||||
|
*/
|
||||||
|
void logStackTrace(void * eip, int uplevel) {
|
||||||
|
(void)eip;//UNUSED
|
||||||
|
const char *msg;
|
||||||
|
int fd = openDirectLogFiledes();
|
||||||
|
|
||||||
|
if (fd == -1) return; /* If we can't log there is anything to do. */
|
||||||
|
|
||||||
|
msg = "\n------ STACK TRACE ------\n";
|
||||||
|
if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */};
|
||||||
|
unw_cursor_t cursor;
|
||||||
|
unw_context_t context;
|
||||||
|
|
||||||
|
unw_getcontext(&context);
|
||||||
|
unw_init_local(&cursor, &context);
|
||||||
|
|
||||||
|
/* Write symbols to log file */
|
||||||
|
msg = "\nBacktrace:\n";
|
||||||
|
if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */};
|
||||||
|
|
||||||
|
for (int i = 0; i < uplevel; i++) {
|
||||||
|
unw_step(&cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( unw_step(&cursor) ) {
|
||||||
|
unw_word_t ip, sp, off;
|
||||||
|
|
||||||
|
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||||
|
unw_get_reg(&cursor, UNW_REG_SP, &sp);
|
||||||
|
|
||||||
|
char symbol[256] = {"<unknown>"};
|
||||||
|
char *name = symbol;
|
||||||
|
|
||||||
|
if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) ) {
|
||||||
|
int status;
|
||||||
|
if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
|
||||||
|
name = symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(fd, "%s(+0x%" PRIxPTR ") [0x%016" PRIxPTR "] sp=0x%016" PRIxPTR "\n",
|
||||||
|
name,
|
||||||
|
static_cast<uintptr_t>(off),
|
||||||
|
static_cast<uintptr_t>(ip),
|
||||||
|
static_cast<uintptr_t>(sp));
|
||||||
|
|
||||||
|
if ( name != symbol )
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UNW_LOCAL_ONLY */
|
||||||
|
|
||||||
|
#ifdef HAVE_BACKTRACE
|
||||||
|
|
||||||
void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd)
|
void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd)
|
||||||
{
|
{
|
||||||
char **syms = backtrace_symbols(trace, csym);
|
char **syms = backtrace_symbols(trace, csym);
|
||||||
@ -1642,8 +1707,6 @@ void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd)
|
|||||||
free(syms);
|
free(syms);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
|
||||||
|
|
||||||
/* Logs the stack trace using the backtrace() call. This function is designed
|
/* Logs the stack trace using the backtrace() call. This function is designed
|
||||||
* to be called from signal handlers safely.
|
* to be called from signal handlers safely.
|
||||||
* The eip argument is optional (can take NULL).
|
* The eip argument is optional (can take NULL).
|
||||||
@ -1934,6 +1997,9 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
|
|
||||||
logRegisters(uc);
|
logRegisters(uc);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef UNW_LOCAL_ONLY
|
||||||
|
logStackTrace(NULL, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
printCrashReport();
|
printCrashReport();
|
||||||
|
|
||||||
@ -2028,6 +2094,8 @@ void watchdogSignalHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
serverLogFromHandler(LL_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---");
|
serverLogFromHandler(LL_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---");
|
||||||
#ifdef HAVE_BACKTRACE
|
#ifdef HAVE_BACKTRACE
|
||||||
logStackTrace(getMcontextEip(uc), 1);
|
logStackTrace(getMcontextEip(uc), 1);
|
||||||
|
#elif defined UNW_LOCAL_ONLY
|
||||||
|
logStackTrace(NULL, 1);
|
||||||
#else
|
#else
|
||||||
serverLogFromHandler(LL_WARNING,"Sorry: no support for backtrace().");
|
serverLogFromHandler(LL_WARNING,"Sorry: no support for backtrace().");
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user