X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/31875a974789e6fabb418ee53dff5e8f10fd8119..refs/heads/master:/runtime/objc-errors.mm?ds=inline diff --git a/runtime/objc-errors.mm b/runtime/objc-errors.mm index 650fcd2..17fdda2 100644 --- a/runtime/objc-errors.mm +++ b/runtime/objc-errors.mm @@ -74,13 +74,8 @@ void _objc_error(id rcv, const char *fmt, va_list args) #else -#include #include <_simple.h> -OBJC_EXPORT void (*_error)(id, const char *, va_list); - -static void _objc_trap(void) __attribute__((noreturn)); - // Return true if c is a UTF8 continuation byte static bool isUTF8Continuation(char c) { @@ -88,6 +83,7 @@ static bool isUTF8Continuation(char c) } // Add "message" to any forthcoming crash log. +mutex_t crashlog_lock; static void _objc_crashlog(const char *message) { char *newmsg; @@ -104,7 +100,6 @@ static void _objc_crashlog(const char *message) } #endif - static mutex_t crashlog_lock; mutex_locker_t lock(crashlog_lock); char *oldmsg = (char *)CRGetCrashLogMessage(); @@ -160,23 +155,15 @@ static void _objc_syslog(const char *message) /* * _objc_error is the default *_error handler. */ -#if __OBJC2__ -__attribute__((noreturn)) -#else +#if !__OBJC2__ // used by ExceptionHandling.framework #endif +__attribute__((noreturn, cold)) void _objc_error(id self, const char *fmt, va_list ap) { - char *buf1; - char *buf2; - - vasprintf(&buf1, fmt, ap); - asprintf(&buf2, "objc[%d]: %s: %s\n", - getpid(), object_getClassName(self), buf1); - _objc_syslog(buf2); - _objc_crashlog(buf2); - - _objc_trap(); + char *buf; + vasprintf(&buf, fmt, ap); + _objc_fatal("%s: %s", object_getClassName(self), buf); } /* @@ -194,25 +181,43 @@ void __objc_error(id rcv, const char *fmt, ...) va_end(vp); } -/* - * this routine handles severe runtime errors...like not being able - * to read the mach headers, allocate space, etc...very uncommon. - */ -void _objc_fatal(const char *fmt, ...) +static __attribute__((noreturn, cold)) +void _objc_fatalv(uint64_t reason, uint64_t flags, const char *fmt, va_list ap) { - va_list ap; char *buf1; - char *buf2; - - va_start(ap,fmt); vasprintf(&buf1, fmt, ap); - va_end (ap); + char *buf2; asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); _objc_syslog(buf2); - _objc_crashlog(buf2); - _objc_trap(); + if (DebugDontCrash) { + char *buf3; + asprintf(&buf3, "objc[%d]: HALTED\n", getpid()); + _objc_syslog(buf3); + _Exit(1); + } + else { + _objc_crashlog(buf1); + abort_with_reason(OS_REASON_OBJC, reason, buf1, flags); + } +} + +void _objc_fatal_with_reason(uint64_t reason, uint64_t flags, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + _objc_fatalv(reason, flags, fmt, ap); +} + +void _objc_fatal(const char *fmt, ...) +{ + va_list ap; + va_start(ap,fmt); + _objc_fatalv(OBJC_EXIT_REASON_UNSPECIFIED, + OS_REASON_FLAG_ONE_TIME_FAILURE, + fmt, ap); } /* @@ -280,22 +285,6 @@ void _objc_inform_now_and_on_crash(const char *fmt, ...) free(buf1); } - -/* Kill the process in a way that generates a crash log. - * This is better than calling exit(). */ -static void _objc_trap(void) -{ - __builtin_trap(); -} - -/* Try to keep _objc_warn_deprecated out of crash logs - * caused by _objc_trap(). rdar://4546883 */ -__attribute__((used)) -static void _objc_trap2(void) -{ - __builtin_trap(); -} - #endif