#include <stdarg.h>
#include <stdbool.h>
#include <_simple.h>
-#include <os/base.h>
#include <errno.h>
+#include <os/base_private.h>
+
+#if __GNUC__
+#define os_constant(x) __builtin_constant_p((x))
+#define os_hardware_trap() __asm__ __volatile__ (""); __builtin_trap()
+#define __OS_COMPILETIME_ASSERT__(e) __extension__({ \
+ char __compile_time_assert__[(e) ? 1 : -1]; \
+ (void)__compile_time_assert__; \
+})
+#else /* __GNUC__ */
+#define os_constant(x) ((long)0)
+#define os_hardware_trap() abort()
+#define __OS_COMPILETIME_ASSERT__(e) (e)
+#endif /* __GNUC__ */
+
+
+/* os_crash() is like os_hardware_trap(), except you get to pass in a crash
+ * message, and it can be redirected to a callback function using
+ * os_set_crash_callback() */
+#define os_crash(msg) \
+ ({ \
+ _os_crash(msg); \
+ os_hardware_trap(); \
+ })
/* This is useful for clients who wish for the messages generated by assumes()
* failures to go somewhere other than (or in addition to) the system log. If
.redirect = &func, \
};
+
+typedef void (*os_crash_callback_t) (const char *);
+
+/* private. use os_get_crash_callback and os_set_crash_callback */
+extern os_crash_callback_t _os_crash_callback;
+
+static inline os_crash_callback_t
+os_get_crash_callback() {
+ return _os_crash_callback;
+}
+
+static inline void
+os_set_crash_callback(os_crash_callback_t callback) {
+ _os_crash_callback = callback;
+}
+
/* The asl_message argument is a _SIMPLE_STRING that, when given to _simple_asl_send(), will
* direct the message to the MessageTracer diagnostic messages store rather than
* the default system log store.
*/
typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const char *);
-#if TARGET_OS_IPHONE
-#define os_set_crash_message(arg) /* no-op */
-#else
#include <CrashReporterClient.h>
-#define os_set_crash_message(arg) _crc_make_setter(message, (arg))
-#endif
+#define os_set_crash_message(arg) CRSetCrashLogMessage(arg)
#define os_assumes(e) __extension__({ \
__typeof__(e) _e = os_fastpath(e); \
__typeof__(e) _e = os_slowpath(e); \
if (_e) { \
if (os_constant(e)) { \
- __OS_COMPILETIME_ASSERT__(!e); \
+ __OS_COMPILETIME_ASSERT__(!(e)); \
} \
_os_assumes_log((uint64_t)(uintptr_t)_e); \
_os_avoid_tail_call(); \
} \
\
char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)_e); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e) { \
if (os_constant(e)) { \
- __OS_COMPILETIME_ASSERT__(!e); \
+ __OS_COMPILETIME_ASSERT__(!(e)); \
} \
\
char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)_e); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e == (__typeof__(e))-1) { \
char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)errno); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e) { \
if (os_constant(e)) { \
- __OS_COMPILETIME_ASSERT__(!e); \
+ __OS_COMPILETIME_ASSERT__(!(e)); \
} \
_os_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \
_os_avoid_tail_call(); \
if (os_constant(e)) { \
__OS_COMPILETIME_ASSERT__(e); \
} \
-\
+ \
char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e) { \
if (os_constant(e)) { \
- __OS_COMPILETIME_ASSERT__(!e); \
+ __OS_COMPILETIME_ASSERT__(!(e)); \
} \
\
char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
__typeof__(e) _e = os_slowpath(e); \
if (_e == (__typeof__(e))-1) { \
char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)errno); \
- os_set_crash_message(_fail_message); \
- os_hardware_trap(); \
+ os_crash(_fail_message); \
free(_fail_message); \
} \
})
+__OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0)
+extern void
+_os_crash(const char *);
+
__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
extern void
_os_assumes_log(uint64_t code);