CLAM-Development
1.1
|
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