Differences From Artifact [d08e1839ba]:
- File src/exceptions/OFException.m — part of check-in [42ed7e394c] at 2013-06-03 21:38:31 on branch trunk — OFException: Cleaner way to check architecture. (user: js, size: 3783) [annotate] [blame] [check-ins using]
To Artifact [59da75fa7e]:
- File
src/exceptions/OFException.m
— part of check-in
[259f593244]
at
2013-06-11 22:55:07
on branch trunk
— Use _Unwind_Backtrace() to get a backtrace.
With this, neither the buggy __builtin_return_address() nor the GNU-only
backtrace() are required for a backtrace. (user: js, size: 2782) [annotate] [blame] [check-ins using]
︙ | ︙ | |||
14 15 16 17 18 19 20 | * file. */ #include "config.h" #include <stdlib.h> | < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 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 | * file. */ #include "config.h" #include <stdlib.h> #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFString.h" #import "OFArray.h" #import "autorelease.h" struct _Unwind_Context; typedef enum { _URC_OK = 0, _URC_END_OF_STACK = 5 }_Unwind_Reason_Code; struct backtrace_ctx { void **backtrace; uint_fast8_t i; }; extern _Unwind_Reason_Code _Unwind_Backtrace( _Unwind_Reason_Code(*)(struct _Unwind_Context*, void*), void*); extern uintptr_t _Unwind_GetIP(struct _Unwind_Context*); static _Unwind_Reason_Code backtrace_callback(struct _Unwind_Context *ctx, void *data) { struct backtrace_ctx *bt = data; if (bt->i < OF_BACKTRACE_SIZE) { bt->backtrace[bt->i++] = (void*)_Unwind_GetIP(ctx); return _URC_OK; } return _URC_END_OF_STACK; } @implementation OFException + (instancetype)exceptionWithClass: (Class)class { return [[[self alloc] initWithClass: class] autorelease]; } |
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 | } abort(); } - initWithClass: (Class)class { self = [super init]; _inClass = class; | > > | < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > | < < < > | > | | > > | > | | | | > > > | | < < < > < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | } abort(); } - initWithClass: (Class)class { struct backtrace_ctx ctx; self = [super init]; _inClass = class; ctx.backtrace = _backtrace; ctx.i = 0; _Unwind_Backtrace(backtrace_callback, &ctx); return self; } - (Class)inClass { return _inClass; } - (OFString*)description { return [OFString stringWithFormat: @"An exception of class %@ occurred in class %@!", object_getClass(self), _inClass]; } - (OFArray*)backtrace { OFMutableArray *backtrace = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); uint_fast8_t i; for (i = 0; i < OF_BACKTRACE_SIZE && _backtrace[i] != NULL; i++) { #ifdef HAVE_DLFCN_H Dl_info info; if (dladdr(_backtrace[i], &info)) { ptrdiff_t offset = (char*)_backtrace[i] - (char*)info.dli_saddr; if (info.dli_sname == NULL) info.dli_sname = "??"; [backtrace addObject: [OFString stringWithFormat: @"%p <%s+%td> at %s", _backtrace[i], info.dli_sname, offset, info.dli_fname]]; } else #endif [backtrace addObject: [OFString stringWithFormat: @"%p", _backtrace[i]]]; } objc_autoreleasePoolPop(pool); [backtrace makeImmutable]; return backtrace; } @end |