aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorToni Uhlig <matzeton@googlemail.com>2018-06-24 15:38:54 +0200
committerToni Uhlig <matzeton@googlemail.com>2018-06-24 15:38:54 +0200
commitcae1514aa299c63b3d8cec88333cfdf82ff16e9b (patch)
treedae8c258f30a990c315a73c222086365d53fcc3a /src
parent31a392c97178d24803b85e9d46f106444d4cbed7 (diff)
added backtrace support on SIGSEGV
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r--src/utils.c39
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);
}
}