ObjFW  Diff

Differences From Artifact [122354a46f]:

To Artifact [18d7beaf46]:


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * file.
 */

#include "config.h"

#include <stdlib.h>

#ifdef HAVE_EXECINFO_H
# include <execinfo.h>
#endif

#import "OFException.h"
#import "OFString.h"
#import "OFArray.h"

#import "autorelease.h"







|
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * 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"
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

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
}

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

	_inClass = class;
#ifdef HAVE_EXECINFO_H









	_backtraceSize = backtrace(_backtraceBuffer,
	    OF_EXCEPTION_MAX_BACKTRACE_SIZE);


































#endif

	return self;
}

- (void)dealloc
{
	[_backtrace release];

	[super dealloc];
}

- (Class)inClass
{
	return _inClass;
}

- (OFString*)description
{
	return [OFString stringWithFormat:
	    @"An exception of class %@ occurred in class %@!",
	    object_getClass(self), _inClass];
}

- (OFArray*)backtrace
{
#ifdef HAVE_EXECINFO_H
	char **symbols;



	if (_backtrace != nil)
		return _backtrace;

	if (_backtraceSize < 1)
		return nil;



	symbols = backtrace_symbols(_backtraceBuffer, _backtraceSize);
	@try {
		int i;



		_backtrace = [[OFMutableArray alloc] init];

		for (i = 0; i < _backtraceSize; i++) {
			void *pool = objc_autoreleasePoolPush();
			OFString *symbol;


			symbol = [OFString
			    stringWithCString: symbols[i]
				     encoding: OF_STRING_ENCODING_NATIVE];

			[_backtrace addObject: symbol];

			objc_autoreleasePoolPop(pool);
		}
	} @finally {
		free(symbols);
	}


	[_backtrace makeImmutable];

	return _backtrace;
#else
	return nil;
#endif
}
@end







|
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
<
<
<
<
<
<














|
|
>
>

<
|
|
<
|
>
>

<
<
|
>

>
|

|
<
|
|
>
|
|
<
>
|
|
<
|
<
<
|
>

|

|





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
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
139
140

141
142
143

144


145
146
147
148
149
150
151
152
153
154
155
}

- 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)
	GET_FRAME(6)
	GET_FRAME(7)
	GET_FRAME(8)
	GET_FRAME(9)
	GET_FRAME(10)
	GET_FRAME(11)
	GET_FRAME(12)
	GET_FRAME(13)
	GET_FRAME(14)
	GET_FRAME(15)
	GET_FRAME(16)
	GET_FRAME(17)
	GET_FRAME(18)
	GET_FRAME(19)
	GET_FRAME(20)
	GET_FRAME(21)
	GET_FRAME(22)
	GET_FRAME(23)
	GET_FRAME(24)
	GET_FRAME(25)
	GET_FRAME(26)
	GET_FRAME(27)
	GET_FRAME(28)
	GET_FRAME(29)
	GET_FRAME(30)
	GET_FRAME(31)
# undef GET_FRAME
backtrace_done:
#endif

	return self;
}








- (Class)inClass
{
	return _inClass;
}

- (OFString*)description
{
	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)
				info.dli_sname = "??";

			[backtrace addObject:

			    [OFString stringWithFormat: @"%p <%s+%td> at %s",
							addr, info.dli_sname,
							offset,
							info.dli_fname]];
		} else

# endif
			[backtrace addObject:
			    [OFString stringWithFormat: @"%p", addr]];

	}



	objc_autoreleasePoolPop(pool);

	[backtrace makeImmutable];

	return backtrace;
#else
	return nil;
#endif
}
@end