diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2018-06-24 15:38:54 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2018-06-24 15:38:54 +0200 |
commit | cae1514aa299c63b3d8cec88333cfdf82ff16e9b (patch) | |
tree | dae8c258f30a990c315a73c222086365d53fcc3a /src | |
parent | 31a392c97178d24803b85e9d46f106444d4cbed7 (diff) |
added backtrace support on SIGSEGV
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/utils.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c index 6911b07..f63070f 100644 --- a/src/utils.c +++ b/src/utils.c @@ -22,6 +22,9 @@ #include <linux/limits.h> #include <libgen.h> #include <assert.h> +#ifdef HAVE_EXECINFO +#include <execinfo.h> +#endif #ifdef HAVE_VALGRIND #include <valgrind.h> #endif @@ -31,6 +34,7 @@ #include "options.h" #define _POSIX_PATH_MAX 256 +#define MAX_STACK_FRAMES 64 char *arg0 = NULL; static int null_fd = -1; @@ -41,7 +45,13 @@ static const char cgdef[] = "/sys/fs/cgroup/potd"; static const char *_cgmem = NULL; static const char *_cgcpu = NULL; static const char *_cgpid = NULL; +#ifdef HAVE_EXECINFO +static void *stack_traces[MAX_STACK_FRAMES]; +#endif +#ifdef HAVE_EXECINFO +static void print_stack_trace(void); +#endif static char * sig_to_str(int signo, char *buf, size_t siz); static void sighandler_child(int signo); @@ -51,6 +61,32 @@ static int cgroups_write_file(const char *cdir, const char *csub, static inline void bin2hex_char(unsigned char c, char hexc[5]); +#ifdef HAVE_EXECINFO +static void print_stack_trace(void) +{ + int i, trace_size = 0; + char **call_stack = NULL; + + trace_size = backtrace(stack_traces, MAX_STACK_FRAMES); + call_stack = backtrace_symbols(stack_traces, trace_size); + + if (log_fmt) + E("Backtrace returned %d addresses", trace_size); + else + fprintf(stderr, "Backtrace returned %d addresses", trace_size); + + for (i = 0; i < trace_size; ++i) { + if (log_fmt) + E(" %s", call_stack[i]); + else + fprintf(stderr, " %s", call_stack[i]); + } + + if (call_stack) + free(call_stack); +} +#endif + int set_fd_nonblock(int fd) { int flags; @@ -111,6 +147,9 @@ static void sighandler_child(int signo) #else E("%s", "Segmentation fault .."); #endif +#ifdef HAVE_EXECINFO + print_stack_trace(); +#endif exit(EXIT_FAILURE); } } |