BackTrace.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <sofa/helper/BackTrace.h>
00028
00029 #if !defined(WIN32)
00030 #include <signal.h>
00031 #endif
00032 #if !defined(WIN32) && !defined(__APPLE__)
00033 #include <execinfo.h>
00034 #include <unistd.h>
00035 #endif
00036 #ifdef __GNUC__
00037 #include <cxxabi.h>
00038 #endif
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043 namespace sofa
00044 {
00045
00046 namespace helper
00047 {
00048
00051 void BackTrace::dump()
00052 {
00053 #if defined(__GNUC__) && !defined(__APPLE__) && !defined(WIN32)
00054 void *array[128];
00055 int size = backtrace(array, sizeof(array) / sizeof(array[0]));
00056 if (size > 0)
00057 {
00058 char** symbols = backtrace_symbols(array, size);
00059 if (symbols != NULL)
00060 {
00061 for (int i = 0; i < size; ++i)
00062 {
00063 char* symbol = symbols[i];
00064
00065
00066 char *beginmangled = strrchr(symbol,'(');
00067 if (beginmangled != NULL)
00068 {
00069 ++beginmangled;
00070 char *endmangled = strrchr(beginmangled ,')');
00071 if (endmangled != NULL)
00072 {
00073
00074 char* savedend = endmangled;
00075 while((endmangled[-1]>='0' && endmangled[-1]<='9') ||
00076 (endmangled[-1]>='a' && endmangled[-1]<='f') ||
00077 (endmangled[-1]>='A' && endmangled[-1]<='F'))
00078 --endmangled;
00079 if (endmangled[-1]=='x' && endmangled[-2]=='0' && endmangled[-3]=='+')
00080 endmangled -= 3;
00081 else
00082 endmangled = savedend;
00083 char* name = (char*)malloc(endmangled-beginmangled+1);
00084 memcpy(name, beginmangled, endmangled-beginmangled);
00085 name[endmangled-beginmangled] = '\0';
00086 int status;
00087 char* realname = abi::__cxa_demangle(name, 0, 0, &status);
00088 if (realname != NULL)
00089 {
00090 free(name);
00091 name = realname;
00092 }
00093 fprintf(stderr,"-> %.*s%s%s\n",beginmangled-symbol,symbol,name,endmangled);
00094 free(name);
00095 }
00096 else
00097 fprintf(stderr,"-> %s\n",symbol);
00098 }
00099 else
00100 fprintf(stderr,"-> %s\n",symbol);
00101 }
00102 free(symbols);
00103 }
00104 else
00105 {
00106 backtrace_symbols_fd(array, size, STDERR_FILENO);
00107 }
00108 }
00109 #endif
00110 }
00111
00115 void BackTrace::autodump()
00116 {
00117 #if !defined(WIN32)
00118 signal(SIGSEGV, BackTrace::sig);
00119 signal(SIGILL, BackTrace::sig);
00120 signal(SIGFPE, BackTrace::sig);
00121 signal(SIGPIPE, BackTrace::sig);
00122 signal(SIGINT, BackTrace::sig);
00123 signal(SIGTERM, BackTrace::sig);
00124 #endif
00125 }
00126
00127 void BackTrace::sig(int sig)
00128 {
00129 #if !defined(WIN32)
00130 fprintf(stderr,"\n########## SIG %d ##########\n",sig);
00131 dump();
00132 signal(sig,SIG_DFL);
00133 raise(sig);
00134 #endif
00135 }
00136
00137 }
00138
00139 }
00140