aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ChangeLog8
-rw-r--r--shell/main.c57
2 files changed, 65 insertions, 0 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index 756fc95aa5..69104e466b 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,3 +1,11 @@
+2003-02-13 Ettore Perazzoli <ettore@ximian.com>
+
+ [Ported SIGSEGV signal redirection hack from mail/.]
+
+ * main.c (segv_redirect): New, SIGSEGV signal handler.
+ (setup_segv_redirect): New function to set it up.
+ (main): Call setup_segv_redirect().
+
2003-02-12 Ettore Perazzoli <ettore@ximian.com>
* e-setup.c (DEFAULT_USER_PATH): Look into evolution/$BASE_VERSION
diff --git a/shell/main.c b/shell/main.c
index ee929abdea..f766a668ab 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -66,11 +66,14 @@
#include <gal/widgets/e-cursors.h>
#include <fcntl.h>
+#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <pthread.h>
+
static EShell *shell = NULL;
static char *evolution_directory = NULL;
@@ -438,6 +441,58 @@ idle_cb (void *data)
return FALSE;
}
+
+/* SIGSEGV handling.
+
+ The GNOME SEGV handler will lose if it's not run from the main Gtk
+ thread. So if we have to redirect the signal if the crash happens in another
+ thread. */
+
+static void (*gnome_segv_handler) (int);
+static GStaticMutex segv_mutex = G_STATIC_MUTEX_INIT;
+static pthread_t main_thread;
+
+static void
+segv_redirect (int sig)
+{
+ if (pthread_self () == main_thread)
+ gnome_segv_handler (sig);
+ else {
+ pthread_kill (main_thread, sig);
+
+ /* We can't return from the signal handler or the thread may
+ SEGV again. But we can't pthread_exit, because then the
+ thread may get cleaned up before bug-buddy can get a stack
+ trace. So we block by trying to lock a mutex we know is
+ already locked. */
+ g_static_mutex_lock (&segv_mutex);
+ }
+}
+
+static void
+setup_segv_redirect (void)
+{
+ struct sigaction sa, osa;
+
+ sigaction (SIGSEGV, NULL, &osa);
+ if (osa.sa_handler == SIG_DFL)
+ return;
+
+ main_thread = pthread_self ();
+
+ sa.sa_flags = 0;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_handler = segv_redirect;
+ sigaction (SIGSEGV, &sa, NULL);
+ sigaction (SIGBUS, &sa, NULL);
+ sigaction (SIGFPE, &sa, NULL);
+
+ sa.sa_handler = SIG_IGN;
+ sigaction (SIGXFSZ, &sa, NULL);
+ gnome_segv_handler = osa.sa_handler;
+ g_static_mutex_lock (&segv_mutex);
+}
+
int
main (int argc, char **argv)
{
@@ -480,6 +535,8 @@ main (int argc, char **argv)
exit (1);
}
+ setup_segv_redirect ();
+
if (evolution_debug_log) {
int fd;