Refactor abort signal handling

- Print signal name to term
- Add -rdynamic option to generate Linux symbol names in backtrace
- Raise default signal after handler to ensure program termination
This commit is contained in:
Casey McGinty 2018-09-11 10:40:45 -07:00
parent a06574fc97
commit 2a3967b7c4
No known key found for this signature in database
GPG Key ID: BA0229620046D260
2 changed files with 22 additions and 3 deletions

View File

@ -98,15 +98,30 @@ void ZSTD_free(void* ptr, ZSTD_customMem customMem)
#define MAX_STACK_FRAMES 50
#ifndef _WIN32
#ifdef __linux__
#define START_STACK_FRAME 2
#elif defined __APPLE__
#define START_STACK_FRAME 4
#endif
static void ABRThandler(int sig)
{
const char* name;
void* addrlist[MAX_STACK_FRAMES + 1];
char** symbollist;
U32 addrlen, i;
(void)sig;
switch (sig) {
case SIGABRT: name = "SIGABRT"; break;
case SIGFPE: name = "SIGFPE"; break;
case SIGILL: name = "SIGILL"; break;
case SIGINT: name = "SIGINT"; break;
case SIGSEGV: name = "SIGSEGV"; break;
default: name = "UNKNOWN"; break;
}
DISPLAY("Stack trace:\n");
DISPLAY("Caught %s signal, printing stack:\n", name);
// Retrieve current stack addresses.
addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
if (addrlen == 0) {
@ -116,10 +131,13 @@ static void ABRThandler(int sig)
// Create readable strings to each frame.
symbollist = backtrace_symbols(addrlist, addrlen);
// Print the stack trace, excluding calls handling the signal.
for (i = 4; i < addrlen; i++) {
for (i = START_STACK_FRAME; i < addrlen; i++) {
DISPLAY("%s\n", symbollist[i]);
}
free(symbollist);
// Reset and raise the signal so default handler runs.
signal(sig, SIG_DFL);
raise(sig);
}
#endif

View File

@ -48,6 +48,7 @@ DEBUGFLAGS+=-Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
-Wredundant-decls
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
LDFLAGS += -rdynamic
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)