cmtkStackBacktrace.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2523 $
00026 //
00027 //  $LastChangedDate: 2010-11-01 15:41:02 -0700 (Mon, 01 Nov 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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   /* skip first stack frame (points here) */
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 } // namespace cmtk
00088 
00089 #ifndef _MSC_VER
00090 void
00091 cmtkStackBacktraceSignalHandler
00092 ( int sig, siginfo_t *info, void* )
00093 {
00094   /* Do something useful with siginfo_t */
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines