1//
2//  simulate_crash
3//  utilities
4//
5//  Copyright (c) 2014 Apple Inc. All Rights Reserved.
6//
7
8#include "debugging.h"
9
10#include <dispatch/dispatch.h>
11#include <dlfcn.h>
12#include <mach/mach.h>
13
14/// Type to represent a boolean value.
15#if TARGET_OS_IPHONE  &&  __LP64__
16typedef bool BOOL;
17#else
18typedef signed char BOOL;
19// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C"
20// even if -funsigned-char is used.
21#endif
22
23static void __security_simulatecrash_link(CFStringRef reason, uint32_t code)
24{
25#if !TARGET_IPHONE_SIMULATOR
26    // Prototype defined in <CrashReporterSupport/CrashReporterSupport.h>, but objC only.
27    // Soft linking here so we don't link unless we hit this.
28    static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description);
29
30    static dispatch_once_t once = 0;
31    dispatch_once(&once, ^{
32        void *image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW);
33        if (image)
34            __SimulateCrash = dlsym(image, "SimulateCrash");
35        else
36            __SimulateCrash = NULL;
37    });
38
39    if (__SimulateCrash)
40        __SimulateCrash(getpid(), code, reason);
41    else
42        secerror("SimulateCrash not available");
43#else
44    secerror("SimulateCrash not available in iOS simulator");
45#endif
46}
47
48
49void __security_simulatecrash(CFStringRef reason, uint32_t code)
50{
51    secerror("Simulating crash, reason: %@, code=%08x", reason, code);
52    __security_simulatecrash_link(reason, code);
53}
54