mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-07 05:25:12 +00:00
Update to custom PLCrashReporter v1.2 Beta 1 build with BIT namespace
- Adjust to new PLCR initialization scheme - Don't enable PLCR if the app is starting with a debugger attached - Add option to enable Mach exception handler. It is strongly discouraged to use this in release builds!
This commit is contained in:
@@ -84,6 +84,8 @@ typedef NS_ENUM(NSUInteger, BITCrashManagerStatus) {
|
||||
More background information on this topic can be found in the following blog post by Landon Fuller, the
|
||||
developer of [PLCrashReporter](https://www.plcrashreporter.org), about writing reliable and
|
||||
safe crash reporting: [Reliable Crash Reporting](http://goo.gl/WvTBR)
|
||||
|
||||
@warning If you start the app with the Xcode debugger attached, detecting crashes will _NOT_ be enabled!
|
||||
*/
|
||||
|
||||
@interface BITCrashManager : BITHockeyBaseManager
|
||||
@@ -127,6 +129,27 @@ typedef NS_ENUM(NSUInteger, BITCrashManagerStatus) {
|
||||
@property (nonatomic, assign) BITCrashManagerStatus crashManagerStatus;
|
||||
|
||||
|
||||
/**
|
||||
* Trap fatal signals via a Mach exception server.
|
||||
*
|
||||
* 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 isDebuggerAttached
|
||||
*/
|
||||
@property (nonatomic, assign, getter=isMachExceptionHandlerEnabled) BOOL enableMachExceptionHandler;
|
||||
|
||||
|
||||
/**
|
||||
Flag that determines if an "Always" option should be shown
|
||||
|
||||
@@ -179,4 +202,19 @@ typedef NS_ENUM(NSUInteger, BITCrashManagerStatus) {
|
||||
*/
|
||||
@property (nonatomic, readonly) NSTimeInterval timeintervalCrashInLastSessionOccured;
|
||||
|
||||
|
||||
///-----------------------------------------------------------------------------
|
||||
/// @name Helper
|
||||
///-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Detect if a debugger is attached to the app process
|
||||
*
|
||||
* This is only invoked once on app startup and can not detect if the debugger is being
|
||||
* attached during runtime!
|
||||
*
|
||||
* @return BOOL if the debugger is attached on app startup
|
||||
*/
|
||||
- (BOOL)isDebuggerAttached;
|
||||
|
||||
@end
|
||||
|
||||
@@ -78,6 +78,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
|
||||
BOOL _sendingInProgress;
|
||||
BOOL _isSetup;
|
||||
|
||||
BITPLCrashReporter *_plCrashReporter;
|
||||
NSUncaughtExceptionHandler *_exceptionHandler;
|
||||
}
|
||||
|
||||
@@ -88,6 +89,7 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
|
||||
_showAlwaysButton = NO;
|
||||
_isSetup = NO;
|
||||
|
||||
_plCrashReporter = nil;
|
||||
_exceptionHandler = nil;
|
||||
|
||||
_crashIdenticalCurrentVersion = YES;
|
||||
@@ -162,34 +164,6 @@ NSString *const kBITCrashManagerStatus = @"BITCrashManagerStatus";
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
/**
|
||||
* Check if the debugger is attached
|
||||
*
|
||||
* Taken from https://github.com/plausiblelabs/plcrashreporter/blob/2dd862ce049e6f43feb355308dfc710f3af54c4d/Source/Crash%20Demo/main.m#L96
|
||||
*
|
||||
* @return `YES` if the debugger is attached to the current process, `NO` otherwise
|
||||
*/
|
||||
static bool isDebuggerAttached (void) {
|
||||
struct kinfo_proc info;
|
||||
size_t info_size = sizeof(info);
|
||||
int name[4];
|
||||
|
||||
name[0] = CTL_KERN;
|
||||
name[1] = KERN_PROC;
|
||||
name[2] = KERN_PROC_PID;
|
||||
name[3] = getpid();
|
||||
|
||||
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
|
||||
NSLog(@"sysctl() failed: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((info.kp_proc.p_flag & P_TRACED) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all settings
|
||||
*
|
||||
@@ -345,6 +319,43 @@ static bool isDebuggerAttached (void) {
|
||||
return useremail;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
/**
|
||||
* Check if the debugger is attached
|
||||
*
|
||||
* Taken from https://github.com/plausiblelabs/plcrashreporter/blob/2dd862ce049e6f43feb355308dfc710f3af54c4d/Source/Crash%20Demo/main.m#L96
|
||||
*
|
||||
* @return `YES` if the debugger is attached to the current process, `NO` otherwise
|
||||
*/
|
||||
- (BOOL)isDebuggerAttached {
|
||||
static BOOL debuggerIsAttached = NO;
|
||||
|
||||
static dispatch_once_t debuggerPredicate;
|
||||
dispatch_once(&debuggerPredicate, ^{
|
||||
struct kinfo_proc info;
|
||||
size_t info_size = sizeof(info);
|
||||
int name[4];
|
||||
|
||||
name[0] = CTL_KERN;
|
||||
name[1] = KERN_PROC;
|
||||
name[2] = KERN_PROC_PID;
|
||||
name[3] = getpid();
|
||||
|
||||
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
|
||||
NSLog(@"[HockeySDK] ERROR: Checking for a running debugger via sysctl() failed: %s", strerror(errno));
|
||||
debuggerIsAttached = false;
|
||||
}
|
||||
|
||||
if (!debuggerIsAttached && (info.kp_proc.p_flag & P_TRACED) != 0)
|
||||
debuggerIsAttached = true;
|
||||
});
|
||||
|
||||
return debuggerIsAttached;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - PLCrashReporter
|
||||
|
||||
/**
|
||||
@@ -353,9 +364,10 @@ static bool isDebuggerAttached (void) {
|
||||
* Parse the new crash report and gather additional meta data from the app which will be stored along the crash report
|
||||
*/
|
||||
- (void) handleCrashReport {
|
||||
BITPLCrashReporter *crashReporter = [BITPLCrashReporter sharedReporter];
|
||||
NSError *error = NULL;
|
||||
|
||||
if (!_plCrashReporter) return;
|
||||
|
||||
[self loadSettings];
|
||||
|
||||
// check if the next call ran successfully the last time
|
||||
@@ -366,7 +378,7 @@ static bool isDebuggerAttached (void) {
|
||||
[self saveSettings];
|
||||
|
||||
// Try loading the crash report
|
||||
NSData *crashData = [[NSData alloc] initWithData:[crashReporter loadPendingCrashReportDataAndReturnError: &error]];
|
||||
NSData *crashData = [[NSData alloc] initWithData:[_plCrashReporter loadPendingCrashReportDataAndReturnError: &error]];
|
||||
|
||||
NSString *cacheFilename = [NSString stringWithFormat: @"%.0f", [NSDate timeIntervalSinceReferenceDate]];
|
||||
|
||||
@@ -421,7 +433,7 @@ static bool isDebuggerAttached (void) {
|
||||
|
||||
[self saveSettings];
|
||||
|
||||
[crashReporter purgePendingCrashReport];
|
||||
[_plCrashReporter purgePendingCrashReport];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -555,68 +567,75 @@ static bool isDebuggerAttached (void) {
|
||||
if (_crashManagerStatus == BITCrashManagerStatusDisabled) return;
|
||||
|
||||
if (!_isSetup) {
|
||||
BITPLCrashReporter *crashReporter = [BITPLCrashReporter sharedReporter];
|
||||
|
||||
// Check if we previously crashed
|
||||
if ([crashReporter hasPendingCrashReport]) {
|
||||
_didCrashInLastSession = YES;
|
||||
[self handleCrashReport];
|
||||
}
|
||||
|
||||
// Don't enable PLCrashReporter exception and signal handlers if we are already running with the debugger
|
||||
// attached. This will not solve the debugger being attached during runtime and then catching all the
|
||||
// exceptions before PLCrashReporter has a chance to do so.
|
||||
// We only check for this if we are not in the App Store environment
|
||||
|
||||
BOOL debuggerIsAttached = NO;
|
||||
if (![self isAppStoreEnvironment]) {
|
||||
if (isDebuggerAttached()) {
|
||||
debuggerIsAttached = YES;
|
||||
NSLog(@"[HockeSDK] WARNING: This app is running with the debugger being attached. Catching crashes is de-activated!");
|
||||
static dispatch_once_t plcrPredicate;
|
||||
dispatch_once(&plcrPredicate, ^{
|
||||
/* Configure our reporter */
|
||||
|
||||
PLCrashReporterSignalHandlerType signalHandlerType = PLCrashReporterSignalHandlerTypeBSD;
|
||||
if (self.isMachExceptionHandlerEnabled) {
|
||||
signalHandlerType = PLCrashReporterSignalHandlerTypeMach;
|
||||
}
|
||||
}
|
||||
|
||||
if (!debuggerIsAttached) {
|
||||
// Multiple exception handlers can be set, but we can only query the top level error handler (uncaught exception handler).
|
||||
//
|
||||
// To check if PLCrashReporter's error handler is successfully added, we compare the top
|
||||
// level one that is set before and the one after PLCrashReporter sets up its own.
|
||||
//
|
||||
// With delayed processing we can then check if another error handler was set up afterwards
|
||||
// and can show a debug warning log message, that the dev has to make sure the "newer" error handler
|
||||
// doesn't exit the process itself, because then all subsequent handlers would never be invoked.
|
||||
//
|
||||
// Note: ANY error handler setup BEFORE HockeySDK initialization will not be processed!
|
||||
BITPLCrashReporterConfig *config = [[BITPLCrashReporterConfig alloc] initWithSignalHandlerType: signalHandlerType
|
||||
symbolicationStrategy: PLCrashReporterSymbolicationStrategyAll];
|
||||
_plCrashReporter = [[BITPLCrashReporter alloc] initWithConfiguration: config];
|
||||
|
||||
// get the current top level error handler
|
||||
NSUncaughtExceptionHandler *initialHandler = NSGetUncaughtExceptionHandler();
|
||||
// Check if we previously crashed
|
||||
if ([_plCrashReporter hasPendingCrashReport]) {
|
||||
_didCrashInLastSession = YES;
|
||||
[self handleCrashReport];
|
||||
}
|
||||
|
||||
// PLCrashReporter may only be initialized once. So make sure the developer
|
||||
// can't break this
|
||||
static dispatch_once_t plcrPredicate;
|
||||
dispatch_once(&plcrPredicate, ^{
|
||||
// The actual signal and mach handlers are only registered when invoking `enableCrashReporterAndReturnError`
|
||||
// So it is safe enough to only disable the following part when a debugger is attached no matter which
|
||||
// signal handler type is set
|
||||
// We only check for this if we are not in the App Store environment
|
||||
|
||||
BOOL debuggerIsAttached = NO;
|
||||
if (![self isAppStoreEnvironment]) {
|
||||
if ([self isDebuggerAttached]) {
|
||||
debuggerIsAttached = YES;
|
||||
NSLog(@"[HockeySDK] WARNING: Detecting crashes is NOT enabled due to running the app with a debugger attached.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!debuggerIsAttached) {
|
||||
// Multiple exception handlers can be set, but we can only query the top level error handler (uncaught exception handler).
|
||||
//
|
||||
// To check if PLCrashReporter's error handler is successfully added, we compare the top
|
||||
// level one that is set before and the one after PLCrashReporter sets up its own.
|
||||
//
|
||||
// With delayed processing we can then check if another error handler was set up afterwards
|
||||
// and can show a debug warning log message, that the dev has to make sure the "newer" error handler
|
||||
// doesn't exit the process itself, because then all subsequent handlers would never be invoked.
|
||||
//
|
||||
// Note: ANY error handler setup BEFORE HockeySDK initialization will not be processed!
|
||||
|
||||
// get the current top level error handler
|
||||
NSUncaughtExceptionHandler *initialHandler = NSGetUncaughtExceptionHandler();
|
||||
|
||||
// PLCrashReporter may only be initialized once. So make sure the developer
|
||||
// can't break this
|
||||
NSError *error = NULL;
|
||||
|
||||
// Enable the Crash Reporter
|
||||
if (![crashReporter enableCrashReporterAndReturnError: &error])
|
||||
if (![_plCrashReporter enableCrashReporterAndReturnError: &error])
|
||||
NSLog(@"[HockeySDK] WARNING: Could not enable crash reporter: %@", [error localizedDescription]);
|
||||
});
|
||||
|
||||
// get the new current top level error handler, which should now be the one from PLCrashReporter
|
||||
NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler();
|
||||
|
||||
// do we have a new top level error handler? then we were successful
|
||||
if (currentHandler && currentHandler != initialHandler) {
|
||||
_exceptionHandler = currentHandler;
|
||||
|
||||
BITHockeyLog(@"INFO: Exception handler successfully initialized.");
|
||||
} else {
|
||||
// this should never happen, theoretically only if NSSetUncaugtExceptionHandler() has some internal issues
|
||||
NSLog(@"[HockeySDK] ERROR: Exception handler could not be set. Make sure there is no other exception handler set up!");
|
||||
// get the new current top level error handler, which should now be the one from PLCrashReporter
|
||||
NSUncaughtExceptionHandler *currentHandler = NSGetUncaughtExceptionHandler();
|
||||
|
||||
// do we have a new top level error handler? then we were successful
|
||||
if (currentHandler && currentHandler != initialHandler) {
|
||||
_exceptionHandler = currentHandler;
|
||||
|
||||
BITHockeyLog(@"INFO: Exception handler successfully initialized.");
|
||||
} else {
|
||||
// this should never happen, theoretically only if NSSetUncaugtExceptionHandler() has some internal issues
|
||||
NSLog(@"[HockeySDK] ERROR: Exception handler could not be set. Make sure there is no other exception handler set up!");
|
||||
}
|
||||
}
|
||||
|
||||
_isSetup = YES;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[self performSelector:@selector(invokeDelayedProcessing) withObject:nil afterDelay:0.5];
|
||||
|
||||
Binary file not shown.
@@ -34,7 +34,7 @@
|
||||
|
||||
// This must be included before any other PLCrashReporter includes, as
|
||||
// it redefines symbol names
|
||||
#import "PLCrashReporterNamespace.h"
|
||||
#import "PLCrashNamespace.h"
|
||||
|
||||
#import "PLCrashReporter.h"
|
||||
#import "PLCrashReport.h"
|
||||
@@ -93,6 +93,9 @@ typedef enum {
|
||||
|
||||
/** The crash report log file is corrupt or invalid */
|
||||
PLCrashReporterErrorCrashReportInvalid = 2,
|
||||
|
||||
/** An attempt to use a resource which was in use at the time in a manner which would have conflicted with the request. */
|
||||
PLCrashReporterErrorResourceBusy = 3
|
||||
} PLCrashReporterError;
|
||||
|
||||
|
||||
@@ -233,7 +236,65 @@ typedef enum {
|
||||
*/
|
||||
|
||||
/**
|
||||
* @page mach_exceptions Mach Exceptions on iOS
|
||||
* @page mach_exceptions Mach Exceptions on Mac OS X and iOS
|
||||
*
|
||||
* PLCrashReporter includes support for monitoring crashes via an in-process Mach exception handler. On Mac OS X, the
|
||||
* Mach exception implementation is fully supported using entirely public API. On iOS, the APIs required are not fully
|
||||
* public -- more details on the implications of this for exception handling on iOS may be found in
|
||||
* @ref mach_exceptions_ios below.
|
||||
*
|
||||
* It is worth noting that even where the Mach exception APIs are fully supported, kernel-internal constants, as well
|
||||
* as architecture-specific trap information, may be required to fully interpret a Mach exception's root cause.
|
||||
*
|
||||
* For example, the EXC_SOFTWARE exception is dispatched for four different failure types, using the exception
|
||||
* code to differentiate failure types:
|
||||
* - Non-existent system call invoked (SIGSYS)
|
||||
* - Write on a pipe with no reader (SIGPIPE)
|
||||
* - Abort program (SIGABRT)
|
||||
* - Kill program (SIGKILL)
|
||||
*
|
||||
* Of those four types, only the constant required to interpret the SIGKILL behavior (EXC_SOFT_SIGNAL) is publicly defined.
|
||||
* Of the remaining three failure types, the constant values are kernel implementation-private, defined only in the available
|
||||
* kernel sources. On iOS, these sources are unavailable, and while they generally do match the Mac OS X implementation, there
|
||||
* are no gaurantees that this is -- or will remain -- the case in the future.
|
||||
*
|
||||
* Likewise, interpretation of particular fault types requires information regarding the underlying machine traps
|
||||
* that triggered the Mach exceptions. For example, a floating point trap on x86/x86-64 will trigger an EXC_ARITHMETIC,
|
||||
* with a subcode value containing the value of the FPU status register. Determining the exact FPU cause requires
|
||||
* extracting the actual exception flags from status register as per the x86 architecture documentation. The exact format
|
||||
* of this subcode value is not actually documented outside the kernel, and may change in future releases.
|
||||
*
|
||||
* While we have the advantage of access to the x86 kernel sources, the situation on ARM is even less clear. The actual
|
||||
* use of the Mach exception codes and subcodes is largely undefined by both headers and publicly available documentation,
|
||||
* and the available x86 kernel sources are of little use in interpreting this data.
|
||||
*
|
||||
* As such, while Mach exceptions may catch some cases that BSD signals can not, they are not a perfect solution,
|
||||
* and may also provide less insight into the actual failures that occur. By comparison, the BSD signal interface
|
||||
* is both fully defined and architecture independent, with any necessary interpretation of the Mach exception
|
||||
* codes handled in-kernel at the time of exception dispatch. It is generally recommended by Apple as the preferred
|
||||
* interface, and should generally be preferred by PLCrashReporter API clients.
|
||||
*
|
||||
* @section mach_exceptions_compatibility Compatibility Issues
|
||||
*
|
||||
* @subsection Debuggers
|
||||
*
|
||||
* Enabling in-process Mach exception handlers will conflict with any attached debuggers; the debugger
|
||||
* may suspend the processes Mach exception handling thread, which will result in any exception messages
|
||||
* sent via the debugger being lost, as the in-process handler will be unable to receive and forward
|
||||
* the messages.
|
||||
*
|
||||
* @subsection Managed Runtimes (Xamarin, Unity)
|
||||
*
|
||||
* A Mach exception handler may conflict with any managed runtime that registers a BSD signal handler that
|
||||
* can safely handle otherwise fatal signals, allowing execution to proceed. This includes products
|
||||
* such as Xamarin for iOS.
|
||||
*
|
||||
* In such a case, PLCrashReporter will write a crash report for non-fatal signals, as there is no
|
||||
* immediate mechanism for determining whether a signal handler exists and that it can safely
|
||||
* handle the failure. This can result in unexpected delays in application execution, increased I/O to
|
||||
* disk, and other undesirable operations.
|
||||
*
|
||||
* @section mach_exceptions_ios Mach Exceptions on iOS
|
||||
*
|
||||
* The APIs required for Mach exception handling are not fully public on iOS. Unfortunately, there are a number
|
||||
* of crash states that can only be handled with Mach exception handlers:
|
||||
|
||||
105
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashFeatureConfig.h
vendored
Normal file
105
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashFeatureConfig.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Author: Landon Fuller <landonf@plausible.coop>
|
||||
*
|
||||
* Copyright (c) 2012-2013 Plausible Labs Cooperative, Inc.
|
||||
* 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 be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PLCRASH_FEATURE_CONFIG_H
|
||||
#define PLCRASH_FEATURE_CONFIG_H
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Build-time configuration for PLCrashReporter.
|
||||
*
|
||||
* This is used to automatically enable/disable features on a per-platform and per-configuration
|
||||
* basis; it may also be used by third-party vendors to configure a custom build of PLCrashReporter.
|
||||
*
|
||||
* @defgroup build_config Build Configuration
|
||||
* @ingroup constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defaults
|
||||
*/
|
||||
|
||||
/*
|
||||
* For release builds, disable unused unwind implementations on targets that do not use them. For non-release
|
||||
* builds, we include the unwind implementations to allow testing on a broader range of targets; it's possible
|
||||
* that both compact and/or DWARF unwinding could be implemented by Apple for iOS/ARM in the future.
|
||||
*/
|
||||
#ifdef PLCF_RELEASE_BUILD
|
||||
# if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
|
||||
# ifndef PLCRASH_FEATURE_UNWIND_DWARF
|
||||
# define PLCRASH_FEATURE_UNWIND_DWARF 0
|
||||
# endif
|
||||
# ifndef PLCRASH_FEATURE_UNWIND_COMPACT
|
||||
# define PLCRASH_FEATURE_UNWIND_COMPACT 0
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Configuration Flags
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PLCRASH_FEATURE_MACH_EXCEPTIONS
|
||||
/**
|
||||
* If true, enable Mach exception support. On Mac OS X, the Mach exception implementation is fully supported,
|
||||
* using publicly available API. On iOS, the APIs required for a complete implementation are not public. However, a
|
||||
* popular commercial crash reporter is now shipping with support for Mach exceptions, which implies that either
|
||||
* they've received special dispensation to use private APIs / private structures, they've found another way to do
|
||||
* it, or they're just using undocumented functionality and hoping for the best.
|
||||
*
|
||||
* The exposed surface of undocumented API usage is relatively low, and there has been strong user demand to
|
||||
* implement Mach exception handling regardless of concerns over API visiblity. Given this, we've enabled
|
||||
* Mach exception handling by default, and provided both build-time and runtime configuration
|
||||
* to disable its use.
|
||||
*
|
||||
* For more information on the potential issues with enabling mach exception support, @sa @ref mach_exceptions.
|
||||
*/
|
||||
# define PLCRASH_FEATURE_MACH_EXCEPTIONS 1
|
||||
#endif
|
||||
|
||||
#ifndef PLCRASH_FEATURE_UNWIND_DWARF
|
||||
/** If true, enable DWARF unwinding support. DWARF unwinding is currently only used by Mac OS X. */
|
||||
# define PLCRASH_FEATURE_UNWIND_DWARF 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PLCRASH_FEATURE_UNWIND_COMPACT
|
||||
/** If true, enable compact unwinding support. This is only used by Mac OS X. */
|
||||
# define PLCRASH_FEATURE_UNWIND_COMPACT 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* PLCRASH_FEATURE_CONFIG_H */
|
||||
@@ -35,6 +35,7 @@
|
||||
* This may be used to avoid symbol conflicts between multiple libraries
|
||||
* that may both incorporate PLCrashReporter.
|
||||
*/
|
||||
// #define PLCRASHREPORTER_PREFIX AcmeCo
|
||||
#define PLCRASHREPORTER_PREFIX BIT
|
||||
|
||||
#ifdef PLCRASHREPORTER_PREFIX
|
||||
@@ -66,5 +67,14 @@
|
||||
#define PLCrashReportHostOperatingSystem PLNS(PLCrashReportHostOperatingSystem)
|
||||
#define PLCrashReporterErrorDomain PLNS(PLCrashReporterErrorDomain)
|
||||
#define PLCrashReporterException PLNS(PLCrashReporterException)
|
||||
#define PLCrashHostInfo PLNS(PLCrashHostInfo)
|
||||
#define PLCrashMachExceptionPort PLNS(PLCrashMachExceptionPort)
|
||||
#define PLCrashMachExceptionPortSet PLNS(PLCrashMachExceptionPortSet)
|
||||
#define PLCrashProcessInfo PLNS(PLCrashProcessInfo)
|
||||
#define PLCrashReporterConfig PLNS(PLCrashReporterConfig)
|
||||
#define PLCrashUncaughtExceptionHandler PLNS(PLCrashUncaughtExceptionHandler)
|
||||
#define PLCrashMachExceptionForward PLNS(PLCrashMachExceptionForward)
|
||||
#define PLCrashSignalHandlerForward PLNS(PLCrashSignalHandlerForward)
|
||||
#define plcrash_signal_handler PLNS(plcrash_signal_handler)
|
||||
|
||||
#endif
|
||||
@@ -32,6 +32,7 @@
|
||||
#import "PLCrashReportBinaryImageInfo.h"
|
||||
#import "PLCrashReportExceptionInfo.h"
|
||||
#import "PLCrashReportMachineInfo.h"
|
||||
#import "PLCrashReportMachExceptionInfo.h"
|
||||
#import "PLCrashReportProcessInfo.h"
|
||||
#import "PLCrashReportProcessorInfo.h"
|
||||
#import "PLCrashReportRegisterInfo.h"
|
||||
@@ -98,6 +99,9 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
|
||||
|
||||
/** Signal info */
|
||||
PLCrashReportSignalInfo *_signalInfo;
|
||||
|
||||
/** Mach exception info */
|
||||
PLCrashReportMachExceptionInfo *_machExceptionInfo;
|
||||
|
||||
/** Thread info (PLCrashReportThreadInfo instances) */
|
||||
NSArray *_threads;
|
||||
@@ -153,6 +157,18 @@ typedef struct _PLCrashReportDecoder _PLCrashReportDecoder;
|
||||
*/
|
||||
@property(nonatomic, readonly) PLCrashReportSignalInfo *signalInfo;
|
||||
|
||||
/**
|
||||
* Mach exception information, if available. This will only be included in the
|
||||
* case that encoding crash reporter's exception-based reporting was enabled, and a Mach
|
||||
* exception was caught.
|
||||
*
|
||||
* @warning If Mach exception information is available, the legacy signalInfo property will also be provided; this
|
||||
* s required to maintain backwards compatibility with the established API. Note, however, that the signal info may be derived from the
|
||||
* Mach exception info by the encoding crash reporter, and thus may not exactly match the kernel exception-to-signal
|
||||
* mappings implemented in xnu. As such, when Mach exception info is available, its use should be preferred.
|
||||
*/
|
||||
@property(nonatomic, readonly) PLCrashReportMachExceptionInfo *machExceptionInfo;
|
||||
|
||||
/**
|
||||
* Thread information. Returns a list of PLCrashReportThreadInfo instances.
|
||||
*/
|
||||
|
||||
48
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportMachExceptionInfo.h
vendored
Normal file
48
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReportMachExceptionInfo.h
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Author: Landon Fuller <landonf@plausiblelabs.com>
|
||||
*
|
||||
* Copyright (c) 2013 Plausible Labs Cooperative, Inc.
|
||||
* 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 be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 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>
|
||||
|
||||
@interface PLCrashReportMachExceptionInfo : NSObject {
|
||||
@private
|
||||
/** The Mach exception type. */
|
||||
uint64_t _type;
|
||||
|
||||
/** The Mach exception codes, represented as an ordered array of NSNumber instances. */
|
||||
NSArray *_codes;
|
||||
}
|
||||
|
||||
- (id) initWithType: (uint64_t) type codes: (NSArray *) codes;
|
||||
|
||||
/** The Mach exception type. */
|
||||
@property(nonatomic, readonly) uint64_t type;
|
||||
|
||||
/** The Mach exception codes, represented as an ordered array of 64-bit unsigned NSNumber instances. */
|
||||
@property(nonatomic, readonly) NSArray *codes;
|
||||
|
||||
@end
|
||||
@@ -29,6 +29,11 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <mach/mach.h>
|
||||
|
||||
#import "PLCrashReporterConfig.h"
|
||||
|
||||
@class PLCrashMachExceptionServer;
|
||||
@class PLCrashMachExceptionPortSet;
|
||||
|
||||
/**
|
||||
* @ingroup functions
|
||||
*
|
||||
@@ -60,15 +65,37 @@ typedef struct PLCrashReporterCallbacks {
|
||||
/** An arbitrary user-supplied context value. This value may be NULL. */
|
||||
void *context;
|
||||
|
||||
/** The callback used to report caught signal information. In version 0 of this structure, all crashes will be
|
||||
* reported via this function. */
|
||||
/**
|
||||
* The callback used to report caught signal information. In version 0 of this structure, all crashes will be
|
||||
* reported via this function.
|
||||
*
|
||||
* @warning When using PLCrashReporterSignalHandlerTypeMach, the siginfo_t argument to this function will be derived
|
||||
* from the Mach exception data, and may be incorrect, or may otherwise not match the expected data as provided via
|
||||
* PLCrashReporterSignalHandlerTypeBSD. In addition, the provided ucontext_t value will be zero-initialized, and will
|
||||
* not provide valid thread state.
|
||||
*
|
||||
* This callback will be deprecated in favor of a Mach-compatible replacement in a future release; support is maintained
|
||||
* here to allow clients that rely on post-crash callbacks without thread state to make use of Mach exceptions.
|
||||
*/
|
||||
PLCrashReporterPostCrashSignalCallback handleSignal;
|
||||
} PLCrashReporterCallbacks;
|
||||
|
||||
@interface PLCrashReporter : NSObject {
|
||||
@private
|
||||
/** Reporter configuration */
|
||||
PLCrashReporterConfig *_config;
|
||||
|
||||
/** YES if the crash reporter has been enabled */
|
||||
BOOL _enabled;
|
||||
|
||||
#if PLCRASH_FEATURE_MACH_EXCEPTIONS
|
||||
/** The backing Mach exception server, if any. Nil if the reporter has not been enabled, or if
|
||||
* the configured signal handler type is not PLCrashReporterSignalHandlerTypeMach. */
|
||||
PLCrashMachExceptionServer *_machServer;
|
||||
|
||||
/** Previously registered Mach exception ports, if any. */
|
||||
PLCrashMachExceptionPortSet *_previousMachPorts;
|
||||
#endif /* PLCRASH_FEATURE_MACH_EXCEPTIONS */
|
||||
|
||||
/** Application identifier */
|
||||
NSString *_applicationIdentifier;
|
||||
@@ -82,6 +109,8 @@ typedef struct PLCrashReporterCallbacks {
|
||||
|
||||
+ (PLCrashReporter *) sharedReporter;
|
||||
|
||||
- (instancetype) initWithConfiguration: (PLCrashReporterConfig *) config;
|
||||
|
||||
- (BOOL) hasPendingCrashReport;
|
||||
|
||||
- (NSData *) loadPendingCrashReportData;
|
||||
|
||||
165
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReporterConfig.h
vendored
Normal file
165
Vendor/CrashReporter.framework/Versions/A/Headers/PLCrashReporterConfig.h
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Author: Landon Fuller <landonf@plausible.coop>
|
||||
*
|
||||
* Copyright (c) 2013 Plausible Labs Cooperative, Inc.
|
||||
* 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 be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 "PLCrashFeatureConfig.h"
|
||||
|
||||
/**
|
||||
* @ingroup enums
|
||||
* Supported mechanisms for trapping and handling crashes.
|
||||
*/
|
||||
typedef NS_ENUM(NSUInteger, PLCrashReporterSignalHandlerType) {
|
||||
/**
|
||||
* Trap fatal signals via a sigaction(2)-registered BSD signal handler.
|
||||
*
|
||||
* PLCrashReporter's signal handler will supersede previously registered handlers; existing
|
||||
* handlers will not be called. This behavior may be modified in a future release, and should
|
||||
* not be relied upon as a mechanism to prevent existing signal handlers from being called.
|
||||
*
|
||||
* There are some limitations to signal-based crash handling on Mac OS X and iOS; specifically:
|
||||
*
|
||||
* - On Mac OS X, stack overflows will only be handled on the thread on which
|
||||
* the crash reporter was initialized. This should generally be the main thread.
|
||||
* - On iOS 6.0 and later, any stack overflows will not be handled due to sigaltstack() being
|
||||
* non-functional on the device. (see rdar://13002712 - SA_ONSTACK/sigaltstack() ignored on iOS).
|
||||
* - Some exit paths in Apple's Libc will deregister a signal handler before firing SIGABRT, resulting
|
||||
* in the signal handler never being called (see rdar://14313497 - ___abort() disables SIGABRT signal
|
||||
* handlers prior to raising SIGABRT). These __abort()-based checks are:
|
||||
* - Implemented for unsafe memcpy/strcpy/snprintf C functions.
|
||||
* - Only enabled when operating on a fixed-width target buffer (in which case the
|
||||
* compiler rewrites the function calls to the built-in variants, and provides the fixed-width length as an argument).
|
||||
* - Only trigger in the case that the source data exceeds the size of the fixed width target
|
||||
* buffer, and the maximum length argument either isn't supplied by the caller (eg, when using strcpy),
|
||||
* or a too-long argument is supplied (eg, strncpy with a length argument longer than the target buffer),
|
||||
* AND that argument can't be checked at compile-time.
|
||||
*/
|
||||
PLCrashReporterSignalHandlerTypeBSD = 0,
|
||||
|
||||
#if PLCRASH_FEATURE_MACH_EXCEPTIONS
|
||||
/**
|
||||
* Trap fatal signals via a Mach exception server.
|
||||
*
|
||||
* If any existing Mach exception server has been registered for the task, exceptions will be forwarded to that
|
||||
* exception handler. Should the exceptions be handled by an existing handler, no report will be generated
|
||||
* by PLCrashReporter.
|
||||
*
|
||||
* @par Mac OS X
|
||||
*
|
||||
* On Mac OS X, the Mach exception implementation is fully supported, using publicly available API -- note,
|
||||
* however, that some kernel-internal constants, as well as architecture-specific trap information,
|
||||
* may be required to fully interpret a Mach exception's root cause.
|
||||
*
|
||||
* @par iOS
|
||||
*
|
||||
* On iOS, the APIs required for a complete implementation are not fully public.
|
||||
*
|
||||
* The exposed surface of undocumented API usage is relatively low, and there has been strong user demand to
|
||||
* implement Mach exception handling regardless of concerns over API visiblity. Given this, we've included
|
||||
* Mach exception handling as an optional feature, with both build-time and runtime configuration
|
||||
* to disable its inclusion or use, respectively.
|
||||
*
|
||||
* @par Debugger Incompatibility
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @par More Details
|
||||
*
|
||||
* For more information, refer to @ref mach_exceptions.
|
||||
*/
|
||||
PLCrashReporterSignalHandlerTypeMach = 1
|
||||
#endif /* PLCRASH_FEATURE_MACH_EXCEPTIONS */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup enums
|
||||
* Supported mechanisms for performing local symbolication.
|
||||
*
|
||||
* Local symbolication is performed using inexact heuristics and symbol data available at runtime; it may
|
||||
* return information that is incorrect. This may still be useful in the case where DWARF data is unavailable
|
||||
* for a given build; in that case, it can provide function and method names (though not line numbers) for a
|
||||
* crash report that may otherwise be unusable.
|
||||
*
|
||||
* Note, however, this comes at the cost of a significant increase in code that must run within the critical
|
||||
* crash reporting section, where failures may result in crash reports being corrupted or left unwritten. In
|
||||
* addition, some of the provided symbolication strategies rely on knowledge of runtime internals that may
|
||||
* change in future iOS releases. Given that DWARF symbolication data will <em>always</em> be more accurate, and
|
||||
* the risks inherent in executing considerably more code at crash time, it is strongly recommended that local
|
||||
* symbolication only be enabled for non-release builds.
|
||||
*
|
||||
* Multiple symbolication strategies may be enabled, in which case a best-match heuristic will be applied to the
|
||||
* results.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSUInteger, PLCrashReporterSymbolicationStrategy) {
|
||||
/** No symbolication. */
|
||||
PLCrashReporterSymbolicationStrategyNone = 0,
|
||||
|
||||
/**
|
||||
* Use the standard binary symbol table. On iOS, this alone will return
|
||||
* incomplete results, as most symbols are rewritten to the common '\<redacted>' string.
|
||||
*/
|
||||
PLCrashReporterSymbolicationStrategySymbolTable = 1 << 0,
|
||||
|
||||
/**
|
||||
* Use Objective-C metadata to find method and class names. This relies on detailed parsing
|
||||
* of the Objective-C runtime data, including undefined flags and other runtime internals. As such,
|
||||
* it may return incorrect data should the runtime be changed incompatibly.
|
||||
*/
|
||||
PLCrashReporterSymbolicationStrategyObjC = 1 << 1,
|
||||
|
||||
/**
|
||||
* Enable all available symbolication strategies.
|
||||
*/
|
||||
PLCrashReporterSymbolicationStrategyAll = (PLCrashReporterSymbolicationStrategySymbolTable|PLCrashReporterSymbolicationStrategyObjC)
|
||||
};
|
||||
|
||||
@interface PLCrashReporterConfig : NSObject {
|
||||
@private
|
||||
/** The configured signal handler type. */
|
||||
PLCrashReporterSignalHandlerType _signalHandlerType;
|
||||
|
||||
/** The configured symbolication strategy. */
|
||||
PLCrashReporterSymbolicationStrategy _symbolicationStrategy;
|
||||
}
|
||||
|
||||
+ (instancetype) defaultConfiguration;
|
||||
|
||||
- (instancetype) init;
|
||||
- (instancetype) initWithSignalHandlerType: (PLCrashReporterSignalHandlerType) signalHandlerType
|
||||
symbolicationStrategy: (PLCrashReporterSymbolicationStrategy) symbolicationStrategy;
|
||||
|
||||
/** The configured signal handler type. */
|
||||
@property(nonatomic, readonly) PLCrashReporterSignalHandlerType signalHandlerType;
|
||||
|
||||
/** The configured symbolication strategy. */
|
||||
@property(nonatomic, readonly) PLCrashReporterSymbolicationStrategy symbolicationStrategy;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user