summaryrefslogtreecommitdiff
path: root/src/httrack.c
diff options
context:
space:
mode:
authorXavier Roche <xroche@users.noreply.github.com>2014-07-14 08:08:55 +0000
committerXavier Roche <xroche@users.noreply.github.com>2014-07-14 08:08:55 +0000
commit1b5adaaa2d90972379ad79b263e951316da13f73 (patch)
tree40cda179852807fbecfcb619cf9eadd402c97bda /src/httrack.c
parent9f21da0f1b9dddceef98038e864c76028bf976ea (diff)
Added stack trace on Linux when crashing for httrack
Diffstat (limited to 'src/httrack.c')
-rw-r--r--src/httrack.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/httrack.c b/src/httrack.c
index e8e5cd3..6ca261b 100644
--- a/src/httrack.c
+++ b/src/httrack.c
@@ -69,6 +69,9 @@ static int linput(FILE * fp, char *s, int max);
#include <unistd.h>
#endif
#include <ctype.h>
+#ifdef __linux
+#include <execinfo.h>
+#endif
/* END specific definitions */
static void __cdecl htsshow_init(t_hts_callbackarg * carg);
@@ -833,6 +836,60 @@ static void sig_ask(int code) { // demander
}
}
#endif
+
+#undef FD_ERR
+#define FD_ERR 2
+
+static void print_backtrace(void) {
+#ifdef __linux
+ void *stack[256];
+ const int size = backtrace(stack, sizeof(stack)/sizeof(stack[0]));
+ if (size != 0) {
+ backtrace_symbols_fd(stack, size, FD_ERR);
+ }
+#else
+ const char msg[] = "No stack trace available on this OS :(\n";
+ write(FD_ERR, msg, sizeof(msg) - 1);
+#endif
+}
+
+static size_t print_num(char *buffer, int num) {
+ size_t i, j;
+ if (num < 0) {
+ *(buffer++) = '\n';
+ num = -num;
+ }
+ for(i = 0 ; num != 0 || i == 0 ; i++, num /= 10) {
+ buffer[i] = '0' + ( num % 10 );
+ }
+ for(j = 0 ; j < i ; j++) {
+ const char c = buffer[i - j - 1];
+ buffer[i - j - 1] = buffer[j];
+ buffer[j] = c;
+ }
+ buffer[i] = '\0';
+ return i;
+}
+
+static void sig_fatal(int code) {
+ const char msg[] = "\nCaught signal ";
+ char buffer[256];
+ size_t size;
+
+ signal(code, SIG_DFL);
+ signal(SIGABRT, SIG_DFL);
+
+ memcpy(buffer, msg, sizeof(msg) - 1);
+ size = sizeof(msg) - 1;
+ size += print_num(&buffer[size], code);
+ buffer[size++] = '\n';
+ write(FD_ERR, buffer, size);
+ print_backtrace();
+ abort();
+}
+
+#undef FD_ERR
+
static void sig_brpipe(int code) { // treat if necessary
signal(code, sig_brpipe);
}
@@ -906,6 +963,21 @@ static void signal_handlers(void) {
signal(SIGPIPE, sig_brpipe); // broken pipe (write into non-opened socket)
signal(SIGCHLD, sig_ignore); // child change status
#endif
+#ifdef SIGABRT
+ signal(SIGABRT, sig_fatal); // bus error
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, sig_fatal); // bus error
+#endif
+#ifdef SIGILL
+ signal(SIGILL, sig_fatal); // illegal instruction
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, sig_fatal); // segmentation violation
+#endif
+#ifdef SIGSTKFLT
+ signal(SIGSTKFLT, sig_fatal); // stack fault
+#endif
}
// fin routines de détournement de SIGHUP & co