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
00028
00029
00030
00031
00032
00033 #include "cmtkStackBacktrace.h"
00034
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037
00038 #ifdef HAVE_EXECINFO_H
00039 # include <execinfo.h>
00040 #endif
00041
00042 namespace
00043 cmtk
00044 {
00045
00048
00049 StackBacktrace
00050 ::StackBacktrace()
00051 {
00052 #ifndef _MSC_VER
00053 struct sigaction sa;
00054
00055 sa.sa_sigaction = cmtkStackBacktraceSignalHandler;
00056 sigemptyset (&sa.sa_mask);
00057 sa.sa_flags = SA_RESTART | SA_SIGINFO;
00058
00059 sigaction(SIGSEGV, &sa, NULL);
00060 sigaction(SIGUSR1, &sa, NULL);
00061 #else
00062 #endif // #ifndef _MSC_VER
00063 }
00064
00065 void
00066 StackBacktrace
00067 ::PrintBacktrace( const int levels )
00068 {
00069 #ifdef HAVE_EXECINFO_H
00070 void *trace[16];
00071 const int trace_size = backtrace(trace, 16);
00072
00073 char *const *messages = backtrace_symbols( trace, trace_size );
00074
00075 printf("[stack] Execution path:\n");
00076
00077 const int printLevels = levels ? levels+1 : trace_size;
00078 for ( int i=1; i<printLevels; ++i )
00079 printf( "[stack] %s\n", messages[i] );
00080 #else // #ifdef HAVE_EXECINFO_H
00081 fputs( "Sorry, stack bracktrace() not supported on this platform.\n", stderr );
00082 #endif // #ifdef HAVE_EXECINFO_H
00083 }
00084
00085 int StackBacktrace::ExitCode = 1;
00086
00087 }
00088
00089 #ifndef _MSC_VER
00090 void
00091 cmtkStackBacktraceSignalHandler
00092 ( int sig, siginfo_t *info, void* )
00093 {
00094
00095 if (sig == SIGSEGV)
00096 {
00097 printf( "Caught signal %d, faulty address is %p\n", sig, info->si_addr );
00098 }
00099 else
00100 {
00101 printf( "Caught signal %d\n", sig);
00102 }
00103
00104 cmtk::StackBacktrace::PrintBacktrace();
00105
00106 exit( cmtk::StackBacktrace::ExitCode );
00107 }
00108 #else // #ifndef _MSC_VER
00109 void
00110 cmtkStackBacktraceSignalHandler
00111 ( int sig )
00112 {
00113 exit( cmtk::StackBacktrace::ExitCode );
00114 }
00115 #endif // #ifndef _MSC_VER
00116