KSCrash.h 11 KB

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