Assert.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 #include "Assert.hxx"
00023 #include <iostream>
00024 #include <cstdlib>
00025 #include <csignal>
00026 #if defined(__linux__)
00027 #include <execinfo.h>
00028 #endif
00029 
00030 
00031 namespace CLAM {
00032 
00033 void DumpBacktrace(std::ostream & os)
00034 {
00035 #if defined(__linux__)
00036 
00037         void *bt_array[100];    // 100 should be enough ?!?
00038         char **bt_strings;
00039         int num_entries;
00040 
00041         if ((num_entries = backtrace(bt_array, 100)) < 0) {
00042                 os << " Unable to generate a backtrace" << std::endl;
00043                 return;
00044         }
00045 
00046         if ((bt_strings = backtrace_symbols(bt_array, num_entries)) == NULL) {
00047                 os << " Unable to adquire symbols names for the backtrace" << std::endl;
00048                 return;
00049         }
00050 
00051         os << "\n Backtrace:\n" << std::endl;
00052         for (int i = 0; i < num_entries; i++) {
00053                 os << "[" << i << "] " <<  bt_strings[i] << std::endl;
00054         }
00055         free(bt_strings);
00056 #else
00057         os << " Unable to adquire symbols names for the backtrace" << std::endl;
00058 #endif
00059 }
00060 
00061 
00062 // by default, CLAM asserts must breakpoint
00063 // we'll want to disable breakpoints for automatic assertion testing 
00064 // purposes
00065 bool disabledCLAMAssertBreakpoint = false;
00066 
00067 // Assert related
00068 
00069 static void DefaultAssertHandler(const char* message, const char* filename, int lineNumber )
00070 {
00071         std::cerr << "##########################################################" << std::endl;
00072         std::cerr << "################### ASSERTION FAILED #####################" << std::endl;
00073         std::cerr << "##########################################################" << std::endl;
00074         std::cerr << "At file " << filename << " line " << lineNumber << std::endl;
00075         std::cerr << message << std::endl;
00076         DumpBacktrace(std::cerr);
00077 }
00078 
00079 static AssertFailedHandlerType CurrentAssertFailedHandler=DefaultAssertHandler;
00080 
00081 AssertFailedHandlerType SetAssertFailedHandler(AssertFailedHandlerType handler) {
00082         AssertFailedHandlerType oldHandler = CurrentAssertFailedHandler;
00083         CurrentAssertFailedHandler = handler;
00084         return oldHandler;
00085 }
00086 
00087 void ExecuteAssertFailedHandler(const char* message, const char* filename, int lineNumber )
00088 {
00089         CurrentAssertFailedHandler(message,filename,lineNumber);
00090 }
00091 
00092 bool ErrAssertionFailed::breakpointInCLAMAssertEnabled = true;
00093 
00094 ErrAssertionFailed::ErrAssertionFailed(const char* message, const char* filename, int lineNumber)
00095         : Err(message)
00096 {
00097         if (!breakpointInCLAMAssertEnabled) return; 
00098 
00099         CurrentAssertFailedHandler( message, filename, lineNumber );
00100 }
00101 
00102 // Warning related
00103 
00104 static void DefaultWarningHandler(const char* message, const char* filename, int lineNumber )
00105 {
00106         std::cerr << "####### WARNING: At file " << filename << " line " << lineNumber << std::endl;
00107         std::cerr << message << std::endl;
00108 }
00109 
00110 static WarningHandlerType CurrentWarningHandler=DefaultWarningHandler;
00111 
00112 WarningHandlerType SetWarningHandler(WarningHandlerType handler) {
00113         WarningHandlerType oldHandler = CurrentWarningHandler;
00114         CurrentWarningHandler = handler;
00115         return oldHandler;
00116 }
00117 
00118 void ExecuteWarningHandler(const char* message, const char* filename, int lineNumber )
00119 {
00120         CurrentWarningHandler(message,filename,lineNumber);
00121 }
00122 
00123 #if 0 //  defined(__linux__)
00124 class SystemSignalTrapper
00125 {
00126         int _signal;
00127         sighandler_t _oldHandler;
00128 public:
00129         SystemSignalTrapper(int signal, sighandler_t handler) :
00130                 _signal(signal)
00131         {
00132                 _oldHandler = std::signal(signal, handler);
00133         }
00134         ~SystemSignalTrapper()
00135         {
00136                 std::signal(_signal, _oldHandler);
00137         }
00138 };
00139 void segvSignalHandler(int myInt)
00140 {
00141         std::cerr << std::endl;
00142         std::cerr << "##########################################################" << std::endl;
00143         std::cerr << "#################### BAD MEMORY ACCES ####################" << std::endl;
00144         std::cerr << "##########################################################" << std::endl;
00145         DumpBacktrace(std::cerr);
00146         std::abort();
00147 }
00148 
00149 static SystemSignalTrapper segvSignalTrapper(SIGSEGV,segvSignalHandler);
00150 #endif //defined linux
00151 
00152 
00153 }
00154 
00155 

Generated on Tue Aug 12 22:33:41 2008 for CLAM by  doxygen 1.5.5