-
Notifications
You must be signed in to change notification settings - Fork 696
/
KSCrash.h
313 lines (264 loc) · 11.2 KB
/
KSCrash.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
//
// KSCrash.h
//
// Created by Karl Stenerud on 2012-01-28.
//
// Copyright (c) 2012 Karl Stenerud. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall remain in place
// in this source code.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import <Foundation/Foundation.h>
#import "KSCrashReportWriter.h"
#import "KSCrashReportFilter.h"
#import "KSCrashMonitorType.h"
typedef enum
{
KSCrashDemangleLanguageNone = 0,
KSCrashDemangleLanguageCPlusPlus = 1,
KSCrashDemangleLanguageSwift = 2,
KSCrashDemangleLanguageAll = ~1
} KSCrashDemangleLanguage;
typedef enum
{
KSCDeleteNever,
KSCDeleteOnSucess,
KSCDeleteAlways
} KSCDeleteBehavior;
/**
* Reports any crashes that occur in the application.
*
* The crash reports will be located in $APP_HOME/Library/Caches/KSCrashReports
*/
@interface KSCrash : NSObject
#pragma mark - Configuration -
/** Init KSCrash instance with custom base path. */
- (id) initWithBasePath:(NSString *)basePath;
/** A dictionary containing any info you'd like to appear in crash reports. Must
* contain only JSON-safe data: NSString for keys, and NSDictionary, NSArray,
* NSString, NSDate, and NSNumber for values.
*
* Default: nil
*/
@property(atomic,readwrite,retain) NSDictionary* userInfo;
/** What to do after sending reports via sendAllReportsWithCompletion:
*
* - Use KSCDeleteNever if you will manually manage the reports.
* - Use KSCDeleteAlways if you will be using an alert confirmation (otherwise it
* will nag the user incessantly until he selects "yes").
* - Use KSCDeleteOnSuccess for all other situations.
*
* Default: KSCDeleteAlways
*/
@property(nonatomic,readwrite,assign) KSCDeleteBehavior deleteBehaviorAfterSendAll;
/** The monitors that will or have been installed.
* Note: This value may change once KSCrash is installed if some monitors
* fail to install.
*
* Default: KSCrashMonitorTypeProductionSafeMinimal
*/
@property(nonatomic,readwrite,assign) KSCrashMonitorType monitoring;
/** Maximum time to allow the main thread to run without returning.
* If a task occupies the main thread for longer than this interval, the
* watchdog will consider the queue deadlocked and shut down the app and write a
* crash report.
*
* Note: You must have added KSCrashMonitorTypeMainThreadDeadlock to the monitoring
* property in order for this to have any effect.
*
* Warning: Make SURE that nothing in your app that runs on the main thread takes
* longer to complete than this value or it WILL get shut down! This includes
* your app startup process, so you may need to push app initialization to
* another thread, or perhaps set this to a higher value until your application
* has been fully initialized.
*
* WARNING: This is still causing false positives in some cases. Use at own risk!
*
* 0 = Disabled.
*
* Default: 0
*/
@property(nonatomic,readwrite,assign) double deadlockWatchdogInterval;
/** If YES, attempt to fetch dispatch queue names for each running thread.
*
* WARNING: There is a chance that this will crash on a ksthread_getQueueName() call!
*
* Enable at your own risk.
*
* Default: NO
*/
@property(nonatomic,readwrite,assign) BOOL searchQueueNames;
/** If YES, introspect memory contents during a crash.
* Any Objective-C objects or C strings near the stack pointer or referenced by
* cpu registers or exceptions will be recorded in the crash report, along with
* their contents.
*
* Default: YES
*/
@property(nonatomic,readwrite,assign) BOOL introspectMemory;
/** If YES, monitor all Objective-C/Swift deallocations and keep track of any
* accesses after deallocation.
*
* Default: NO
*/
@property(nonatomic,readwrite,assign) BOOL catchZombies;
/** List of Objective-C classes that should never be introspected.
* Whenever a class in this list is encountered, only the class name will be recorded.
* This can be useful for information security concerns.
*
* Default: nil
*/
@property(nonatomic,readwrite,retain) NSArray* doNotIntrospectClasses;
/** The maximum number of reports allowed on disk before old ones get deleted.
*
* Default: 5
*/
@property(nonatomic,readwrite,assign) int maxReportCount;
/** The report sink where reports get sent.
* This MUST be set or else the reporter will not send reports (although it will
* still record them).
*
* Note: If you use an installation, it will automatically set this property.
* Do not modify it in such a case.
*/
@property(nonatomic,readwrite,retain) id<KSCrashReportFilter> sink;
/** C Function to call during a crash report to give the callee an opportunity to
* add to the report. NULL = ignore.
*
* WARNING: Only call async-safe functions from this function! DO NOT call
* Objective-C methods!!!
*
* Note: If you use an installation, it will automatically set this property.
* Do not modify it in such a case.
*/
@property(nonatomic,readwrite,assign) KSReportWriteCallback onCrash;
/** Add a copy of KSCrash's console log messages to the crash report.
*/
@property(nonatomic,readwrite,assign) BOOL addConsoleLogToReport;
/** Print the previous app run log to the console when installing KSCrash.
* This is primarily for debugging purposes.
*/
@property(nonatomic,readwrite,assign) BOOL printPreviousLog;
/** Which languages to demangle when getting stack traces (default KSCrashDemangleLanguageAll) */
@property(nonatomic,readwrite,assign) KSCrashDemangleLanguage demangleLanguages;
/** Exposes the uncaughtExceptionHandler if set from KSCrash. Is nil if debugger is running. **/
@property (nonatomic, assign) NSUncaughtExceptionHandler *uncaughtExceptionHandler;
/** Exposes the currentSnapshotUserReportedExceptionHandler if set from KSCrash. Is nil if debugger is running. **/
@property (nonatomic, assign) NSUncaughtExceptionHandler *currentSnapshotUserReportedExceptionHandler;
#pragma mark - Information -
/** Total active time elapsed since the last crash. */
@property(nonatomic,readonly,assign) NSTimeInterval activeDurationSinceLastCrash;
/** Total time backgrounded elapsed since the last crash. */
@property(nonatomic,readonly,assign) NSTimeInterval backgroundDurationSinceLastCrash;
/** Number of app launches since the last crash. */
@property(nonatomic,readonly,assign) int launchesSinceLastCrash;
/** Number of sessions (launch, resume from suspend) since last crash. */
@property(nonatomic,readonly,assign) int sessionsSinceLastCrash;
/** Total active time elapsed since launch. */
@property(nonatomic,readonly,assign) NSTimeInterval activeDurationSinceLaunch;
/** Total time backgrounded elapsed since launch. */
@property(nonatomic,readonly,assign) NSTimeInterval backgroundDurationSinceLaunch;
/** Number of sessions (launch, resume from suspend) since app launch. */
@property(nonatomic,readonly,assign) int sessionsSinceLaunch;
/** If true, the application crashed on the previous launch. */
@property(nonatomic,readonly,assign) BOOL crashedLastLaunch;
/** The total number of unsent reports. Note: This is an expensive operation. */
@property(nonatomic,readonly,assign) int reportCount;
/** Information about the operating system and environment */
@property(nonatomic,readonly,strong) NSDictionary* systemInfo;
#pragma mark - API -
/** Get the singleton instance of the crash reporter.
*/
+ (KSCrash*) sharedInstance;
/** Install the crash reporter.
* The reporter will record crashes, but will not send any crash reports unless
* sink is set.
*
* @return YES if the reporter successfully installed.
*/
- (BOOL) install;
/** Send all outstanding crash reports to the current sink.
* It will only attempt to send the most recent 5 reports. All others will be
* deleted. Once the reports are successfully sent to the server, they may be
* deleted locally, depending on the property "deleteAfterSendAll".
*
* Note: property "sink" MUST be set or else this method will call onCompletion
* with an error.
*
* @param onCompletion Called when sending is complete (nil = ignore).
*/
- (void) sendAllReportsWithCompletion:(KSCrashReportFilterCompletion) onCompletion;
/** Get all unsent report IDs.
*
* @return An array with report IDs.
*/
- (NSArray*) reportIDs;
/** Get report.
*
* @param reportID An ID of report.
*
* @return A dictionary with report fields. See KSCrashReportFields.h for available fields.
*/
- (NSDictionary*) reportWithID:(NSNumber*) reportID;
/** Delete all unsent reports.
*/
- (void) deleteAllReports;
/** Delete report.
*
* @param reportID An ID of report to delete.
*/
- (void) deleteReportWithID:(NSNumber*) reportID;
/** Report a custom, user defined exception.
* This can be useful when dealing with scripting languages.
*
* If terminateProgram is true, all sentries will be uninstalled and the application will
* terminate with an abort().
*
* @param name The exception name (for namespacing exception types).
*
* @param reason A description of why the exception occurred.
*
* @param language A unique language identifier.
*
* @param lineOfCode A copy of the offending line of code (nil = ignore).
*
* @param stackTrace An array of frames (dictionaries or strings) representing the call stack leading to the exception (nil = ignore).
*
* @param logAllThreads If true, suspend all threads and log their state. Note that this incurs a
* performance penalty, so it's best to use only on fatal errors.
*
* @param terminateProgram If true, do not return from this function call. Terminate the program instead.
*/
- (void) reportUserException:(NSString*) name
reason:(NSString*) reason
language:(NSString*) language
lineOfCode:(NSString*) lineOfCode
stackTrace:(NSArray*) stackTrace
logAllThreads:(BOOL) logAllThreads
terminateProgram:(BOOL) terminateProgram;
/** Experimental feature. Works like LD_PRELOAD. Enable C++ exceptions catching with __cxa_throw swap,
* by updating pointers in the indirect symbol table, which is located in the __LINKEDIT segment.
* It supports getting a true stackstace even in dynamically linked libraries.
* Also allows a user to override original __cxa_throw with his implementation.
*/
- (void) enableSwapOfCxaThrow;
@end
//! Project version number for KSCrashFramework.
FOUNDATION_EXPORT const double KSCrashFrameworkVersionNumber;
//! Project version string for KSCrashFramework.
FOUNDATION_EXPORT const unsigned char KSCrashFrameworkVersionString[];