Differences From Artifact [18d7beaf46]:
- File
src/exceptions/OFException.m
— part of check-in
[a889f21180]
at
2013-05-22 20:36:31
on branch trunk
— Don't depened on execinfo.h for backtraces.
Instead, __builtin_return_address() is used now. This makes backtraces
available on many platforms, it even works if dladdr is missing (it does
not show symbol names then, though). (user: js, size: 3039) [annotate] [blame] [check-ins using]
To Artifact [fbd2e39b2b]:
- File
src/exceptions/OFException.m
— part of check-in
[f2a8bdf254]
at
2013-05-25 11:40:28
on branch trunk
— Switch back to backtrace().
The reason is that __builtin_frame_address(n) for n > 0 seems to just
crash on most platforms when -fomit-stack-pointer is specified, which
seems to be the default for many platforms on -O2. The documentation
says that __builtin_frame_address() should return NULL in case it can't
get the frame, but it seems to crash instead.Therefore, this commit reverts to using backtrace() from execinfo.h, if
available. However, as __builtin_frame_address() seems to always work on
PPC (even with -fomit-frame-pointer) and seems to be the only way to get
a backtrace on the Wii, this is still used if backtrace() is unavailable
and __ppc__ defined. (user: js, size: 3823) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | * file. */ #include "config.h" #include <stdlib.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFString.h" #import "OFArray.h" | > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * file. */ #include "config.h" #include <stdlib.h> #ifdef HAVE_EXECINFO_H # include <execinfo.h> #endif #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFString.h" #import "OFArray.h" |
︙ | ︙ | |||
47 48 49 50 51 52 53 | } - initWithClass: (Class)class { self = [super init]; _inClass = class; | > > | | | | < | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | } - initWithClass: (Class)class { self = [super init]; _inClass = class; #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) _backtraceSize = backtrace(_backtrace, 32); #elif defined(HAVE_BUILTIN_RETURN_ADDRESS) && defined(__ppc__) /* * We can't use a loop here, as __builtin_return_address() and * __builtin_frame_address() only allow a constant as parameter. */ # define GET_FRAME(i) \ if (__builtin_frame_address(i + 1) == NULL) \ goto backtrace_done; \ if ((_backtrace[i] = (__builtin_return_address(i))) == NULL) \ goto backtrace_done; GET_FRAME(0) GET_FRAME(1) GET_FRAME(2) GET_FRAME(3) GET_FRAME(4) GET_FRAME(5) |
︙ | ︙ | |||
111 112 113 114 115 116 117 | return [OFString stringWithFormat: @"An exception of class %@ occurred in class %@!", object_getClass(self), _inClass]; } - (OFArray*)backtrace { | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | return [OFString stringWithFormat: @"An exception of class %@ occurred in class %@!", object_getClass(self), _inClass]; } - (OFArray*)backtrace { #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) OFMutableArray *backtrace = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); char **symbols; if (_backtraceSize < 0) return nil; symbols = backtrace_symbols(_backtrace, _backtraceSize); @try { int i; for (i = 0; i < _backtraceSize; i++) { OFString *symbol = [OFString stringWithCString: symbols[i] encoding: OF_STRING_ENCODING_NATIVE]; [backtrace addObject: symbol]; } } @finally { free(symbols); } objc_autoreleasePoolPop(pool); [backtrace makeImmutable]; return backtrace; #elif defined(HAVE_BUILTIN_RETURN_ADDRESS) && defined(__ppc__) OFMutableArray *backtrace = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); uint_fast8_t i; for (i = 0; i < 32 && _backtrace[i] != NULL; i++) { void *addr = __builtin_extract_return_addr(_backtrace[i]); # ifdef HAVE_DLFCN_H Dl_info info; if (dladdr(addr, &info)) { ptrdiff_t offset = (char*)addr - (char*)info.dli_saddr; if (info.dli_sname == NULL) |
︙ | ︙ |