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 | |
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.
-rw-r--r-- | src/exceptionbase.cpp | 75 | ||||
-rw-r--r-- | src/exceptionbase.h | 12 |
2 files changed, 82 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 | ||
diff --git a/src/exceptionbase.h b/src/exceptionbase.h index 391e41d..4d1d2ff 100644 --- a/src/exceptionbase.h +++ b/src/exceptionbase.h | |||
@@ -12,6 +12,12 @@ | |||
12 | #include <exception> | 12 | #include <exception> |
13 | #include <stdarg.h> | 13 | #include <stdarg.h> |
14 | 14 | ||
15 | // This shouldn't normally be defined here, I don't think it's all that portable | ||
16 | // and it also changes the class interface, we should find out how much of | ||
17 | // an issue that is, we could just put in an empty getBacktrace() function for | ||
18 | // when you don't have support for it... | ||
19 | #define LIBBU_EXCEPTION_BACKTRACE | ||
20 | |||
15 | namespace Bu | 21 | namespace Bu |
16 | { | 22 | { |
17 | /** | 23 | /** |
@@ -83,9 +89,15 @@ namespace Bu | |||
83 | */ | 89 | */ |
84 | void setWhat( const char *lpText ); | 90 | void setWhat( const char *lpText ); |
85 | 91 | ||
92 | const char *getBacktrace() const throw(); | ||
93 | |||
86 | private: | 94 | private: |
87 | int nErrorCode; /**< The code for the error that occured. */ | 95 | int nErrorCode; /**< The code for the error that occured. */ |
88 | char *sWhat; /**< The text string telling people what went wrong. */ | 96 | char *sWhat; /**< The text string telling people what went wrong. */ |
97 | #ifdef LIBBU_EXCEPTION_BACKTRACE | ||
98 | char *sBT; /**< The backtrace text. */ | ||
99 | void createBacktrace(); | ||
100 | #endif | ||
89 | }; | 101 | }; |
90 | } | 102 | } |
91 | 103 | ||