diff options
author | Mike Buland <eichlan@xagasoft.com> | 2008-03-04 19:26:24 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2008-03-04 19:26:24 +0000 |
commit | 57bbb6651bfc10d9f2404164e3303c3376dfc62c (patch) | |
tree | 90bac81adc231a92251ac2d540c0c9d75468f7d4 /src/exceptionbase.cpp | |
parent | b1c614da6f0b248b18e83a014030b5bdfd9c09c6 (diff) | |
download | libbu++-57bbb6651bfc10d9f2404164e3303c3376dfc62c.tar.gz libbu++-57bbb6651bfc10d9f2404164e3303c3376dfc62c.tar.bz2 libbu++-57bbb6651bfc10d9f2404164e3303c3376dfc62c.tar.xz libbu++-57bbb6651bfc10d9f2404164e3303c3376dfc62c.zip |
Added backtrace support to the Exception system. It's pretty simple, if it's
enabled, and the compiler/libc support it, then you just get backtraces, if not
you get a message about it not being supported. It probably shouldn't be
enabled in most production environments, since it does happen for every
exception, and could be memory and time consuming.
Diffstat (limited to 'src/exceptionbase.cpp')
-rw-r--r-- | src/exceptionbase.cpp | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/src/exceptionbase.cpp b/src/exceptionbase.cpp index 61bbcb4..6e5ae10 100644 --- a/src/exceptionbase.cpp +++ b/src/exceptionbase.cpp | |||
@@ -11,45 +11,70 @@ | |||
11 | Bu::ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() : | 11 | Bu::ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() : |
12 | nErrorCode( 0 ), | 12 | nErrorCode( 0 ), |
13 | sWhat( NULL ) | 13 | sWhat( NULL ) |
14 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
15 | , sBT( NULL ) | ||
16 | #endif | ||
14 | { | 17 | { |
15 | va_list ap; | 18 | va_list ap; |
16 | 19 | ||
17 | va_start(ap, lpFormat); | 20 | va_start(ap, lpFormat); |
18 | setWhat( lpFormat, ap ); | 21 | setWhat( lpFormat, ap ); |
19 | va_end(ap); | 22 | va_end(ap); |
23 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
24 | createBacktrace(); | ||
25 | #endif | ||
20 | } | 26 | } |
21 | 27 | ||
22 | Bu::ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() : | 28 | Bu::ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() : |
23 | nErrorCode( nCode ), | 29 | nErrorCode( nCode ), |
24 | sWhat( NULL ) | 30 | sWhat( NULL ) |
31 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
32 | , sBT( NULL ) | ||
33 | #endif | ||
25 | { | 34 | { |
26 | va_list ap; | 35 | va_list ap; |
27 | 36 | ||
28 | va_start(ap, lpFormat); | 37 | va_start(ap, lpFormat); |
29 | setWhat( lpFormat, ap ); | 38 | setWhat( lpFormat, ap ); |
30 | va_end(ap); | 39 | va_end(ap); |
40 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
41 | createBacktrace(); | ||
42 | #endif | ||
31 | } | 43 | } |
32 | 44 | ||
33 | Bu::ExceptionBase::ExceptionBase( int nCode ) throw() : | 45 | Bu::ExceptionBase::ExceptionBase( int nCode ) throw() : |
34 | nErrorCode( nCode ), | 46 | nErrorCode( nCode ), |
35 | sWhat( NULL ) | 47 | sWhat( NULL ) |
48 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
49 | , sBT( NULL ) | ||
50 | #endif | ||
36 | { | 51 | { |
52 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
53 | createBacktrace(); | ||
54 | #endif | ||
37 | } | 55 | } |
38 | 56 | ||
39 | Bu::ExceptionBase::ExceptionBase( const ExceptionBase &e ) throw () : | 57 | Bu::ExceptionBase::ExceptionBase( const ExceptionBase &e ) throw () : |
40 | nErrorCode( e.nErrorCode ), | 58 | nErrorCode( e.nErrorCode ), |
41 | sWhat( NULL ) | 59 | sWhat( NULL ) |
60 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
61 | , sBT( NULL ) | ||
62 | #endif | ||
42 | { | 63 | { |
43 | setWhat( e.sWhat ); | 64 | setWhat( e.sWhat ); |
65 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
66 | createBacktrace(); | ||
67 | #endif | ||
44 | } | 68 | } |
45 | 69 | ||
46 | Bu::ExceptionBase::~ExceptionBase() throw() | 70 | Bu::ExceptionBase::~ExceptionBase() throw() |
47 | { | 71 | { |
48 | if( sWhat ) | 72 | delete[] sWhat; |
49 | { | 73 | sWhat = NULL; |
50 | delete[] sWhat; | 74 | #ifdef LIBBU_EXCEPTION_BACKTRACE |
51 | sWhat = NULL; | 75 | delete[] sBT; |
52 | } | 76 | sBT = NULL; |
77 | #endif | ||
53 | } | 78 | } |
54 | 79 | ||
55 | void Bu::ExceptionBase::setWhat( const char *lpFormat, va_list &vargs ) | 80 | void Bu::ExceptionBase::setWhat( const char *lpFormat, va_list &vargs ) |
@@ -82,3 +107,43 @@ int Bu::ExceptionBase::getErrorCode() | |||
82 | return nErrorCode; | 107 | return nErrorCode; |
83 | } | 108 | } |
84 | 109 | ||
110 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
111 | const char *Bu::ExceptionBase::getBacktrace() const throw() | ||
112 | { | ||
113 | return sBT; | ||
114 | } | ||
115 | |||
116 | #include "bu/fstring.h" | ||
117 | #include <execinfo.h> | ||
118 | |||
119 | void Bu::ExceptionBase::createBacktrace() | ||
120 | { | ||
121 | void *array[1000]; | ||
122 | size_t size; | ||
123 | char **strings; | ||
124 | size_t i; | ||
125 | |||
126 | size = backtrace (array, 1000); | ||
127 | strings = backtrace_symbols (array, size); | ||
128 | |||
129 | Bu::FString s; | ||
130 | s.format("Obtained %zd stack frames.\n", size ); | ||
131 | |||
132 | for (i = 0; i < size; i++) | ||
133 | { | ||
134 | s += strings[i]; | ||
135 | s += "\n"; | ||
136 | } | ||
137 | |||
138 | free (strings); | ||
139 | |||
140 | sBT = new char[s.getSize()+1]; | ||
141 | strcpy( sBT, s.getStr() ); | ||
142 | } | ||
143 | |||
144 | #else | ||
145 | const char *Bu::ExceptionBase::getBacktrace() const throw() | ||
146 | { | ||
147 | return "Backtrace support is not compiled in.\n"; | ||
148 | } | ||
149 | #endif | ||