Author: post
Date: 2010-03-29 20:28:13 +0200 (Mon, 29 Mar 2010)
New Revision: 3276

Modified:
   trunk/src/application.c
Log:
Add internal backtrace and register print on crash.

Modified: trunk/src/application.c
===================================================================
--- trunk/src/application.c     2010-03-28 19:48:07 UTC (rev 3275)
+++ trunk/src/application.c     2010-03-29 18:28:13 UTC (rev 3276)
@@ -28,6 +28,12 @@
 #ifndef WIN32
 #include <gconf/gconf-client.h>
 #endif
+#if defined(__GNUC__) && (defined (__x86_64__) || defined (__i386__))
+#include <execinfo.h>
+#include <signal.h>
+#define __USE_GNU
+#include <ucontext.h>
+#endif
 #include "application.h"
 #include "gtk-interface.h"
 #include "gtk-helper.h"
@@ -599,7 +605,106 @@
        g_static_rec_mutex_unlock (&gdk_lock);
 }
 
+#if defined(__GNUC__) && (defined (__x86_64__) || defined (__i386__))
 
+#if defined (__x86_64__)
+#define PROG_COUNTER_REG REG_RIP
+#else
+#define PROG_COUNTER_REG REG_EIP
+#endif
+
+void segfault_sigaction(int signal, siginfo_t *si, void *arg)
+{
+       ucontext_t *uc = (ucontext_t *)arg;
+       void* caller_address = (void *) 
uc->uc_mcontext.gregs[PROG_COUNTER_REG];   
+       if (signal == SIGSEGV)
+               printf("\nCaught SIGSEGV requesting address: %p from 
%p\n\nBacktrace:\n", si->si_addr, caller_address);
+       else if (signal == SIGILL)
+               printf("\nCaught SIGILL at %p\n\nBacktrace:\n", caller_address);
+       void* tracePtrs[100];
+       int count = backtrace( tracePtrs, 100 );
+       tracePtrs[1] = caller_address;
+       char** funcNames = backtrace_symbols( tracePtrs, count );
+
+       int i;
+       /* Print the stack trace */
+       for( i = 1; i < count; i++ )
+               printf("[%d]: %s\n", i, funcNames[i] );
+
+       printf("\nRegisters:\n");
+
+#if defined (__x86_64__)
+       unsigned long val = uc->uc_mcontext.gregs[REG_RAX];
+       printf("[rax]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RBX];
+       printf("[rbx]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RCX];
+       printf("[rcx]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RDX];
+       printf("[rdx]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RSI];
+       printf("[rsi]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RDI];
+       printf("[rdi]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R8];
+       printf("[r08]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R9];
+       printf("[r09]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R10];
+       printf("[r10]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R11];
+       printf("[r11]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R12];
+       printf("[r12]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R13];
+       printf("[r13]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R14];
+       printf("[r14]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_R15];
+       printf("[r15]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RSP];
+       printf("[rsp]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_RIP];
+       printf("[rip]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       
+       guint32 *mregs = (guint32*)uc->uc_mcontext.fpregs->_xmm;
+       for( i = 0; i < 8; i++) {
+               printf("xmm%02d: %08x %08x %08x %08x |", i*2, 
mregs[i*2*4+3],mregs[i*2*4+2],mregs[i*2*4+1], mregs[i*2*4]);
+               printf("xmm%02d: %08x %08x %08x %08x\n", i*2+1, 
mregs[i*2*4+3+4],mregs[i*2*4+2+4],mregs[i*2*4+1+4], mregs[i*2*4+4]);
+       }
+#endif
+       
+#if defined (__i386__)
+       unsigned long val = uc->uc_mcontext.gregs[REG_EAX];
+       printf("[eax]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_EBX];
+       printf("[ebx]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_ECX];
+       printf("[ecx]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_EDX];
+       printf("[edx]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_ESI];
+       printf("[esi]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_EDI];
+       printf("[edi]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_ESP];
+       printf("[esp]: 0x%08x%08x | ", (int)(val>>32), (int)(val&0xffffffff));
+       val = uc->uc_mcontext.gregs[REG_EIP];
+       printf("[eip]: 0x%08x%08x\n", (int)(val>>32), (int)(val&0xffffffff));
+       
+       guint32 *mregs = (guint32*)uc->uc_mcontext.fpregs->_xmm;
+       for( i = 0; i < 8; i++) {
+               printf("xmm%02d: %08x %08x %08x %08x |", i*2, 
mregs[i*2*4+3],mregs[i*2*4+2],mregs[i*2*4+1], mregs[i*2*4]);
+               printf("xmm%02d: %08x %08x %08x %08x\n", i*2+1, 
mregs[i*2*4+3+4],mregs[i*2*4+2+4],mregs[i*2*4+1+4], mregs[i*2*4+4]);
+       }
+#endif
+       printf("\nPlease file a bugreport at http://bugzilla.rawstudio.org/ 
including the information above, thanks!\n");
+       /* Free the string pointers */
+       free( funcNames );      
+       exit(0);
+}
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -608,6 +713,17 @@
        gboolean do_test = FALSE;
        int opt;
        gboolean use_system_theme = DEFAULT_CONF_USE_SYSTEM_THEME;
+#if defined(__GNUC__) && (defined (__x86_64__) || defined (__i386__))
+       struct sigaction sa;
+       memset(&sa, 0, sizeof(sigaction));
+       sigemptyset(&sa.sa_mask);
+       sa.sa_sigaction = segfault_sigaction;
+       sa.sa_flags   = SA_SIGINFO;
+
+       sigaction(SIGSEGV, &sa, NULL);
+       sigaction(SIGILL, &sa, NULL);
+#endif
+
 #ifndef WIN32
        GConfClient *client;
 #endif


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to