Exception.h
1 #ifndef EXCEPTION_H 2 #define EXCEPTION_H 3 #include <string> 4 #include <exception> 5 6 7 class Exception : public std::exception 8 { 9 public: 10 explicit Exception(const char *what); 11 explicit Exception(const std::string &what); 12 virtual ~Exception() throw(); 13 virtual const char *what() const throw(); 14 const char *stackTrace() const throw(); 15 16 private: 17 void fillStackTrace(); 18 19 std::string demangle(const char *symbol); 20 std::string _message; 21 std::string _stack; 22 }; 23 24 25 26 27 #endif
Exception.cpp
1 #include "execption.h" 2 #include <cxxabi.h> 3 #include <execinfo.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 7 using namespace std; 8 9 Exception::Exception(const char *what) 10 :_message(what) 11 { 12 fillStackTrace(); 13 } 14 15 Exception::Exception(const std::string &what) 16 :_message(what) 17 { 18 fillStackTrace(); 19 } 20 21 Exception::~Exception() throw() 22 { 23 24 } 25 26 const char *Exception::what() const throw() 27 { 28 return _message.c_str(); 29 } 30 31 const char *Exception::stackTrace() const throw() 32 { 33 return _stack.c_str(); 34 } 35 36 void Exception::fillStackTrace() 37 { 38 const int len = 200; 39 void *buffer[len]; 40 int nptrs = ::backtrace(buffer, len); 41 42 char **strings = ::backtrace_symbols(buffer, nptrs); 43 44 if(strings) 45 { 46 for(int i = 0; i != nptrs; ++ i) 47 { 48 _stack.append(demangle(strings[i])); 49 _stack.push_back(‘\n‘); 50 } 51 free(strings); 52 } 53 } 54 55 56 string Exception::demangle(const char *symbol) 57 { 58 size_t size; 59 int status; 60 char tmp[128]; 61 char *demangled; 62 63 if(1 == sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", tmp)) 64 { 65 if(NULL != (demangled = abi::__cxa_demangle(tmp, NULL, &size, &status))) 66 { 67 string result(demangled); 68 free(demangled); 69 return result; 70 } 71 } 72 73 if(1 == sscanf(symbol, "%127s", tmp)) 74 { 75 return tmp; 76 } 77 78 return symbol; 79 }
测试代码:
1 #include "Exception.h" 2 #include <stdio.h> 3 4 using namespace std; 5 6 class Bar 7 { 8 public: 9 void test() 10 { 11 throw Exception("oops"); 12 } 13 }; 14 15 void foo() 16 { 17 Bar b; 18 b.test(); 19 } 20 21 22 int main(int argc, const char *argv[]) 23 { 24 25 try 26 { 27 foo(); 28 } 29 catch(const Exception &ex) 30 { 31 printf("reason : %s\n", ex.what()); 32 printf("stack trace : %s \n", ex.stackTrace()); 33 } 34 return 0; 35 }
显示结果如下:
reason : oops
stack trace : Exception::fillStackTrace()
Exception::Exception(char const*)
Bar::test()
foo()
./a.out(main+0x10)
/lib/libc.so.6(__libc_start_main+0xe6)
./a.out()
编译时不要忘记 : 加上-rdynamic
时间: 2024-11-13 23:34:43