From c49a46ca8adc933f4bea922d6197e8903b686d31 Mon Sep 17 00:00:00 2001 From: malavan Date: Mon, 19 Jul 2021 17:20:52 +0000 Subject: [PATCH] add backtrace for alpine using libunwind Former-commit-id: c583ffff412b9df705b7c96e68e3908b645c7d43 --- src/Makefile | 13 ++++++++--- src/debug.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/Makefile b/src/Makefile index 37f7ba917..c8075236e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -127,7 +127,7 @@ ifneq ($(uname_S),Darwin) endif # Linux ARM32 needs -latomic at linking time ifneq (,$(findstring armv,$(uname_M))) - FINAL_LIBS+=-latomic + FINAL_LIBS+=-latomic endif @@ -177,7 +177,7 @@ ifeq ($(uname_S),OpenBSD) FINAL_CXXFLAGS+= -DUSE_BACKTRACE -I/usr/local/include FINAL_LDFLAGS+= -L/usr/local/lib FINAL_LIBS+= -lexecinfo - endif + endif else ifeq ($(uname_S),NetBSD) @@ -187,7 +187,7 @@ ifeq ($(uname_S),NetBSD) FINAL_CFLAGS+= -DUSE_BACKTRACE -I/usr/pkg/include FINAL_LDFLAGS+= -L/usr/pkg/lib FINAL_LIBS+= -lexecinfo - endif + endif else ifeq ($(uname_S),FreeBSD) # FreeBSD @@ -316,6 +316,13 @@ else endef endif +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_CXX=$(QUIET_CC)$(CXX) $(FINAL_CXXFLAGS) KEYDB_AS=$(QUIET_CC) as --64 -g diff --git a/src/debug.cpp b/src/debug.cpp index 7b7fe29e1..7a2c16255 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -51,6 +51,11 @@ typedef ucontext_t sigcontext_t; #include #endif /* HAVE_BACKTRACE */ +#ifdef UNW_LOCAL_ONLY +#include +#include +#endif + #ifdef __CYGWIN__ #ifndef SA_ONSTACK #define SA_ONSTACK 0x08000000 @@ -947,7 +952,7 @@ void _serverAssert(const char *estr, const char *file, int line) { serverLog(LL_WARNING,"==> %s:%d '%s' is not true",file,line,estr); if (g_pserver->crashlog_enabled) { -#ifdef HAVE_BACKTRACE +#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY logStackTrace(NULL, 1); #endif printCrashReport(); @@ -1044,7 +1049,7 @@ void _serverPanic(const char *file, int line, const char *msg, ...) { serverLog(LL_WARNING,"Guru Meditation: %s #%s:%d",fmtmsg,file,line); if (g_pserver->crashlog_enabled) { -#ifdef HAVE_BACKTRACE +#if defined HAVE_BACKTRACE || defined UNW_LOCAL_ONLY logStackTrace(NULL, 1); #endif printCrashReport(); @@ -1599,6 +1604,52 @@ void safe_write(int fd, const void *pv, ssize_t cb) } while (offset < cb); } +#ifdef UNW_LOCAL_ONLY + +void logStackTrace(void *eip, int uplevel) { + int fd = openDirectLogFiledes(); + + if (fd == -1) return; /* If we can't log there is anything to do. */ + unw_cursor_t cursor; + unw_context_t context; + + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + 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] = {""}; + 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(off), + static_cast(ip), + static_cast(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) { char **syms = backtrace_symbols(trace, csym); @@ -1642,8 +1693,6 @@ void backtrace_symbols_demangle_fd(void **trace, size_t csym, int fd) free(syms); } -#ifdef HAVE_BACKTRACE - /* Logs the stack trace using the backtrace() call. This function is designed * to be called from signal handlers safely. * The eip argument is optional (can take NULL). @@ -1934,6 +1983,9 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { logRegisters(uc); #endif +#ifdef UNW_LOCAL_ONLY + logStackTrace(NULL, 1); +#endif printCrashReport(); @@ -2028,6 +2080,8 @@ void watchdogSignalHandler(int sig, siginfo_t *info, void *secret) { serverLogFromHandler(LL_WARNING,"\n--- WATCHDOG TIMER EXPIRED ---"); #ifdef HAVE_BACKTRACE logStackTrace(getMcontextEip(uc), 1); +#elif defined UNW_LOCAL_ONLY + logStackTrace(NULL, 1); #else serverLogFromHandler(LL_WARNING,"Sorry: no support for backtrace()."); #endif