@@ -42,10 +42,11 @@ # import "OFPlainMutex.h" /* For OFSpinlock */ #endif #import "OFString.h" #import "OFThread.h" #import "OFTimer.h" +#import "OFValue.h" #import "OFAllocFailedException.h" #import "OFEnumerationMutationException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" @@ -250,23 +251,52 @@ #if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__) static void uncaughtExceptionHandler(id exception) { OFString *description = [exception description]; - OFArray *backtrace = nil; + OFArray OF_GENERIC(OFValue *) *stackTraceAddresses = nil; + OFArray OF_GENERIC(OFString *) *stackTraceSymbols = nil; OFStringEncoding encoding = [OFLocale encoding]; fprintf(stderr, "\nRuntime error: Unhandled exception:\n%s\n", [description cStringWithEncoding: encoding]); - if ([exception respondsToSelector: @selector(backtrace)]) - backtrace = [exception backtrace]; + if ([exception respondsToSelector: @selector(stackTraceAddresses)]) + stackTraceAddresses = [exception stackTraceAddresses]; - if (backtrace != nil) { - OFString *s = [backtrace componentsJoinedByString: @"\n "]; - fprintf(stderr, "\nBacktrace:\n %s\n\n", - [s cStringWithEncoding: encoding]); + if (stackTraceAddresses != nil) { + size_t count = stackTraceAddresses.count; + + if ([exception respondsToSelector: + @selector(stackTraceSymbols)]) + stackTraceSymbols = [exception stackTraceSymbols]; + + if (stackTraceSymbols.count != count) + stackTraceSymbols = nil; + + fputs("\nStack trace:\n", stderr); + + if (stackTraceSymbols != nil) { + for (size_t i = 0; i < count; i++) { + void *address = [[stackTraceAddresses + objectAtIndex: i] pointerValue]; + const char *symbol = [[stackTraceSymbols + objectAtIndex: i] + cStringWithEncoding: encoding]; + + fprintf(stderr, " %p %s\n", address, symbol); + } + } else { + for (size_t i = 0; i < count; i++) { + void *address = [[stackTraceAddresses + objectAtIndex: i] pointerValue]; + + fprintf(stderr, " %p\n", address); + } + } + + fputs("\n", stderr); } abort(); } #endif @@ -330,10 +360,14 @@ #endif instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN); if (!objc_constructInstance(class, instance)) { +#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) + OFSpinlockFree(&((struct PreIvars *)(void *) + ((char *)instance - PRE_IVARS_ALIGN))->retainCountSpinlock); +#endif free((char *)instance - PRE_IVARS_ALIGN); @throw [OFInitializationFailedException exceptionWithClass: class]; } @@ -1080,11 +1114,11 @@ unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < sizeof(ptr); i++) { - OFHashAdd(&hash, ptr & 0xFF); + OFHashAddByte(&hash, ptr & 0xFF); ptr >>= 8; } OFHashFinalize(&hash); @@ -1200,10 +1234,14 @@ } - (void)dealloc { objc_destructInstance(self); + +#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) + OFSpinlockFree(&PRE_IVARS->retainCountSpinlock); +#endif free((char *)self - PRE_IVARS_ALIGN); } /* Required to use properties with the Apple runtime */