Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v6.9.1 #1084

Merged
merged 12 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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