异常类Exception

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('
');
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
", ex.what());
32         printf("stack trace : %s 
", 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

有了这个类,我们可以在程序中这样处理异常:

 1 try
 2     {
 3         //
 4     }
 5     catch(const Exception &ex)
 6     {
 7         fprintf(stderr, "reason: %s
", ex.what());
 8         fprintf(stderr, "stack trace: %s
", ex.stackTrace());
 9         abort();
10     }
11     catch (const std::exception& ex)
12     {
13         fprintf(stderr, "reason: %s
", ex.what());
14         abort();
15     }
16     catch (...)
17     {
18         fprintf(stderr, "unknown exception caught 
");
19     throw; // rethrow
20     }
View Code
原文地址:https://www.cnblogs.com/gjn135120/p/4007171.html