summaryrefslogtreecommitdiff
path: root/src/exceptionbase.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-03-04 19:26:24 +0000
committerMike Buland <eichlan@xagasoft.com>2008-03-04 19:26:24 +0000
commit57bbb6651bfc10d9f2404164e3303c3376dfc62c (patch)
tree90bac81adc231a92251ac2d540c0c9d75468f7d4 /src/exceptionbase.cpp
parentb1c614da6f0b248b18e83a014030b5bdfd9c09c6 (diff)
downloadlibbu++-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.cpp75
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 @@
11Bu::ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() : 11Bu::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
22Bu::ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() : 28Bu::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
33Bu::ExceptionBase::ExceptionBase( int nCode ) throw() : 45Bu::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
39Bu::ExceptionBase::ExceptionBase( const ExceptionBase &e ) throw () : 57Bu::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
46Bu::ExceptionBase::~ExceptionBase() throw() 70Bu::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
55void Bu::ExceptionBase::setWhat( const char *lpFormat, va_list &vargs ) 80void 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
111const char *Bu::ExceptionBase::getBacktrace() const throw()
112{
113 return sBT;
114}
115
116#include "bu/fstring.h"
117#include <execinfo.h>
118
119void 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
145const char *Bu::ExceptionBase::getBacktrace() const throw()
146{
147 return "Backtrace support is not compiled in.\n";
148}
149#endif