summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure37
-rw-r--r--configure.ac3
-rw-r--r--src/httrack.c72
3 files changed, 112 insertions, 0 deletions
diff --git a/configure b/configure
index 1023c04..e656504 100755
--- a/configure
+++ b/configure
@@ -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