]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Print a stack trace on unexpected term signal (e.g. SIGABRT)
authorCasey McGinty <casey.mcginty@gmail.com>
Fri, 7 Sep 2018 01:46:52 +0000 (18:46 -0700)
committerCasey McGinty <casey.mcginty@gmail.com>
Fri, 7 Sep 2018 01:46:52 +0000 (18:46 -0700)
For OSX and Linux, add a signal handler to SIGABRT, SGIFPE, SIGILL,
SIGSEGV, and SIGBUS. When the program terminates unexpectedly the
handler will print the current stack to the terminal to help determine
the location of the failure.

On OSX the output will look like:

```
Stack trace:
4   zstd                                0x000000010927ed96 main + 16886
5   libdyld.dylib                       0x00007fff767d1015 start + 1
6   ???                                 0x0000000000000001 0x0 + 1
```

On Linux the output will look like:

```
Stack trace:
./zstd() [0x4b8e1b]
./zstd() [0x4b928a]
./zstd() [0x403dc2]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f5e0fbb0445]
./zstd() [0x405754]
```

As is, the code does not function on WIN32.

See also: https://oroboro.com/stack-trace-on-crash/

lib/common/zstd_common.c
lib/common/zstd_internal.h
programs/fileio.c
programs/zstdcli.c

index 6f05d240e43cfdbec4009a916a7c6710c2418b30..d3ad057302e3d61c9a80a05191c21714d9b8077b 100644 (file)
 ***************************************/
 #include <stdlib.h>      /* malloc, calloc, free */
 #include <string.h>      /* memset */
+#include <stdio.h>       /* fprintf(), stderr */
+#include <signal.h>      /* signal() */
+#ifndef _WIN32
+#include <execinfo.h>    /* backtrace, backtrace_symbols, symbollist */
+#endif
 #include "error_private.h"
 #include "zstd_internal.h"
 
 
+/*-************************************
+*  Display Macros
+**************************************/
+#define DISPLAY(...)         fprintf(stderr, __VA_ARGS__)
+
+
 /*-****************************************
 *  Version
 ******************************************/
@@ -79,3 +90,46 @@ void ZSTD_free(void* ptr, ZSTD_customMem customMem)
             free(ptr);
     }
 }
+
+
+/*-*********************************************************
+*  Termination signal trapping (Print debug stack trace)
+***********************************************************/
+#define MAX_STACK_FRAMES    50
+
+#ifndef _WIN32
+static void ABRThandler(int sig)
+{
+   void* addrlist[MAX_STACK_FRAMES + 1];
+   char** symbollist;
+   U32 addrlen, i;
+
+   (void)sig;
+
+   DISPLAY("Stack trace:\n");
+   // Retrieve current stack addresses.
+   addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
+   if (addrlen == 0) {
+      DISPLAY("\n");
+      return;
+   }
+   // 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++) {
+      DISPLAY("%s\n", symbollist[i]);
+   }
+   free(symbollist);
+}
+#endif
+
+void ZSTD_addAbortHandler()
+{
+#ifndef _WIN32
+    signal(SIGABRT, ABRThandler);
+    signal(SIGFPE, ABRThandler);
+    signal(SIGILL, ABRThandler);
+    signal(SIGSEGV, ABRThandler);
+    signal(SIGBUS, ABRThandler);
+#endif
+}
index e75adfa61323a91f0569663bcabf18dd9c5e7993..b555dd828c05043c14f64902d42a91c27e4263a3 100644 (file)
@@ -206,6 +206,9 @@ void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
 void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
 void ZSTD_free(void* ptr, ZSTD_customMem customMem);
 
+/* custom crash signal handler */
+void ZSTD_addAbortHandler(void);
+
 
 MEM_STATIC U32 ZSTD_highbit32(U32 val)   /* compress, dictBuilder, decodeCorpus */
 {
index 5f10958d754e71bcb732985c8dfead7d17511acd..7e9c31cb267ce61f6354d65dd94ed63091b150aa 100644 (file)
@@ -157,7 +157,7 @@ static void clearHandler(void)
 }
 
 
-/* ************************************************************
+/*-************************************************************
 * Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW
 ***************************************************************/
 #if defined(_MSC_VER) && _MSC_VER >= 1400
index 0fccd34f9e04d9e4e222d68f917fe9bbfdc96048..0688d44bc1c2ff7468628a0fd9b6a898aa87fab1 100644 (file)
@@ -39,6 +39,7 @@
 #endif
 #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_maxCLevel */
 #include "zstd.h"     /* ZSTD_VERSION_STRING */
+#include "zstd_internal.h" /* ZSTD_addAbortHandler */
 
 
 /*-************************************
@@ -511,6 +512,9 @@ int main(int argCount, const char* argv[])
     if (exeNameMatch(programName, ZSTD_UNLZ4)) { operation=zom_decompress; FIO_setCompressionType(FIO_lz4Compression); }                                   /* behave like unlz4, also supports multiple formats */
     memset(&compressionParams, 0, sizeof(compressionParams));
 
+    /* init crash handler */
+    ZSTD_addAbortHandler();
+
     /* command switches */
     for (argNb=1; argNb<argCount; argNb++) {
         const char* argument = argv[argNb];