Skip to content

Commit

Permalink
Merge pull request #178 from bugsnag/update-crash-reporter
Browse files Browse the repository at this point in the history
Update crash reporter
  • Loading branch information
fractalwrench authored Oct 2, 2017
2 parents 0184c8e + 0f82ec5 commit 41f9ebd
Show file tree
Hide file tree
Showing 29 changed files with 853 additions and 320 deletions.
4 changes: 2 additions & 2 deletions Bugsnag.podspec.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Bugsnag",
"version": "5.11.2",
"version": "5.12.0",
"summary": "Cocoa notifier for SDK for bugsnag.com",
"homepage": "https://bugsnag.com",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
},
"source": {
"git": "https://github.com/bugsnag/bugsnag-cocoa.git",
"tag": "v5.11.2"
"tag": "v5.12.0"
},
"frameworks": ["Foundation", "SystemConfiguration"],
"libraries": [
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog
=========

## 5.12.0 (02 Oct 2017)

* Fix fatalError not producing crash report
* Update library's calculation of stack frame depth
* Reduced build warning count

## 5.11.2 (15 Sep 2017)

* Fixed wrong tag in Cocoapods spec
Expand Down
12 changes: 12 additions & 0 deletions OSX/Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
E72352C21F55924A00436528 /* BSGConnectivity.m in Sources */ = {isa = PBXBuildFile; fileRef = E72352C01F55924A00436528 /* BSGConnectivity.m */; };
E7433AD21F4F64EF00C082D1 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A2C8FF11C6BC3A800846019 /* libz.tbd */; };
E7433AD31F4F64F400C082D1 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A2C8FF31C6BC3AE00846019 /* libc++.tbd */; };
E762E9F91F73F7F300E82B43 /* BugsnagHandledStateTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E762E9F71F73F7E900E82B43 /* BugsnagHandledStateTest.m */; };
E762E9FC1F73F80200E82B43 /* BugsnagHandledState.h in Headers */ = {isa = PBXBuildFile; fileRef = E762E9FA1F73F80200E82B43 /* BugsnagHandledState.h */; };
E762E9FD1F73F80200E82B43 /* BugsnagHandledState.m in Sources */ = {isa = PBXBuildFile; fileRef = E762E9FB1F73F80200E82B43 /* BugsnagHandledState.m */; };
E79E6B021F4E3847002B35F9 /* BugsnagCrashSentry.h in Headers */ = {isa = PBXBuildFile; fileRef = E79E6AFC1F4E3847002B35F9 /* BugsnagCrashSentry.h */; };
E79E6B031F4E3847002B35F9 /* BugsnagCrashSentry.m in Sources */ = {isa = PBXBuildFile; fileRef = E79E6AFD1F4E3847002B35F9 /* BugsnagCrashSentry.m */; };
E79E6B041F4E3847002B35F9 /* BugsnagErrorReportApiClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E79E6AFE1F4E3847002B35F9 /* BugsnagErrorReportApiClient.h */; };
Expand Down Expand Up @@ -180,6 +183,9 @@
8AD9FA851E0862DC002859A7 /* BugsnagConfigurationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BugsnagConfigurationTests.m; path = ../Tests/BugsnagConfigurationTests.m; sourceTree = SOURCE_ROOT; };
E72352BF1F55924A00436528 /* BSGConnectivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BSGConnectivity.h; path = ../Source/BSGConnectivity.h; sourceTree = SOURCE_ROOT; };
E72352C01F55924A00436528 /* BSGConnectivity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BSGConnectivity.m; path = ../Source/BSGConnectivity.m; sourceTree = SOURCE_ROOT; };
E762E9F71F73F7E900E82B43 /* BugsnagHandledStateTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BugsnagHandledStateTest.m; path = ../Tests/BugsnagHandledStateTest.m; sourceTree = SOURCE_ROOT; };
E762E9FA1F73F80200E82B43 /* BugsnagHandledState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugsnagHandledState.h; path = ../Source/BugsnagHandledState.h; sourceTree = SOURCE_ROOT; };
E762E9FB1F73F80200E82B43 /* BugsnagHandledState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BugsnagHandledState.m; path = ../Source/BugsnagHandledState.m; sourceTree = SOURCE_ROOT; };
E79E6AFC1F4E3847002B35F9 /* BugsnagCrashSentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugsnagCrashSentry.h; path = ../Source/BugsnagCrashSentry.h; sourceTree = SOURCE_ROOT; };
E79E6AFD1F4E3847002B35F9 /* BugsnagCrashSentry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BugsnagCrashSentry.m; path = ../Source/BugsnagCrashSentry.m; sourceTree = SOURCE_ROOT; };
E79E6AFE1F4E3847002B35F9 /* BugsnagErrorReportApiClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BugsnagErrorReportApiClient.h; path = ../Source/BugsnagErrorReportApiClient.h; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -318,6 +324,8 @@
8A2C8FA31C6BC1F700846019 /* Bugsnag */ = {
isa = PBXGroup;
children = (
E762E9FA1F73F80200E82B43 /* BugsnagHandledState.h */,
E762E9FB1F73F80200E82B43 /* BugsnagHandledState.m */,
E79E6B081F4E3850002B35F9 /* BSG_KSCrash */,
E79E6AFC1F4E3847002B35F9 /* BugsnagCrashSentry.h */,
E79E6AFD1F4E3847002B35F9 /* BugsnagCrashSentry.m */,
Expand Down Expand Up @@ -356,6 +364,7 @@
8A2C8FAF1C6BC1F700846019 /* Tests */ = {
isa = PBXGroup;
children = (
E762E9F71F73F7E900E82B43 /* BugsnagHandledStateTest.m */,
8AD9FA841E0862DC002859A7 /* BugsnagConfigurationSpec.m */,
8AD9FA851E0862DC002859A7 /* BugsnagConfigurationTests.m */,
8A2C8FE01C6BC38200846019 /* BugsnagBreadcrumbsTest.m */,
Expand Down Expand Up @@ -542,6 +551,7 @@
E79E6B931F4E3850002B35F9 /* BSG_KSCrashReportStore.h in Headers */,
E79E6BD31F4E3850002B35F9 /* NSDictionary+BSG_Merge.h in Headers */,
E79E6BB01F4E3850002B35F9 /* BSG_KSBacktrace.h in Headers */,
E762E9FC1F73F80200E82B43 /* BugsnagHandledState.h in Headers */,
E79E6BB51F4E3850002B35F9 /* BSG_KSDynamicLinker.h in Headers */,
E79E6BBF1F4E3850002B35F9 /* BSG_KSMach.h in Headers */,
E79E6BBA1F4E3850002B35F9 /* BSG_KSJSONCodecObjC.h in Headers */,
Expand Down Expand Up @@ -742,6 +752,7 @@
E79E6BA51F4E3850002B35F9 /* BSG_KSCrashSentry_MachException.c in Sources */,
E79E6BB41F4E3850002B35F9 /* BSG_KSDynamicLinker.c in Sources */,
E79E6B031F4E3847002B35F9 /* BugsnagCrashSentry.m in Sources */,
E762E9FD1F73F80200E82B43 /* BugsnagHandledState.m in Sources */,
8A2C8FCE1C6BC2C800846019 /* Bugsnag.m in Sources */,
E79E6B891F4E3850002B35F9 /* BSG_KSCrash.m in Sources */,
E79E6BAC1F4E3850002B35F9 /* BSG_KSCrashSentry_User.c in Sources */,
Expand All @@ -758,6 +769,7 @@
8A2C8FEA1C6BC38900846019 /* BugsnagBreadcrumbsTest.m in Sources */,
8A2C8FEC1C6BC38900846019 /* BugsnagSinkTests.m in Sources */,
8AD9FA891E086351002859A7 /* BugsnagConfigurationTests.m in Sources */,
E762E9F91F73F7F300E82B43 /* BugsnagHandledStateTest.m in Sources */,
8A2C8FEB1C6BC38900846019 /* BugsnagCrashReportTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
14 changes: 14 additions & 0 deletions Source/Bugsnag.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ static NSString *_Nonnull const BugsnagSeverityInfo = @"info";
atSeverity:(NSString *_Nullable)severity
__deprecated_msg("Use notify:block: instead and add the metadata and severity to the report directly.");

/**
* Intended for use by other clients (React Native/Unity). Calling this method directly from
* iOS is not supported.
*/
+ (void)internalClientNotify:(NSException *_Nonnull)exception
withData:(NSDictionary *_Nullable)metaData
block:(BugsnagNotifyBlock _Nullable)block;

/** Add custom data to send to Bugsnag with every exception. If value is nil,
* delete the current value for attributeName
*
Expand Down Expand Up @@ -193,4 +201,10 @@ static NSString *_Nonnull const BugsnagSeverityInfo = @"info";

+ (NSDateFormatter *_Nonnull)payloadDateFormatter;

+ (void)setSuspendThreadsForUserReported:(BOOL)suspendThreadsForUserReported;
+ (void)setReportWhenDebuggerIsAttached:(BOOL)reportWhenDebuggerIsAttached;
+ (void)setThreadTracingEnabled:(BOOL)threadTracingEnabled;
+ (void)setWriteBinaryImagesForUserReported:(BOOL)writeBinaryImagesForUserReported;


@end
26 changes: 26 additions & 0 deletions Source/Bugsnag.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#import "BugsnagNotifier.h"
#import "BugsnagSink.h"
#import "BugsnagLogger.h"
#import "BSG_KSCrash.h"

static BugsnagNotifier* bsg_g_bugsnag_notifier = NULL;

Expand Down Expand Up @@ -122,6 +123,7 @@ + (void)notify:(NSException *)exception
atSeverity:(NSString*)severity {

[[self notifier] notifyException:exception
atSeverity:BSGParseSeverity(severity)
block:^(BugsnagCrashReport * _Nonnull report) {
report.depth += 2;
report.metaData = [metaData BSG_mergedInto:
Expand All @@ -130,6 +132,14 @@ + (void)notify:(NSException *)exception
}];
}

+ (void)internalClientNotify:(NSException *_Nonnull)exception
withData:(NSDictionary *_Nullable)metaData
block:(BugsnagNotifyBlock _Nullable)block {
[self.notifier internalClientNotify:exception
withData:metaData
block:block];
}

+ (void) addAttribute:(NSString*)attributeName withValue:(id)value toTabWithName:(NSString*)tabName {
if([self bugsnagStarted]) {
[self.notifier.configuration.metaData addAttribute:attributeName withValue:value toTabWithName:tabName];
Expand Down Expand Up @@ -183,6 +193,22 @@ + (NSDateFormatter *)payloadDateFormatter {
return formatter;
}

+ (void)setSuspendThreadsForUserReported:(BOOL)suspendThreadsForUserReported {
[[BSG_KSCrash sharedInstance] setSuspendThreadsForUserReported:suspendThreadsForUserReported];
}

+ (void)setReportWhenDebuggerIsAttached:(BOOL)reportWhenDebuggerIsAttached {
[[BSG_KSCrash sharedInstance] setReportWhenDebuggerIsAttached:reportWhenDebuggerIsAttached];
}

+ (void)setThreadTracingEnabled:(BOOL)threadTracingEnabled {
[[BSG_KSCrash sharedInstance] setThreadTracingEnabled:threadTracingEnabled];
}

+ (void)setWriteBinaryImagesForUserReported:(BOOL)writeBinaryImagesForUserReported {
[[BSG_KSCrash sharedInstance] setWriteBinaryImagesForUserReported:writeBinaryImagesForUserReported];
}

@end

//
Expand Down
14 changes: 11 additions & 3 deletions Source/BugsnagCrashReport.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <Foundation/Foundation.h>

@class BugsnagConfiguration;
@class BugsnagHandledState;

typedef NS_ENUM(NSUInteger, BSGSeverity) {
BSGSeverityError,
Expand Down Expand Up @@ -46,21 +47,23 @@ NSString *_Nonnull BSGFormatSeverity(BSGSeverity severity);
- (instancetype _Nonnull)initWithKSReport:(NSDictionary *_Nonnull)report;

/**
* Create a basic crash report from raw parts
* Create a basic crash report from raw parts.
*
* Assumes that the exception is handled.
*
* @param name The name of the exception
* @param message The reason or message from the exception
* @param config Bugsnag configuration
* @param metaData additional data to attach to the report
* @param severity severity of the error
* @param handledState the handled state of the error
*
* @return a Bugsnag crash report
*/
- (instancetype _Nonnull)initWithErrorName:(NSString *_Nonnull)name
errorMessage:(NSString *_Nonnull)message
configuration:(BugsnagConfiguration *_Nonnull)config
metaData:(NSDictionary *_Nonnull)metaData
severity:(BSGSeverity)severity;
handledState:(BugsnagHandledState *_Nonnull)handledState;

/**
* Serialize a crash report as a JSON payload
Expand Down Expand Up @@ -147,6 +150,11 @@ NSString *_Nonnull BSGFormatSeverity(BSGSeverity severity);
* generates a section on bugsnag, displaying key/value pairs
*/
@property (nonatomic, readwrite, copy, nonnull) NSDictionary *metaData;
/**
* The event state (whether the error is handled/unhandled)
*/
@property (nonatomic, readonly, nonnull) BugsnagHandledState *handledState;

/**
* Property overrides
*/
Expand Down
49 changes: 42 additions & 7 deletions Source/BugsnagCrashReport.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import "BugsnagLogger.h"
#import "BSGSerialization.h"
#import "BugsnagSystemInfo.h"
#import "BugsnagHandledState.h"

NSMutableDictionary *BSGFormatFrame(NSDictionary *frame,
NSArray *binaryImages) {
Expand Down Expand Up @@ -284,6 +285,7 @@ @interface BugsnagCrashReport ()
* User-provided exception metadata
*/
@property (nonatomic, readwrite, copy, nullable) NSDictionary *customException;

@end

@implementation BugsnagCrashReport
Expand All @@ -293,7 +295,6 @@ - (instancetype)initWithKSReport:(NSDictionary *)report {
_notifyReleaseStages = [report valueForKeyPath:@"user.config.notifyReleaseStages"];
_releaseStage = BSGParseReleaseStage(report);

// TODO BSG_KSCrash replacement
_error = [report valueForKeyPath:@"crash.error"];
_errorType = _error[@"type"];
_errorClass = BSGParseErrorClass(_error, _errorType);
Expand All @@ -314,25 +315,40 @@ - (instancetype)initWithKSReport:(NSDictionary *)report {
_groupingHash = BSGParseGroupingHash(report, _metaData);
_overrides = [report valueForKeyPath:@"user.overrides"];
_customException = BSGParseCustomException(report, [_errorClass copy], [_errorMessage copy]);

NSDictionary *recordedState = [report valueForKeyPath:@"user.handledState"];

if (recordedState) {
_handledState = [[BugsnagHandledState alloc] initWithDictionary:recordedState];
} else { // the event was unhandled.
BOOL isSignal = [@"signal" isEqualToString:_errorType];
SeverityReasonType severityReason = isSignal ? Signal : UnhandledException;
_handledState = [BugsnagHandledState handledStateWithSeverityReason:severityReason
severity:BSGSeverityError
attrValue:_errorClass];
}
_severity = _handledState.currentSeverity;
}
return self;
}

- (instancetype)initWithErrorName:(NSString *)name
errorMessage:(NSString *)message
configuration:(BugsnagConfiguration *)config
metaData:(NSDictionary *)metaData
severity:(BSGSeverity)severity {
- (instancetype _Nonnull)initWithErrorName:(NSString *_Nonnull)name
errorMessage:(NSString *_Nonnull)message
configuration:(BugsnagConfiguration *_Nonnull)config
metaData:(NSDictionary *_Nonnull)metaData
handledState:(BugsnagHandledState *_Nonnull)handledState {
if (self = [super init]) {
_errorClass = name;
_errorMessage = message;
_metaData = metaData ?: [NSDictionary new];
_severity = severity;
_releaseStage = config.releaseStage;
_notifyReleaseStages = config.notifyReleaseStages;
_context = BSGParseContext(nil, metaData);
_breadcrumbs = [config.breadcrumbs arrayValue];
_overrides = [NSDictionary new];

_handledState = handledState;
_severity = handledState.currentSeverity;
}
return self;
}
Expand Down Expand Up @@ -403,6 +419,11 @@ - (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type {
[self setOverrideProperty:@"customStacktraceType" value:type];
}

- (void)setSeverity:(BSGSeverity)severity {
_severity = severity;
_handledState.currentSeverity = severity;
}

- (void)setOverrideProperty:(NSString *)key value:(id)value {
NSMutableDictionary *metadata = [self.overrides mutableCopy];
if (value) {
Expand Down Expand Up @@ -457,6 +478,20 @@ - (NSDictionary *)serializableValueWithTopLevelData:
BSGDictSetSafeObject(event, [self app], @"app");
BSGDictSetSafeObject(event, [self context], @"context");
BSGDictInsertIfNotNil(event, self.groupingHash, @"groupingHash");

BSGDictSetSafeObject(event, @(self.handledState.unhandled), @"unhandled");

// serialize handled/unhandled into payload
NSMutableDictionary *severityReason = [NSMutableDictionary new];
NSString *reasonType = [BugsnagHandledState stringFromSeverityReason:self.handledState.calculateSeverityReasonType];
severityReason[@"type"] = reasonType;

if (self.handledState.attrKey && self.handledState.attrValue) {
severityReason[@"attributes"] = @{self.handledState.attrKey: self.handledState.attrValue};
}

BSGDictSetSafeObject(event, severityReason, @"severityReason");


// Inserted into `context` property
[metaData removeObjectForKey:@"context"];
Expand Down
45 changes: 45 additions & 0 deletions Source/BugsnagHandledState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// BugsnagHandledState.h
// Bugsnag
//
// Created by Jamie Lynch on 21/09/2017.
// Copyright © 2017 Bugsnag. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "BugsnagCrashReport.h"

typedef NS_ENUM(NSUInteger, SeverityReasonType) {
UnhandledException,
Signal,
HandledError,
HandledException,
UserSpecifiedSeverity,
UserCallbackSetSeverity,
PromiseRejection
};

@interface BugsnagHandledState : NSObject

@property (nonatomic, readonly) BOOL unhandled;
@property (nonatomic, readonly) SeverityReasonType severityReasonType;
@property (nonatomic, readonly) BSGSeverity originalSeverity;
@property (nonatomic) BSGSeverity currentSeverity;
@property (nonatomic, readonly) SeverityReasonType calculateSeverityReasonType;
@property (nonatomic, readonly) NSString *attrValue;
@property (nonatomic, readonly) NSString *attrKey;

+ (NSString *)stringFromSeverityReason:(SeverityReasonType)severityReason;
+ (SeverityReasonType)severityReasonFromString:(NSString *)string;

+ (instancetype)handledStateWithSeverityReason:(SeverityReasonType)severityReason;

+ (instancetype)handledStateWithSeverityReason:(SeverityReasonType)severityReason
severity:(BSGSeverity)severity
attrValue:(NSString *)attrValue;

- (NSDictionary *)toJson;

- (instancetype)initWithDictionary:(NSDictionary *)dict;

@end
Loading

0 comments on commit 41f9ebd

Please sign in to comment.