#else
-#include <vproc_priv.h>
#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)
{
}
// Add "message" to any forthcoming crash log.
+mutex_t crashlog_lock;
static void _objc_crashlog(const char *message)
{
char *newmsg;
}
#endif
- static mutex_t crashlog_lock;
mutex_locker_t lock(crashlog_lock);
char *oldmsg = (char *)CRGetCrashLogMessage();
/*
* _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);
}
/*
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);
}
/*
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