Overview
Comment: | Use _Unwind_Backtrace() to get a backtrace.
With this, neither the buggy __builtin_return_address() nor the GNU-only |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
259f59324452f3188ad0bef03d85fbcd |
User & Date: | js on 2013-06-11 22:55:07 |
Other Links: | manifest | tags |
Context
2013-06-11
| ||
23:33 | Initial sockets support for the Wii. check-in: ffb91daffe user: js tags: trunk | |
22:55 | Use _Unwind_Backtrace() to get a backtrace. check-in: 259f593244 user: js tags: trunk | |
2013-06-03
| ||
21:38 | OFException: Cleaner way to check architecture. check-in: 42ed7e394c user: js tags: trunk | |
Changes
Modified configure.ac from [c5958dcc8b] to [538d135f42].
︙ | ︙ | |||
747 748 749 750 751 752 753 | ;; esac AS_IF([test x"$have_processes" = x"yes"], [ AC_SUBST(OFPROCESS_M, "OFProcess.m") AC_DEFINE(OF_HAVE_PROCESSES, 1, [Whether we have processes]) ]) | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | ;; esac AS_IF([test x"$have_processes" = x"yes"], [ AC_SUBST(OFPROCESS_M, "OFProcess.m") AC_DEFINE(OF_HAVE_PROCESSES, 1, [Whether we have processes]) ]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_CHECK_HEADER(Foundation/NSObject.h, [ AC_SUBST(FOUNDATION_COMPAT_M, "foundation-compat.m") AC_SUBST(BRIDGE, "bridge") AS_IF([test x"$enable_shared" != x"no"], [ AC_SUBST(OBJFW_BRIDGE_SHARED_LIB, |
︙ | ︙ |
Modified src/exceptions/OFException.h from [3edc7f9b6e] to [cc67cf334c].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #import "OFObject.h" @class OFString; @class OFArray; @class OFMutableArray; /*! * @brief The base class for all exceptions in ObjFW * * The OFException class is the base class for all exceptions in ObjFW, except * the OFAllocFailedException. */ @interface OFException: OFObject { Class _inClass; | > > | < | 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 | #import "OFObject.h" @class OFString; @class OFArray; @class OFMutableArray; #define OF_BACKTRACE_SIZE 32 /*! * @brief The base class for all exceptions in ObjFW * * The OFException class is the base class for all exceptions in ObjFW, except * the OFAllocFailedException. */ @interface OFException: OFObject { Class _inClass; void *_backtrace[OF_BACKTRACE_SIZE]; } #ifdef OF_HAVE_PROPERTIES @property (readonly) Class inClass; #endif /*! |
︙ | ︙ |
Modified src/exceptions/OFException.m from [d08e1839ba] to [59da75fa7e].
︙ | ︙ | |||
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 |