BITCrashManager Class Reference
| Inherits from | BITHockeyBaseManager : NSObject |
| Declared in | BITCrashManager.h |
Overview
The crash reporting module.
This is the HockeySDK module for handling crash reports, including when distributed via the App Store. As a foundation it is using the open source, reliable and async-safe crash reporting framework PLCrashReporter.
This module works as a wrapper around the underlying crash reporting framework and provides functionality to detect new crashes, queues them if networking is not available, present a user interface to approve sending the reports to the HockeyApp servers and more.
It also provides options to add additional meta information to each crash report, like userName, userEmail
via BITHockeyManagerDelegate protocol, and additional textual log information via BITCrashManagerDelegate
protocol and a way to detect startup crashes so you can adjust your startup process to get these crash reports
too and delay your app initialization.
Crashes are send the next time the app starts. If crashManagerStatus is set to BITCrashManagerStatusAutoSend,
crashes will be send without any user interaction, otherwise an alert will appear allowing the users to decide
whether they want to send the report or not. This module is not sending the reports right when the crash happens
deliberately, because if is not safe to implement such a mechanism while being async-safe (any Objective-C code
is NOT async-safe!) and not causing more danger like a deadlock of the device, than helping. We found that users
do start the app again because most don’t know what happened, and you will get by far most of the reports.
Sending the reports on startup is done asynchronously (non-blocking). This is the only safe way to ensure that the app won’t be possibly killed by the iOS watchdog process, because startup could take too long and the app could not react to any user input when network conditions are bad or connectivity might be very slow.
It is possible to check upon startup if the app crashed before using didCrashInLastSession and also how much
time passed between the app launch and the crash using timeintervalCrashInLastSessionOccured. This allows you
to add additional code to your app delaying the app start until the crash has been successfully send if the crash
occured within a critical startup timeframe, e.g. after 10 seconds. The BITCrashManagerDelegate protocol provides
various delegates to inform the app about it’s current status so you can continue the remaining app startup setup
after sending has been completed. The documentation contains a guide
How to handle Crashes on startup with an example on how to do that.
More background information on this topic can be found in the following blog post by Landon Fuller, the developer of PLCrashReporter, about writing reliable and safe crash reporting: Reliable Crash Reporting
Warning: If you start the app with the Xcode debugger attached, detecting crashes will NOT be enabled!
Tasks
Delegate
-
delegateproperty
Configuration
-
crashManagerStatusproperty -
enableMachExceptionHandlerproperty -
enableOnDeviceSymbolicationproperty -
– setCrashCallbacks: -
showAlwaysButtonproperty
Crash Meta Information
-
didCrashInLastSessionproperty -
timeintervalCrashInLastSessionOccuredproperty
Helper
Properties
crashManagerStatus
Set the default status of the Crash Manager
@property (nonatomic, assign) BITCrashManagerStatus crashManagerStatusDiscussion
Defines if the crash reporting feature should be disabled, ask the user before sending each crash report or send crash reportings automatically without asking.
The default value is BITCrashManagerStatusAlwaysAsk. The user can switch to
BITCrashManagerStatusAutoSend by choosing “Always” in the dialog (since
showAlwaysButton default is YES).
The current value is always stored in User Defaults with the key
BITCrashManagerStatus.
If you intend to implement a user setting to let them enable or disable
crash reporting, this delegate should be used to return that value. You also
have to make sure the new value is stored in the UserDefaults with the key
BITCrashManagerStatus.
Declared In
BITCrashManager.hdelegate
Sets the optional BITCrashManagerDelegate delegate.
@property (nonatomic, weak) id delegateDeclared In
BITCrashManager.hdidCrashInLastSession
Indicates if the app crash in the previous session
@property (nonatomic, readonly) BOOL didCrashInLastSessionDiscussion
Use this on startup, to check if the app starts the first time after it crashed previously. You can use this also to disable specific events, like asking the user to rate your app.
Warning: This property only has a correct value, once [BITHockeyManager startManager] was
invoked!
Declared In
BITCrashManager.henableMachExceptionHandler
Trap fatal signals via a Mach exception server.
@property (nonatomic, assign, getter=isMachExceptionHandlerEnabled) BOOL enableMachExceptionHandlerDiscussion
By default the SDK is using the safe and proven in-process BSD Signals for catching crashes. This option provides an option to enable catching fatal signals via a Mach exception server instead.
We strongly advice NOT to enable Mach exception handler in release versions of your apps!
Default: NO
Warning: The Mach exception handler executes in-process, and will interfere with debuggers when they attempt to suspend all active threads (which will include the Mach exception handler). Mach-based handling should NOT be used when a debugger is attached. The SDK will not enabled catching exceptions if the app is started with the debugger running. If you attach the debugger during runtime, this may cause issues the Mach exception handler is enabled!
See Also
Declared In
BITCrashManager.henableOnDeviceSymbolication
Enable on device symbolication for system symbols
@property (nonatomic, assign, getter=isOnDeviceSymbolicationEnabled) BOOL enableOnDeviceSymbolicationDiscussion
By default, the SDK does not symbolicate on the device, since this can take a few seconds at each crash. Also note that symbolication on the device might not be able to retrieve all symbols.
Enable if you want to analyze crashes on unreleased OS versions.
Default: NO
Declared In
BITCrashManager.hshowAlwaysButton
Flag that determines if an “Always” option should be shown
@property (nonatomic, assign, getter=shouldShowAlwaysButton) BOOL showAlwaysButtonDiscussion
If enabled the crash reporting alert will also present an “Always” option, so the user doesn’t have to approve every single crash over and over again.
If If crashManagerStatus is set to BITCrashManagerStatusAutoSend, this property
has no effect, since no alert will be presented.
Default: YES
See Also
Declared In
BITCrashManager.htimeintervalCrashInLastSessionOccured
Provides the time between startup and crash in seconds
@property (nonatomic, readonly) NSTimeInterval timeintervalCrashInLastSessionOccuredDiscussion
Use this in together with didCrashInLastSession to detect if the app crashed very
early after startup. This can be used to delay app initialization until the crash
report has been sent to the server or if you want to do any other actions like
cleaning up some cache data etc.
Note that sending a crash reports starts as early as 1.5 seconds after the application did finish launching!
The BITCrashManagerDelegate protocol provides some delegates to inform if sending
a crash report was finished successfully, ended in error or was cancelled by the user.
Default: -1
Declared In
BITCrashManager.hInstance Methods
generateTestCrash
Lets the app crash for easy testing of the SDK
- (void)generateTestCrashDiscussion
The best way to use this is to trigger the crash with a button action.
Make sure not to let the app crash in applicationDidFinishLaunching or any other
startup method! Since otherwise the app would crash before the SDK could process it.
Note that our SDK provides support for handling crashes that happen early on startup. Check the documentation for more information on how to use this.
If the SDK detects an App Store environment, it will NOT cause the app to crash!
Declared In
BITCrashManager.hisDebuggerAttached
Detect if a debugger is attached to the app process
- (BOOL)isDebuggerAttachedReturn Value
BOOL if the debugger is attached on app startup
Discussion
This is only invoked once on app startup and can not detect if the debugger is being attached during runtime!
Declared In
BITCrashManager.hsetCrashCallbacks:
Set the callbacks that will be executed prior to program termination after a crash has occurred
- (void)setCrashCallbacks:(PLCrashReporterCallbacks *)callbacksParameters
- callbacks
A pointer to an initialized PLCrashReporterCallback structure, see https://www.plcrashreporter.org/documentation/api/v1.2-rc2/struct_p_l_crash_reporter_callbacks.html
Discussion
PLCrashReporter provides support for executing an application specified function in the context of the crash reporter’s signal handler, after the crash report has been written to disk.
Writing code intended for execution inside of a signal handler is exceptionally difficult, and is NOT recommended!
Program Flow and Signal Handlers
When the signal handler is called the normal flow of the program is interrupted, and your program is an unknown state. Locks may be held, the heap may be corrupt (or in the process of being updated), and your signal handler may invoke a function that was being executed at the time of the signal. This may result in deadlocks, data corruption, and program termination.
Async-Safe Functions
A subset of functions are defined to be async-safe by the OS, and are safely callable from within a signal handler. If you do implement a custom post-crash handler, it must be async-safe. A table of POSIX-defined async-safe functions and additional information is available from the CERT programming guide - SIG30-C, see https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
Most notably, the Objective-C runtime itself is not async-safe, and Objective-C may not be used within a signal handler.
Documentation taken from PLCrashReporter: https://www.plcrashreporter.org/documentation/api/v1.2-rc2/async_safety.html
Declared In
BITCrashManager.h