Skip to content

Commit

Permalink
Merge pull request #1084 from bugsnag/release-v6.9.1
Browse files Browse the repository at this point in the history
Release v6.9.1
  • Loading branch information
kstenerud authored Apr 28, 2021
2 parents 2f5925e + 5899b74 commit 981cc25
Show file tree
Hide file tree
Showing 32 changed files with 153 additions and 89 deletions.
3 changes: 0 additions & 3 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ steps:
docker-compose#v3.3.0:
run: cocoa-maze-runner
command:
- "features/app_hangs.feature"
- "features/barebone_tests.feature"
- "--app=/app/build/iOSTestApp.ipa"
- "--farm=bs"
Expand All @@ -165,7 +164,6 @@ steps:
docker-compose#v3.3.0:
run: cocoa-maze-runner
command:
- "features/app_hangs.feature"
- "features/barebone_tests.feature"
- "--app=/app/build/iOSTestApp.ipa"
- "--farm=bs"
Expand All @@ -192,7 +190,6 @@ steps:
commands:
- bundle install
- bundle exec maze-runner
features/app_hangs.feature
features/barebone_tests.feature
--farm=local
--os=macos
Expand Down
4 changes: 2 additions & 2 deletions .jazzy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ author_url: "https://www.bugsnag.com"
author: "Bugsnag Inc"
clean: false # avoid deleting docs/.git
framework_root: "Bugsnag"
github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.9.0/Bugsnag"
github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.9.1/Bugsnag"
github_url: "https://github.com/bugsnag/bugsnag-cocoa"
hide_documentation_coverage: true
module: "Bugsnag"
module_version: "6.9.0"
module_version: "6.9.1"
objc: true
output: "docs"
readme: "README.md"
Expand Down
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": "6.9.0",
"version": "6.9.1",
"summary": "The Bugsnag crash reporting framework for Apple platforms.",
"homepage": "https://bugsnag.com",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
},
"source": {
"git": "https://github.com/bugsnag/bugsnag-cocoa.git",
"tag": "v6.9.0"
"tag": "v6.9.1"
},
"frameworks": [
"Foundation",
Expand Down
2 changes: 2 additions & 0 deletions Bugsnag/Client/BugsnagClient+AppHangs.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ - (void)appHangDetectedWithThreads:(nonnull NSArray<BugsnagThread *> *)threads {
threads:threads
session:self.sessionTracker.runningSession];

self.appHangEvent.context = self.context;

NSError *writeError = nil;
NSDictionary *json = [self.appHangEvent toJsonWithRedactedKeys:self.configuration.redactedKeys];
if (![BSGJSONSerialization writeJSONObject:json toFile:BSGFileLocations.current.appHangEvent options:0 error:&writeError]) {
Expand Down
9 changes: 9 additions & 0 deletions Bugsnag/Client/BugsnagClient+OutOfMemory.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "BugsnagAppWithState+Private.h"
#import "BugsnagBreadcrumbs.h"
#import "BugsnagClient+Private.h"
#import "BugsnagConfiguration+Private.h"
#import "BugsnagDeviceWithState+Private.h"
#import "BugsnagError+Private.h"
#import "BugsnagEvent+Private.h"
Expand All @@ -27,6 +28,12 @@ - (BugsnagEvent *)generateOutOfMemoryEvent {
app.dsymUuid = appDict[BSGKeyMachoUUID];
app.isLaunching = [self.stateMetadataFromLastLaunch[BSGKeyApp][BSGKeyIsLaunching] boolValue];

if (self.configMetadataFromLastLaunch) {
[app setValuesFromConfiguration:
[[BugsnagConfiguration alloc] initWithDictionaryRepresentation:
(NSDictionary * _Nonnull)self.configMetadataFromLastLaunch]];
}

NSDictionary *deviceDict = self.systemState.lastLaunchState[SYSTEMSTATE_KEY_DEVICE];
BugsnagDeviceWithState *device = [BugsnagDeviceWithState deviceFromJson:deviceDict];
device.manufacturer = @"Apple";
Expand Down Expand Up @@ -59,6 +66,8 @@ - (BugsnagEvent *)generateOutOfMemoryEvent {
threads:@[]
session:session];

event.context = self.stateMetadataFromLastLaunch[BSGKeyClient][BSGKeyContext];

return event;
}

Expand Down
26 changes: 26 additions & 0 deletions Bugsnag/Client/BugsnagClient+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,32 @@ NS_ASSUME_NONNULL_BEGIN

@property (readonly, nonatomic) BOOL started;

/// State related metadata
///
/// Upon change this is automatically persisted to disk, making it available when contructing OOM payloads.
/// Is it also added to KSCrashReports under `user.state` by `BSSerializeDataCrashHandler()`.
///
/// Example contents:
///
/// {
/// "app": {
/// "codeBundleId": "com.example.app",
/// "isLaunching": true
/// },
/// "client": {
/// "context": "MyViewController",
/// },
/// "deviceState": {
/// "batteryLevel": 0.5,
/// "charging": false,
/// "lowMemoryWarning": "2021-01-01T15:29:02.170Z",
/// "orientation": "portrait"
/// },
/// "user": {
/// "id": "abc123",
/// "name": "bob"
/// }
/// }
@property (strong, nonatomic) BugsnagMetadata *state;

@property (strong, nonatomic) NSMutableArray *stateEventBlocks;
Expand Down
24 changes: 11 additions & 13 deletions Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#import "BugsnagSession+Private.h"
#import "BugsnagSessionTracker+Private.h"
#import "BugsnagSessionTrackingApiClient.h"
#import "BugsnagStackframe+Private.h"
#import "BugsnagStateEvent.h"
#import "BugsnagSystemState.h"
#import "BugsnagThread+Private.h"
Expand Down Expand Up @@ -98,9 +99,6 @@
// Contains notifier state, under "deviceState" and crash-specific
// information under "crash".
char *statePath;
// Contains properties in the Bugsnag payload overridden by the user before
// it was sent
char *userOverridesJSON;
// User onCrash handler
void (*onCrash)(const BSG_KSCrashReportWriter *writer);
} bsg_g_bugsnag_data;
Expand Down Expand Up @@ -247,7 +245,10 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration {
if ((self = [super init])) {
// Take a shallow copy of the configuration
_configuration = [configuration copy];
_state = [[BugsnagMetadata alloc] initWithDictionary:@{BSGKeyApp: @{BSGKeyIsLaunching: @YES}}];
_state = [[BugsnagMetadata alloc] initWithDictionary:@{
BSGKeyApp: @{BSGKeyIsLaunching: @YES},
BSGKeyClient: BSGDictionaryWithKeyAndObject(BSGKeyContext, _configuration.context)
}];
self.notifier = [BugsnagNotifier new];
self.systemState = [[BugsnagSystemState alloc] initWithConfiguration:configuration];

Expand Down Expand Up @@ -762,11 +763,12 @@ - (void)removeOnBreadcrumbBlock:(BugsnagOnBreadcrumbBlock _Nonnull)block {
}

// =============================================================================
// MARK: - Other methods
// MARK: - Context
// =============================================================================

- (void)setContext:(nullable NSString *)context {
self.configuration.context = context;
[self.state addMetadata:context withKey:BSGKeyContext toSection:BSGKeyClient];
[self notifyObservers:[[BugsnagStateEvent alloc] initWithName:kStateEventContext data:context]];
}

Expand Down Expand Up @@ -870,18 +872,14 @@ - (void)notify:(NSException *)exception

NSArray<NSNumber *> *callStack = exception.callStackReturnAddresses;
if (!callStack.count) {
// If the NSException was not raised by the Objective-C runtime, it will be missing a call stack.
// Use the current call stack instead.
callStack = BSGArraySubarrayFromIndex(NSThread.callStackReturnAddresses, depth);
}
BOOL recordAllThreads = self.configuration.sendThreads == BSGThreadSendPolicyAlways;
NSArray *threads = [BugsnagThread allThreads:recordAllThreads callStackReturnAddresses:callStack];
NSArray *threads = recordAllThreads ? [BugsnagThread allThreads:YES callStackReturnAddresses:callStack] : @[];

NSArray<BugsnagStackframe *> *stacktrace = nil;
for (BugsnagThread *thread in threads) {
if (thread.errorReportingThread) {
stacktrace = thread.stacktrace;
break;
}
}
NSArray<BugsnagStackframe *> *stacktrace = [BugsnagStackframe stackframesWithCallStackReturnAddresses:callStack];

BugsnagError *error = [[BugsnagError alloc] initWithErrorClass:exception.name ?: NSStringFromClass([exception class])
errorMessage:exception.reason ?: @""
Expand Down
3 changes: 3 additions & 0 deletions Bugsnag/Helpers/BugsnagCollections.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ NSArray * BSGArraySubarrayFromIndex(NSArray *array, NSUInteger index);

// MARK: - NSDictionary

/// Returns a dictionary containing the key and object, or an empty dictionary if the object is nil.
NSDictionary * BSGDictionaryWithKeyAndObject(NSString *key, id _Nullable object);

/**
* Merge values from source dictionary with destination
*
Expand Down
4 changes: 4 additions & 0 deletions Bugsnag/Helpers/BugsnagCollections.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ void BSGArrayAddIfNonnull(NSMutableArray *array, id _Nullable object) {

// MARK: - NSDictionary

NSDictionary * BSGDictionaryWithKeyAndObject(NSString *key, id _Nullable object) {
return object ? @{key: (id _Nonnull)object} : @{};
}

NSDictionary *BSGDictMerge(NSDictionary *source, NSDictionary *destination) {
if ([destination count] == 0) {
return source;
Expand Down
1 change: 1 addition & 0 deletions Bugsnag/Helpers/BugsnagKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern NSString *const BSGKeyBatteryLevel;
extern NSString *const BSGKeyBreadcrumbs;
extern NSString *const BSGKeyBundleVersion;
extern NSString *const BSGKeyCharging;
extern NSString *const BSGKeyClient;
extern NSString *const BSGKeyCodeBundleId;
extern NSString *const BSGKeyConfig;
extern NSString *const BSGKeyContext;
Expand Down
1 change: 1 addition & 0 deletions Bugsnag/Helpers/BugsnagKeys.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
NSString *const BSGKeyBreadcrumbs = @"breadcrumbs";
NSString *const BSGKeyBundleVersion = @"bundleVersion";
NSString *const BSGKeyCharging = @"charging";
NSString *const BSGKeyClient = @"client";
NSString *const BSGKeyCodeBundleId = @"codeBundleId";
NSString *const BSGKeyConfig = @"config";
NSString *const BSGKeyContext = @"context";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ void bsg_recordException(NSException *exception) {
bsg_lastHandledException = exception;
BSG_KSLOG_DEBUG(@"Writing exception info into a new report");

BSG_KSLOG_DEBUG(@"Suspending all threads.");
bsg_kscrashsentry_suspendThreads();

BSG_KSLOG_DEBUG(@"Filling out context.");
NSArray *addresses = [exception callStackReturnAddresses];
NSUInteger numFrames = [addresses count];
Expand All @@ -137,6 +134,9 @@ void bsg_recordException(NSException *exception) {
bsg_g_context->stackTrace = callstack;
bsg_g_context->stackTraceLength = callstack ? (int)numFrames : 0;

BSG_KSLOG_DEBUG(@"Suspending all threads.");
bsg_kscrashsentry_suspendThreads();

BSG_KSLOG_DEBUG(@"Calling main crash handler.");
bsg_g_context->onCrash(crashContext());

Expand Down
2 changes: 2 additions & 0 deletions Bugsnag/Payload/BugsnagApp+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ NS_ASSUME_NONNULL_BEGIN

+ (void)populateFields:(BugsnagApp *)app dictionary:(NSDictionary *)event config:(BugsnagConfiguration *)config codeBundleId:(NSString *)codeBundleId;

- (void)setValuesFromConfiguration:(BugsnagConfiguration *)configuration;

- (NSDictionary *)toDict;

@end
Expand Down
23 changes: 19 additions & 4 deletions Bugsnag/Payload/BugsnagApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,27 @@ + (void)populateFields:(BugsnagApp *)app
{
NSDictionary *system = event[BSGKeySystem];
app.id = system[@"CFBundleIdentifier"];
app.bundleVersion = config.bundleVersion ?: system[@"CFBundleVersion"];
app.bundleVersion = system[@"CFBundleVersion"];
app.dsymUuid = system[@"app_uuid"];
app.version = config.appVersion ?: system[@"CFBundleShortVersionString"];
app.releaseStage = config.releaseStage;
app.version = system[@"CFBundleShortVersionString"];
app.codeBundleId = [event valueForKeyPath:@"user.state.app.codeBundleId"] ?: codeBundleId;
app.type = config.appType;
[app setValuesFromConfiguration:config];
}

- (void)setValuesFromConfiguration:(BugsnagConfiguration *)configuration
{
if (configuration.appType) {
self.type = configuration.appType;
}
if (configuration.appVersion) {
self.version = configuration.appVersion;
}
if (configuration.bundleVersion) {
self.bundleVersion = configuration.bundleVersion;
}
if (configuration.releaseStage) {
self.releaseStage = configuration.releaseStage;
}
}

- (NSDictionary *)toDict
Expand Down
1 change: 1 addition & 0 deletions Bugsnag/Payload/BugsnagAppWithState+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "BugsnagAppWithState.h"
#import "BugsnagApp+Private.h"

@class BugsnagConfiguration;

Expand Down
2 changes: 1 addition & 1 deletion Bugsnag/Payload/BugsnagError+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN

@interface BugsnagError ()

- (instancetype)initWithEvent:(NSDictionary *)event errorReportingThread:(nullable BugsnagThread *)thread;
- (instancetype)initWithKSCrashReport:(NSDictionary *)event stacktrace:(NSArray<BugsnagStackframe *> *)stacktrace;

- (instancetype)initWithErrorClass:(NSString *)errorClass
errorMessage:(NSString *)errorMessage
Expand Down
8 changes: 2 additions & 6 deletions Bugsnag/Payload/BugsnagError.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,7 @@ @implementation BugsnagError

@dynamic type;

- (instancetype)initWithErrorReportingThread:(BugsnagThread *)thread {
return [self initWithEvent:@{} errorReportingThread:thread];
}

- (instancetype)initWithEvent:(NSDictionary *)event errorReportingThread:(BugsnagThread *)thread {
- (instancetype)initWithKSCrashReport:(NSDictionary *)event stacktrace:(NSArray<BugsnagStackframe *> *)stacktrace {
if (self = [super init]) {
NSDictionary *error = [event valueForKeyPath:@"crash.error"];
NSString *errorType = error[BSGKeyType];
Expand All @@ -96,7 +92,7 @@ - (instancetype)initWithEvent:(NSDictionary *)event errorReportingThread:(Bugsna
_typeString = BSGSerializeErrorType(BSGErrorTypeCocoa);

if (![[event valueForKeyPath:@"user.state.didOOM"] boolValue]) {
_stacktrace = thread.stacktrace;
_stacktrace = stacktrace;
}
}
return self;
Expand Down
20 changes: 12 additions & 8 deletions Bugsnag/Payload/BugsnagEvent.m
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ - (instancetype)initWithKSReport:(NSDictionary *)event {
} else if ([event valueForKeyPath:@"user.event"] != nil) {
return [self initWithUserData:event];
} else {
return [self initWithKSCrashData:event];
return [self initWithKSCrashReport:event];
}
}

Expand All @@ -259,7 +259,7 @@ - (instancetype)initWithKSReport:(NSDictionary *)event {
*
* @return a BugsnagEvent containing the parsed information
*/
- (instancetype)initWithKSCrashData:(NSDictionary *)event {
- (instancetype)initWithKSCrashReport:(NSDictionary *)event {
NSMutableDictionary *error = [[event valueForKeyPath:@"crash.error"] mutableCopy];
NSString *errorType = error[BSGKeyType];

Expand Down Expand Up @@ -310,20 +310,23 @@ - (instancetype)initWithKSCrashData:(NSDictionary *)event {
// generate threads/error info
NSArray *binaryImages = event[@"binary_images"];
NSArray *threadDict = [event valueForKeyPath:@"crash.threads"];
NSMutableArray<BugsnagThread *> *threads = [BugsnagThread threadsFromArray:threadDict
binaryImages:binaryImages
depth:depth
errorType:errorType];
NSArray<BugsnagThread *> *threads = [BugsnagThread threadsFromArray:threadDict binaryImages:binaryImages depth:depth errorType:errorType];

BugsnagThread *errorReportingThread;
BugsnagThread *errorReportingThread = nil;
for (BugsnagThread *thread in threads) {
if (thread.errorReportingThread) {
errorReportingThread = thread;
break;
}
}

NSArray<BugsnagError *> *errors = @[[[BugsnagError alloc] initWithEvent:event errorReportingThread:errorReportingThread]];
NSArray<BugsnagError *> *errors = @[[[BugsnagError alloc] initWithKSCrashReport:event stacktrace:errorReportingThread.stacktrace ?: @[]]];

// KSCrash captures only the offending thread when sendThreads = BSGThreadSendPolicyNever.
// The BugsnagEvent should not contain threads in this case, only the stacktrace.
if (threads.count == 1) {
threads = @[];
}

if (errorReportingThread.crashInfoMessage) {
[errors[0] updateWithCrashInfoMessage:(NSString * _Nonnull)errorReportingThread.crashInfoMessage];
Expand Down Expand Up @@ -374,6 +377,7 @@ - (instancetype)initWithKSCrashData:(NSDictionary *)event {
obj.enabledReleaseStages = BSGLoadConfigValue(event, BSGKeyEnabledReleaseStages);
obj.releaseStage = BSGParseReleaseStage(event);
obj.deviceAppHash = deviceAppHash;
obj.context = [event valueForKeyPath:@"user.state.client.context"];
obj.customException = BSGParseCustomException(event, [errors[0].errorClass copy], [errors[0].errorMessage copy]);
obj.error = error;
obj.depth = depth;
Expand Down
2 changes: 1 addition & 1 deletion Bugsnag/Payload/BugsnagNotifier.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ - (instancetype)init {
#else
self.name = @"Bugsnag Objective-C";
#endif
self.version = @"6.9.0";
self.version = @"6.9.1";
self.url = @"https://github.com/bugsnag/bugsnag-cocoa";
self.dependencies = [NSMutableArray new];
}
Expand Down
Loading

0 comments on commit 981cc25

Please sign in to comment.