diff options
author | Xavier Roche <xroche@users.noreply.github.com> | 2014-07-14 08:08:55 +0000 |
---|---|---|
committer | Xavier Roche <xroche@users.noreply.github.com> | 2014-07-14 08:08:55 +0000 |
commit | 1b5adaaa2d90972379ad79b263e951316da13f73 (patch) | |
tree | 40cda179852807fbecfcb619cf9eadd402c97bda | |
parent | 9f21da0f1b9dddceef98038e864c76028bf976ea (diff) |
Added stack trace on Linux when crashing for httrack
-rwxr-xr-x | configure | 37 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/httrack.c | 72 |
3 files changed, 112 insertions, 0 deletions
@@ -12246,6 +12246,43 @@ else fi +## Export all symbols for backtraces +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -rdynamic" >&5 +$as_echo_n "checking whether C compiler accepts -rdynamic... " >&6; } +if ${ax_cv_check_cflags___rdynamic+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -rdynamic" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ax_cv_check_cflags___rdynamic=yes +else + ax_cv_check_cflags___rdynamic=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___rdynamic" >&5 +$as_echo "$ax_cv_check_cflags___rdynamic" >&6; } +if test x"$ax_cv_check_cflags___rdynamic" = xyes; then : + DEFAULT_CFLAGS="$DEFAULT_CFLAGS -rdynamic" +else + : +fi + + ### Check for -fvisibility=hidden support diff --git a/configure.ac b/configure.ac index 5a0db60..0927a77 100644 --- a/configure.ac +++ b/configure.ac @@ -76,6 +76,9 @@ AX_CHECK_COMPILE_FLAG([-fstrict-aliasing -Wstrict-aliasing], [DEFAULT_CFLAGS="$D AX_CHECK_LINK_FLAG([-Wl,--discard-all], [DEFAULT_LDLAGS="$DEFAULT_LDLAGS -Wl,--discard-all"]) AX_CHECK_LINK_FLAG([-Wl,--no-undefined], [DEFAULT_LDLAGS="$DEFAULT_LDLAGS -Wl,--no-undefined"]) +## Export all symbols for backtraces +AX_CHECK_COMPILE_FLAG([-rdynamic], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -rdynamic"]) + ### Check for -fvisibility=hidden support gl_VISIBILITY AM_CFLAGS="$AM_CFLAGS $CFLAG_VISIBILITY" 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 |