39
40
41
42
43
44
45
46
47
48
49
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
39
40
41
42
43
44
45
46
47
48
49
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
75
76
|
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
+
-
|
# import "threading.h"
#endif
#if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS)
# include <winerror.h>
#endif
/*
* Define HAVE_DWARF_EXCEPTIONS if OBJC_ZEROCOST_EXCEPTIONS is defined, but
* don't do so on iOS, as it is defined there even if SjLj exceptions are used.
*/
#ifndef HAVE_DWARF_EXCEPTIONS
# if defined(OBJC_ZEROCOST_EXCEPTIONS) && !defined(OF_IOS)
# define HAVE_DWARF_EXCEPTIONS
# endif
#endif
/*
* Define HAVE_DWARF_EXCEPTIONS if HAVE_SEH_EXCEPTIONS is defined, as SEH
* exceptions are implemented as a wrapper around DWARF exceptions.
*/
#ifdef HAVE_SEH_EXCEPTIONS
# define HAVE_DWARF_EXCEPTIONS
#endif
#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__)
# define HAVE_ARM_EHABI_EXCEPTIONS
#endif
#ifdef HAVE_DWARF_EXCEPTIONS
struct _Unwind_Context;
typedef enum {
_URC_OK = 0,
_URC_END_OF_STACK = 5
}_Unwind_Reason_Code;
struct backtrace_ctx {
void **backtrace;
uint8_t i;
};
#ifdef HAVE__UNWIND_BACKTRACE
extern _Unwind_Reason_Code _Unwind_Backtrace(
_Unwind_Reason_Code (*)(struct _Unwind_Context *, void *), void *);
#endif
# ifndef HAVE_ARM_EHABI_EXCEPTIONS
#ifndef HAVE_ARM_EHABI_EXCEPTIONS
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
# else
#else
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
void *);
# endif
#endif
#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;
OF_CONSTRUCTOR()
{
|
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
-
+
|
}
# endif
#endif
return ret;
}
#ifdef HAVE_DWARF_EXCEPTIONS
#ifdef HAVE__UNWIND_BACKTRACE
static _Unwind_Reason_Code
backtrace_callback(struct _Unwind_Context *ctx, void *data)
{
struct backtrace_ctx *bt = data;
if (bt->i < OF_BACKTRACE_SIZE) {
# ifndef HAVE_ARM_EHABI_EXCEPTIONS
|
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
-
+
|
@implementation OFException
+ (instancetype)exception
{
return [[[self alloc] init] autorelease];
}
#ifdef HAVE_DWARF_EXCEPTIONS
#ifdef HAVE__UNWIND_BACKTRACE
- (instancetype)init
{
struct backtrace_ctx ctx;
self = [super init];
ctx.backtrace = _backtrace;
|
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
-
+
|
{
return [OFString stringWithFormat:
@"An exception of type %@ occurred!", [self class]];
}
- (OFArray OF_GENERIC(OFString *) *)backtrace
{
#ifdef HAVE_DWARF_EXCEPTIONS
#ifdef HAVE__UNWIND_BACKTRACE
OFMutableArray OF_GENERIC(OFString *) *backtrace =
[OFMutableArray array];
void *pool = objc_autoreleasePoolPush();
for (uint8_t i = 0;
i < OF_BACKTRACE_SIZE && _backtrace[i] != NULL; i++) {
# ifdef HAVE_DLADDR
|