#include "debugging.h"
#include <dispatch/dispatch.h>
#include <dlfcn.h>
#include <mach/mach.h>
#if TARGET_OS_IPHONE && __LP64__
typedef bool BOOL;
#else
typedef signed char BOOL;
#endif
static void *
__security_get_CrashReporterSupport(void)
{
static void *image = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW);
});
return image;
}
static void __security_simulatecrash_link(CFStringRef reason, uint32_t code)
{
#if !TARGET_OS_SIMULATOR
static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description) = NULL;
static dispatch_once_t once = 0;
dispatch_once(&once, ^{
void *image = __security_get_CrashReporterSupport();
if (image)
__SimulateCrash = dlsym(image, "SimulateCrash");
});
if (__SimulateCrash)
__SimulateCrash(getpid(), code, reason);
else
secerror("SimulateCrash not available");
#else
secerror("SimulateCrash not available in iOS simulator");
#endif
}
static int __simulate_crash_counter = -1;
void __security_simulatecrash(CFStringRef reason, uint32_t code)
{
secerror("Simulating crash, reason: %@, code=%08x", reason, code);
if (__simulate_crash_counter < 0)
__security_simulatecrash_link(reason, code);
else
__simulate_crash_counter++;
}
void __security_stackshotreport(CFStringRef reason, uint32_t code)
{
secerror("stackshot report, reason: %@, code=%08x", reason, code);
#if !TARGET_OS_SIMULATOR
static BOOL (*__WriteStackshotReport)(void *, mach_exception_data_type_t) = NULL;
static dispatch_once_t once = 0;
dispatch_once(&once, ^{
void *image = __security_get_CrashReporterSupport();
if (image)
__WriteStackshotReport = dlsym(image, "WriteStackshotReport");
});
if (__WriteStackshotReport)
__WriteStackshotReport((void *)reason, code);
else
secerror("WriteStackshotReport not available");
#else
secerror("WriteStackshotReport not available in iOS simulator");
#endif
}
int __security_simulatecrash_enable(bool enable)
{
int count = __simulate_crash_counter;
__simulate_crash_counter = enable ? -1 : 0;
return count;
}