ObjFW  Diff

Differences From Artifact [c381d0d5f6]:

To Artifact [5ced4219b2]:


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







+
+
+







-
-
-
-












-
+

-
+
















-
+



-
+




-
+




-
+







#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif

#import "OFException.h"
#import "OFArray.h"
#import "OFLocale.h"
#ifdef OF_HAVE_THREADS
# import "OFPlainMutex.h"
#endif
#import "OFString.h"
#import "OFSystemInfo.h"

#import "OFInitializationFailedException.h"
#import "OFLockFailedException.h"
#import "OFUnlockFailedException.h"

#ifdef OF_HAVE_THREADS
# import "mutex.h"
#endif

#if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS)
# include <winerror.h>
#endif

#if defined(OF_ARM) && !defined(__ARM_DWARF_EH__)
# define HAVE_ARM_EHABI_EXCEPTIONS
#endif

struct _Unwind_Context;
typedef enum {
	_URC_OK		  = 0,
	_URC_END_OF_STACK = 5
}_Unwind_Reason_Code;
} _Unwind_Reason_Code;

struct backtrace_ctx {
struct BacktraceCtx {
	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
extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *);
#else
extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int,
    void *);
#endif

#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;
static OFPlainMutex mutex;

OF_CONSTRUCTOR()
{
	OF_ENSURE(of_mutex_new(&mutex) == 0);
	OFEnsure(OFPlainMutexNew(&mutex) == 0);
}

OF_DESTRUCTOR()
{
	of_mutex_free(&mutex);
	OFPlainMutexFree(&mutex);
}
#endif

OFString *
of_strerror(int errNo)
OFStrError(int errNo)
{
	OFString *ret;
#ifdef HAVE_STRERROR_R
	char buffer[256];
#endif

	if (errNo == 0)
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
212
213
214
215

216
217
218
219
220
221
222
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202

203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221







-
+









-
+










-
+







	if (strerror_r(errNo, buffer, 256) != 0)
		return @"Unknown error (strerror_r failed)";

	ret = [OFString stringWithCString: buffer
				 encoding: [OFLocale encoding]];
#else
# ifdef OF_HAVE_THREADS
	if (of_mutex_lock(&mutex) != 0)
	if (OFPlainMutexLock(&mutex) != 0)
		@throw [OFLockFailedException exception];

	@try {
# endif
		ret = [OFString
		    stringWithCString: strerror(errNo)
			     encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
	} @finally {
		if (of_mutex_unlock(&mutex) != 0)
		if (OFPlainMutexUnlock(&mutex) != 0)
			@throw [OFUnlockFailedException exception];
	}
# endif
#endif

	return ret;
}

#ifdef OF_WINDOWS
OFString *
of_windows_status_to_string(LSTATUS status)
OFWindowsStatusToString(LSTATUS status)
{
	OFString *string = nil;
	void *buffer;

	if ([OFSystemInfo isWindowsNT]) {
		if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
		    FORMAT_MESSAGE_ALLOCATE_BUFFER |
251
252
253
254
255
256
257
258

259
260

261
262

263
264
265
266
267
268
269
250
251
252
253
254
255
256

257
258

259
260

261
262
263
264
265
266
267
268







-
+

-
+

-
+








	return string;
}
#endif

#ifdef HAVE__UNWIND_BACKTRACE
static _Unwind_Reason_Code
backtrace_callback(struct _Unwind_Context *ctx, void *data)
backtraceCallback(struct _Unwind_Context *ctx, void *data)
{
	struct backtrace_ctx *bt = data;
	struct BacktraceCtx *bt = data;

	if (bt->i < OF_BACKTRACE_SIZE) {
	if (bt->i < OFBacktraceSize) {
# ifndef HAVE_ARM_EHABI_EXCEPTIONS
		bt->backtrace[bt->i++] = (void *)_Unwind_GetIP(ctx);
# else
		uintptr_t ip;

		_Unwind_VRS_Get(ctx, 0, 15, 0, &ip);
		bt->backtrace[bt->i++] = (void *)(ip & ~1);
280
281
282
283
284
285
286
287

288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
279
280
281
282
283
284
285

286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311

312
313
314
315
316
317
318







-
+





-
+


















-
+
-







{
	return [[[self alloc] init] autorelease];
}

#ifdef HAVE__UNWIND_BACKTRACE
- (instancetype)init
{
	struct backtrace_ctx ctx;
	struct BacktraceCtx ctx;

	self = [super init];

	ctx.backtrace = _backtrace;
	ctx.i = 0;
	_Unwind_Backtrace(backtrace_callback, &ctx);
	_Unwind_Backtrace(backtraceCallback, &ctx);

	return self;
}
#endif

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

- (OFArray OF_GENERIC(OFString *) *)backtrace
{
#ifdef HAVE__UNWIND_BACKTRACE
	OFMutableArray OF_GENERIC(OFString *) *backtrace =
	    [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();

	for (uint8_t i = 0;
	for (uint8_t i = 0; i < OFBacktraceSize && _backtrace[i] != NULL; i++) {
	    i < OF_BACKTRACE_SIZE && _backtrace[i] != NULL; i++) {
# ifdef HAVE_DLADDR
		Dl_info info;

		if (dladdr(_backtrace[i], &info)) {
			OFString *frame;

			if (info.dli_sname != NULL) {