ObjFW  Diff

Differences From Artifact [18d7beaf46]:

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


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
}

- initWithClass: (Class)class
{
	self = [super init];

	_inClass = class;


#ifdef HAVE_BUILTIN_RETURN_ADDRESS
	/*
	 * 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 ((_returnAddresses[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)







>
>
|




|
|
|
<
|







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



























118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	return [OFString stringWithFormat:
	    @"An exception of class %@ occurred in class %@!",
	    object_getClass(self), _inClass];
}

- (OFArray*)backtrace
{



























#ifdef HAVE_BUILTIN_RETURN_ADDRESS
	OFMutableArray *backtrace = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();
	uint_fast8_t i;

	for (i = 0; i < 32 && _returnAddresses[i] != NULL; i++) {
		void *addr =
		    __builtin_extract_return_addr(_returnAddresses[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)







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|




|

|







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)