]> git.saurik.com Git - apple/security.git/blob - OSX/utilities/simulate_crash.c
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / utilities / simulate_crash.c
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__
16 typedef bool BOOL;
17 #else
18 typedef 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
23 static void *
24 __security_get_CrashReporterSupport(void)
25 {
26 static void *image = NULL;
27 static dispatch_once_t onceToken;
28 dispatch_once(&onceToken, ^{
29 image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW);
30 });
31 return image;
32 }
33
34 static void __security_simulatecrash_link(CFStringRef reason, uint32_t code)
35 {
36 #if !TARGET_OS_SIMULATOR
37 // Prototype defined in <CrashReporterSupport/CrashReporterSupport.h>, but objC only.
38 // Soft linking here so we don't link unless we hit this.
39 static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description) = NULL;
40
41 static dispatch_once_t once = 0;
42 dispatch_once(&once, ^{
43 void *image = __security_get_CrashReporterSupport();
44 if (image)
45 __SimulateCrash = dlsym(image, "SimulateCrash");
46 });
47
48 if (__SimulateCrash)
49 __SimulateCrash(getpid(), code, reason);
50 else
51 secerror("SimulateCrash not available");
52 #else
53 secerror("SimulateCrash not available in iOS simulator");
54 #endif
55 }
56
57 static int __simulate_crash_counter = -1;
58
59 void __security_simulatecrash(CFStringRef reason, uint32_t code)
60 {
61 secerror("Simulating crash, reason: %@, code=%08x", reason, code);
62 if (__simulate_crash_counter < 0)
63 __security_simulatecrash_link(reason, code);
64 else
65 __simulate_crash_counter++;
66 }
67
68 void __security_stackshotreport(CFStringRef reason, uint32_t code)
69 {
70 secerror("stackshot report, reason: %@, code=%08x", reason, code);
71 #if !TARGET_OS_SIMULATOR
72 // Prototype defined in <CrashReporterSupport/CrashReporterSupport.h>, but objC only.
73 // Soft linking here so we don't link unless we hit this.
74 static BOOL (*__WriteStackshotReport)(void *, mach_exception_data_type_t) = NULL;
75
76 static dispatch_once_t once = 0;
77 dispatch_once(&once, ^{
78 void *image = __security_get_CrashReporterSupport();
79 if (image)
80 __WriteStackshotReport = dlsym(image, "WriteStackshotReport");
81 });
82
83 if (__WriteStackshotReport)
84 __WriteStackshotReport((void *)reason, code);
85 else
86 secerror("WriteStackshotReport not available");
87 #else
88 secerror("WriteStackshotReport not available in iOS simulator");
89 #endif
90 }
91
92
93 int __security_simulatecrash_enable(bool enable)
94 {
95 int count = __simulate_crash_counter;
96 __simulate_crash_counter = enable ? -1 : 0;
97 return count;
98 }