From 970f0304d44acb5622badfdd5d2012fe1ff1c08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Spie=C3=9F?= Date: Mon, 7 Mar 2016 00:11:39 +0100 Subject: [PATCH] Add signal handler callback --- Classes/BITCrashManager.m | 72 +++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/Classes/BITCrashManager.m b/Classes/BITCrashManager.m index 774ed0388d..5dfc957187 100644 --- a/Classes/BITCrashManager.m +++ b/Classes/BITCrashManager.m @@ -28,7 +28,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#import "HockeySDK.h" +#import "HockeySDKFeatureConfig.h" #if HOCKEYSDK_FEATURE_CRASH_REPORTER @@ -39,13 +39,20 @@ #import "BITHockeyHelper.h" #import "BITHockeyAppClient.h" +#import "BITCrashManager.h" +#import "BITCrashManagerPrivate.h" #import "BITCrashAttachment.h" #import "BITHockeyBaseManagerPrivate.h" -#import "BITCrashManagerPrivate.h" #import "BITCrashReportTextFormatter.h" #import "BITCrashDetailsPrivate.h" #import "BITCrashCXXExceptionHandler.h" +#if HOCKEYSDK_FEATURE_METRICS +#import "BITMetricsManagerPrivate.h" +#import "BITChannel.h" +#import "BITPersistencePrivate.h" +#endif + #include // stores the set of crashreports that have been approved but aren't sent yet @@ -81,16 +88,40 @@ NSString *const kBITFakeCrashDeviceModel = @"BITFakeCrashDeviceModel"; NSString *const kBITFakeCrashAppBinaryUUID = @"BITFakeCrashAppBinaryUUID"; NSString *const kBITFakeCrashReport = @"BITFakeCrashAppString"; +#if HOCKEYSDK_FEATURE_METRICS +static char const *BITSaveEventsFilePath; +#endif static BITCrashManagerCallbacks bitCrashCallbacks = { .context = NULL, .handleSignal = NULL }; -// proxy implementation for PLCrashReporter to keep our interface stable while this can change +#if HOCKEYSDK_FEATURE_METRICS +static void bit_save_events_callback(siginfo_t *info, ucontext_t *uap, void *context) { + // Try to get a file descriptor with our pre-filled path + int fd = open(BITSaveEventsFilePath, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { + return; + } + + size_t len = strlen(BITSafeJsonEventsString); + if (len > 0) { + // Simply write the whole string to disk + write(fd, BITSafeJsonEventsString, len); + } + close(fd); +} +#endif + +// Proxy implementation for PLCrashReporter to keep our interface stable while this can change static void plcr_post_crash_callback (siginfo_t *info, ucontext_t *uap, void *context) { - if (bitCrashCallbacks.handleSignal != NULL) +#if HOCKEYSDK_FEATURE_METRICS + bit_save_events_callback(info, uap, context); +#endif + if (bitCrashCallbacks.handleSignal != NULL) { bitCrashCallbacks.handleSignal(context); + } } static PLCrashReporterCallbacks plCrashCallbacks = { @@ -99,7 +130,6 @@ static PLCrashReporterCallbacks plCrashCallbacks = { .handleSignal = plcr_post_crash_callback }; - // Temporary class until PLCR catches up // We trick PLCR with an Objective-C exception. // @@ -154,8 +184,6 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf NSString *_settingsFile; NSString *_analyzerInProgressFile; NSFileManager *_fileManager; - - PLCrashReporterCallbacks *_crashCallBacks; BOOL _crashIdenticalCurrentVersion; @@ -183,7 +211,6 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf _plCrashReporter = nil; _exceptionHandler = nil; - _crashCallBacks = nil; _crashIdenticalCurrentVersion = YES; @@ -657,17 +684,18 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf return useremail; } - -#pragma mark - Public - +#pragma mark - CrashCallbacks /** * Set the callback for PLCrashReporter * * @param callbacks BITCrashManagerCallbacks instance */ -- (void)setCrashCallbacks: (BITCrashManagerCallbacks *) callbacks { +- (void)setCrashCallbacks:(BITCrashManagerCallbacks *)callbacks { if (!callbacks) return; + if (_isSetup) { + BITHockeyLog(@"CrashCallbacks need to be configured before calling startManager!"); + } // set our proxy callback struct bitCrashCallbacks.context = callbacks->context; @@ -675,10 +703,17 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf // set the PLCrashReporterCallbacks struct plCrashCallbacks.context = callbacks->context; - - _crashCallBacks = &plCrashCallbacks; } +#if HOCKEYSDK_FEATURE_METRICS +- (void)configDefaultCrashCallback { + BITMetricsManager *metricsManager = [BITHockeyManager sharedHockeyManager].metricsManager; + BITPersistence *persistence = metricsManager.persistence; + BITSaveEventsFilePath = strdup([persistence fileURLForType:BITPersistenceTypeTelemetry].UTF8String); +} +#endif + +#pragma mark - Public - (void)setAlertViewHandler:(BITCustomAlertViewHandler)alertViewHandler{ _alertViewHandler = alertViewHandler; @@ -1174,10 +1209,11 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf // can't break this NSError *error = NULL; - // set any user defined callbacks, hopefully the users knows what they do - if (_crashCallBacks) { - [self.plCrashReporter setCrashCallbacks:_crashCallBacks]; - } +#if HOCKEYSDK_FEATURE_METRICS + [self configDefaultCrashCallback]; +#endif + // Set plCrashReporter callback which contains our default callback and potentially user defined callbacks + [self.plCrashReporter setCrashCallbacks:&plCrashCallbacks]; // Enable the Crash Reporter if (![self.plCrashReporter enableCrashReporterAndReturnError: &error])