N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/Vaike/linux/system-addons/debug/sigsegv.c

Go to the documentation of this file.
00001 
00014 #ifndef __cplusplus
00015 #define NO_CPP_DEMANGLE
00016 #endif
00017 
00018 #define _GNU_SOURCE
00019 #include <memory.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <signal.h>
00023 #include <ucontext.h>
00024 #include <dlfcn.h>
00025 #include <execinfo.h>
00026 #ifndef NO_CPP_DEMANGLE
00027 #include <cxxabi.h>
00028 #endif
00029 
00030 #if defined(REG_RIP)
00031 # define SIGSEGV_STACK_IA64
00032 # define REGFORMAT "%016lx"
00033 #elif defined(REG_EIP)
00034 # define SIGSEGV_STACK_X86
00035 # define REGFORMAT "%08x"
00036 #else
00037 # define SIGSEGV_STACK_GENERIC
00038 # define REGFORMAT "%x"
00039 #endif
00040 
00041 static void signal_segv(int signum, siginfo_t* info, void*ptr) {
00042     static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};
00043 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
00044 # ifdef SIGSEGV_REGS
00045     size_t i;
00046 # endif
00047     ucontext_t *ucontext = (ucontext_t*)ptr;
00048     int f = 0;
00049     Dl_info dlinfo;
00050     void **bp = 0;
00051     void *ip = 0;
00052 #else
00053     size_t i;
00054     void *bt[20];
00055     char **strings;
00056     size_t sz;
00057 #endif
00058 
00059     fprintf(stderr, "Segmentation Fault!\n");
00060     fprintf(stderr, "info.si_signo = %d\n", signum);
00061     fprintf(stderr, "info.si_errno = %d\n", info->si_errno);
00062     fprintf(stderr, "info.si_code  = %d (%s)\n", info->si_code, si_codes[info->si_code]);
00063     fprintf(stderr, "info.si_addr  = %p\n", info->si_addr);
00064 
00065 #ifdef SIGSEGV_REGS
00066     for(i = 0; i < NGREG; i++)
00067         fprintf(stderr, "reg[%02d]       = 0x" REGFORMAT "\n", i, ucontext->uc_mcontext.gregs[i]);
00068 #endif
00069 
00070 #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
00071 # if defined(SIGSEGV_STACK_IA64)
00072     ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
00073     bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
00074 # elif defined(SIGSEGV_STACK_X86)
00075     ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
00076     bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
00077 # endif
00078 
00079     fprintf(stderr, "Stack trace:\n");
00080     while(bp && ip) {
00081         if(!dladdr(ip, &dlinfo))
00082             break;
00083 
00084         const char *symname = dlinfo.dli_sname;
00085 # ifndef NO_CPP_DEMANGLE
00086         int status;
00087         char *tmp = __cxa_demangle(symname, NULL, 0, &status);
00088 
00089         if(status == 0 && tmp)
00090             symname = tmp;
00091 # endif
00092 
00093         fprintf(stderr, "% 2d: %p <%s+%u> (%s)\n",
00094                 ++f,
00095                 ip,
00096                 symname,
00097                 (unsigned)(ip - dlinfo.dli_saddr),
00098                 dlinfo.dli_fname);
00099 
00100 # ifndef NO_CPP_DEMANGLE
00101         if(tmp)
00102             free(tmp);
00103 # endif
00104 
00105         if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
00106             break;
00107 
00108         ip = bp[1];
00109         bp = (void**)bp[0];
00110     }
00111 #else  // !SIGSEGV_STACK_X86 && !SIGSEGV_STACK_IA64
00112     fprintf(stderr, "Stack trace (non-dedicated):\n");
00113     sz = backtrace(bt, 20);
00114     strings = backtrace_symbols(bt, sz);
00115 
00116     for(i = 0; i < sz; ++i)
00117         fprintf(stderr, "%s\n", strings[i]);
00118 #endif
00119     fprintf(stderr, "End of stack trace\n");
00120     exit (-1);
00121 }
00122 
00123 int setup_sigsegv() {
00124     struct sigaction action;
00125     memset(&action, 0, sizeof(action));
00126     action.sa_sigaction = signal_segv;
00127     action.sa_flags = SA_SIGINFO;
00128     if(sigaction(SIGSEGV, &action, NULL) < 0) {
00129         perror("sigaction");
00130         return 0;
00131     }
00132 
00133     return 1;
00134 }
00135 
00136 #ifdef SIGSEGV_AUTO_INIT
00137 static void __attribute((constructor)) init(void) {
00138     setup_sigsegv();
00139 }
00140 #endif


© 2007, Los Alamos National Security, LLC.