From 46f37cad7d1cb84e8c44ae91c7c9ed9769abda3b Mon Sep 17 00:00:00 2001 From: Steve Kirkland-Walton Date: Thu, 20 Jun 2024 14:10:28 +0100 Subject: [PATCH 1/6] Build xcframework on CI --- .buildkite/pipeline.full.yml | 16 ++++++++-------- .buildkite/pipeline.yml | 35 ++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.buildkite/pipeline.full.yml b/.buildkite/pipeline.full.yml index 8578cfc58..50a51885a 100644 --- a/.buildkite/pipeline.full.yml +++ b/.buildkite/pipeline.full.yml @@ -17,7 +17,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -49,7 +49,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -78,7 +78,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -105,7 +105,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -131,7 +131,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -163,7 +163,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -193,7 +193,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -225,7 +225,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 51e18c257..c1474331c 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,13 +7,28 @@ steps: # Build # + - label: Static framework and Swift Package Manager builds + timeout_in_minutes: 10 + agents: + queue: macos-14 + env: + XCODE_VERSION: 15.3.0 + commands: + - make build_xcframework + - make build_swift + - make build_ios_static + plugins: + - artifacts#v1.9.3: + upload: "build/xcframeworks/products/Bugsnag.xcframework" + compressed: xcframework.zip + - label: Build test fixtures key: cocoa_fixture timeout_in_minutes: 30 agents: queue: macos-14 env: - DEVELOPER_DIR: /Applications/Xcode-15.app + XCODE_VERSION: 15.3.0 artifact_paths: - features/fixtures/ios/output/iOSTestApp.ipa - features/fixtures/macos/output/macOSTestApp.zip @@ -25,16 +40,6 @@ steps: - bundle exec upload-app --farm=bb --app=./features/fixtures/ios/output/iOSTestApp.ipa --app-id-file=./features/fixtures/ios/output/ipa_url_bb.txt - bundle exec upload-app --farm=bs --app=./features/fixtures/ios/output/iOSTestApp.ipa --app-id-file=./features/fixtures/ios/output/ipa_url_bs.txt - - label: Static framework and Swift Package Manager builds - timeout_in_minutes: 10 - agents: - queue: macos-14 - env: - DEVELOPER_DIR: /Applications/Xcode-15.app - commands: - - make build_swift - - make build_ios_static - - label: Carthage timeout_in_minutes: 15 agents: @@ -446,7 +451,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -476,7 +481,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -506,7 +511,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: @@ -536,7 +541,7 @@ steps: agents: queue: opensource plugins: - artifacts#v1.9.0: + artifacts#v1.9.3: download: "features/fixtures/ios/output/ipa_url_bb.txt" upload: "maze_output/failed/**/*" docker-compose#v4.7.0: From cdc4777a3c1ef17d4dfc21473d5c2706bbac2915 Mon Sep 17 00:00:00 2001 From: robert-smartbear <126675445+robert-smartbear@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:15:23 +0200 Subject: [PATCH 2/6] Camelcase error correlation fields (#1665) Co-authored-by: Robert --- Bugsnag/Payload/BugsnagCorrelation.m | 8 ++++---- Bugsnag/Payload/BugsnagEvent.m | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Bugsnag/Payload/BugsnagCorrelation.m b/Bugsnag/Payload/BugsnagCorrelation.m index 1b6383ecf..2eb4254c9 100644 --- a/Bugsnag/Payload/BugsnagCorrelation.m +++ b/Bugsnag/Payload/BugsnagCorrelation.m @@ -25,12 +25,12 @@ - (instancetype) initWithJsonDictionary:(NSDictionary *) if ((self = [super init])) { id nsnull = NSNull.null; - _traceId = (NSString *)dict[@"traceid"]; + _traceId = (NSString *)dict[@"traceId"]; if (_traceId == nsnull) { _traceId = nil; } - _spanId = (NSString *)dict[@"spanid"]; + _spanId = (NSString *)dict[@"spanId"]; if (_spanId == nsnull) { _spanId = nil; } @@ -41,8 +41,8 @@ - (instancetype) initWithJsonDictionary:(NSDictionary *) - (NSDictionary *) toJsonDictionary { NSMutableDictionary *dict = [NSMutableDictionary new]; - dict[@"traceid"] = self.traceId; - dict[@"spanid"] = self.spanId; + dict[@"traceId"] = self.traceId; + dict[@"spanId"] = self.spanId; return dict; } diff --git a/Bugsnag/Payload/BugsnagEvent.m b/Bugsnag/Payload/BugsnagEvent.m index e505f3cc7..ede81274a 100644 --- a/Bugsnag/Payload/BugsnagEvent.m +++ b/Bugsnag/Payload/BugsnagEvent.m @@ -380,8 +380,8 @@ - (instancetype)initWithKSCrashReport:(NSDictionary *)event { [configDict isKindOfClass:[NSDictionary class]] ? configDict : @{}]; NSDictionary *correlationDict = [event valueForKeyPath:@"user.correlation"]; - NSString *traceId = correlationDict[@"traceid"]; - NSString *spanId = correlationDict[@"spanid"]; + NSString *traceId = correlationDict[@"traceId"]; + NSString *spanId = correlationDict[@"spanId"]; BugsnagAppWithState *app = [BugsnagAppWithState appWithDictionary:event config:config codeBundleId:self.codeBundleId]; From 454878cede30f3cea8e68daf3834a23bd22a4204 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 27 Jun 2024 19:40:36 +0200 Subject: [PATCH 3/6] Harmonize all calls to manual error reporting, and ensure proper frame stripping in all cases --- Bugsnag/Bugsnag.m | 20 ++++++-- Bugsnag/Client/BugsnagClient+Private.h | 20 ++++++++ Bugsnag/Client/BugsnagClient.m | 51 +++++++------------- Bugsnag/Helpers/BSGUtils.h | 2 + Bugsnag/Helpers/BSGUtils.m | 7 +++ Tests/BugsnagTests/BugsnagClientMirrorTest.m | 1 + 6 files changed, 64 insertions(+), 37 deletions(-) diff --git a/Bugsnag/Bugsnag.m b/Bugsnag/Bugsnag.m index da9e7a344..7eebdfe00 100644 --- a/Bugsnag/Bugsnag.m +++ b/Bugsnag/Bugsnag.m @@ -32,6 +32,7 @@ #import "BugsnagClient+Private.h" #import "BugsnagInternals.h" #import "BugsnagLogger.h" +#import "BSGUtils.h" static BugsnagClient *bsg_g_bugsnag_client = NULL; @@ -98,27 +99,38 @@ + (void)markLaunchCompleted { } } +// Here, we pass all public notify APIs to a common handling method +// (notifyErrorOrException) and then prevent the compiler from performing +// any inlining or outlining that would change the number of Bugsnag handler +// methods on the stack and break our stack stripping. +// Note: Each BSGPreventInlining call site within a module MUST pass a different +// string to prevent outlining! + + (void)notify:(NSException *)exception { if ([self bugsnagReadyForInternalCalls]) { - [self.client notify:exception]; + BSGPreventInlining(@"Prevent"); + [self.client notifyErrorOrException:exception stackStripDepth:2 block:nil]; } } + (void)notify:(NSException *)exception block:(BugsnagOnErrorBlock)block { if ([self bugsnagReadyForInternalCalls]) { - [self.client notify:exception block:block]; + BSGPreventInlining(@"inlining"); + [self.client notifyErrorOrException:exception stackStripDepth:2 block:block]; } } + (void)notifyError:(NSError *)error { if ([self bugsnagReadyForInternalCalls]) { - [self.client notifyError:error]; + BSGPreventInlining(@"and"); + [self.client notifyErrorOrException:error stackStripDepth:2 block:nil]; } } + (void)notifyError:(NSError *)error block:(BugsnagOnErrorBlock)block { if ([self bugsnagReadyForInternalCalls]) { - [self.client notifyError:error block:block]; + BSGPreventInlining(@"outlining"); + [self.client notifyErrorOrException:error stackStripDepth:2 block:block]; } } diff --git a/Bugsnag/Client/BugsnagClient+Private.h b/Bugsnag/Client/BugsnagClient+Private.h index fd3c836fd..068e40727 100644 --- a/Bugsnag/Client/BugsnagClient+Private.h +++ b/Bugsnag/Client/BugsnagClient+Private.h @@ -75,6 +75,26 @@ BSG_OBJC_DIRECT_MEMBERS - (void)start; +/** + * Common entry point to notify an error or an exception. + * Bugsnag components MUST NOT call the regular notify methods in this class. ALWAYS call + * this method instead. + * + * You must provide the number of stack trace entries to strip from the top of the stack + * (INCLUDING this method) so that our own reporting methods don't show up in the reported stack trace. + * + * Example: stackStripDepth = 2 would strip the top two entries, which we would expect to be + * 1. +[Bugsnag notifyError:block:] + * 2. -[BugsnagClient notifyErrorOrException:stackStripDepth:block:] + * + * @param errorOrException the error or exception to report. + * @param stackStripDepth The number of stack trace entries to strip from the top of the stack. + * @param block Called after reporting. + */ +- (void)notifyErrorOrException:(id)errorOrException + stackStripDepth:(NSUInteger)stackStripDepth + block:(_Nullable BugsnagOnErrorBlock)block; + @end NS_ASSUME_NONNULL_END diff --git a/Bugsnag/Client/BugsnagClient.m b/Bugsnag/Client/BugsnagClient.m index 73215e52c..dd1200d49 100644 --- a/Bugsnag/Client/BugsnagClient.m +++ b/Bugsnag/Client/BugsnagClient.m @@ -641,37 +641,35 @@ - (NSString *)context { // MARK: - Notify -// Prevent the compiler from inlining or optimizing, which would reduce -// the number of bugsnag-only stack entries and mess up our pruning. -// We have to do it this way because you can't mark Objective-C methods noinline or optnone. -// We leave it externable to further dissuade the optimizer. -__attribute__((optnone)) -void bsg_notifyErrorOrException(BugsnagClient *self, id errorOrException, BugsnagOnErrorBlock block) { - [self notifyErrorOrException:errorOrException block:block]; -} - -// note - some duplication between notifyError calls is required to ensure -// the same number of stackframes are used for each call. -// see notify:handledState:block for further info +// Here, we pass all public notify APIs to a common handling method +// (notifyErrorOrException) and then prevent the compiler from performing +// any inlining or outlining that would change the number of Bugsnag handler +// methods on the stack and break our stack stripping. +// Note: Each BSGPreventInlining call site within a module MUST pass a different +// string to prevent outlining! - (void)notifyError:(NSError *)error { bsg_log_debug(@"%s %@", __PRETTY_FUNCTION__, error); - bsg_notifyErrorOrException(self, error, nil); + BSGPreventInlining(@"Prevent"); + [self notifyErrorOrException:error stackStripDepth:2 block:nil]; } - (void)notifyError:(NSError *)error block:(BugsnagOnErrorBlock)block { bsg_log_debug(@"%s %@", __PRETTY_FUNCTION__, error); - bsg_notifyErrorOrException(self, error, block); + BSGPreventInlining(@"inlining"); + [self notifyErrorOrException:error stackStripDepth:2 block:block]; } - (void)notify:(NSException *)exception { bsg_log_debug(@"%s %@", __PRETTY_FUNCTION__, exception); - bsg_notifyErrorOrException(self, exception, nil); + BSGPreventInlining(@"and"); + [self notifyErrorOrException:exception stackStripDepth:2 block:nil]; } - (void)notify:(NSException *)exception block:(BugsnagOnErrorBlock)block { bsg_log_debug(@"%s %@", __PRETTY_FUNCTION__, exception); - bsg_notifyErrorOrException(self, exception, block); + BSGPreventInlining(@"outlining"); + [self notifyErrorOrException:exception stackStripDepth:2 block:block]; } // MARK: - Notify (Internal) @@ -686,7 +684,9 @@ - (BugsnagCorrelation *)getCurrentCorrelation { return [[BugsnagCorrelation alloc] initWithTraceId:traceId spanId:spanId]; } -- (void)notifyErrorOrException:(id)errorOrException block:(BugsnagOnErrorBlock)block { +- (void)notifyErrorOrException:(id)errorOrException + stackStripDepth:(NSUInteger)stackStripDepth + block:(_Nullable BugsnagOnErrorBlock)block { BugsnagCorrelation *correlation = [self getCurrentCorrelation]; NSDictionary *systemInfo = [BSG_KSSystemInfo systemInfo]; BugsnagMetadata *metadata = [self.metadata copy]; @@ -730,25 +730,10 @@ - (void)notifyErrorOrException:(id)errorOrException block:(BugsnagOnErrorBlock)b return; } - /** - * Stack frames starting from this one are removed by setting the depth. - * This helps remove bugsnag frames from showing in NSErrors as their - * trace is synthesized. - * - * For example, for [Bugsnag notifyError:block:], bugsnag adds the following - * frames which must be removed: - * - * 1. +[Bugsnag notifyError:block:] - * 2. -[BugsnagClient notifyError:block:] - * 3. bsg_notifyErrorOrException() - * 4. -[BugsnagClient notifyErrorOrException:block:] - */ - NSUInteger depth = 4; - 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); + callStack = BSGArraySubarrayFromIndex(NSThread.callStackReturnAddresses, stackStripDepth); } #if BSG_HAVE_MACH_THREADS diff --git a/Bugsnag/Helpers/BSGUtils.h b/Bugsnag/Helpers/BSGUtils.h index d462290fa..89c5ababd 100644 --- a/Bugsnag/Helpers/BSGUtils.h +++ b/Bugsnag/Helpers/BSGUtils.h @@ -45,6 +45,8 @@ static inline NSString * _Nullable BSGStringFromClass(Class _Nullable cls) { */ void bsg_safe_strncpy(char *dst, const char *src, size_t length); +NSString * _Nullable BSGPreventInlining(NSString * _Nullable someValue); + NS_ASSUME_NONNULL_END __END_DECLS diff --git a/Bugsnag/Helpers/BSGUtils.m b/Bugsnag/Helpers/BSGUtils.m index 04e8d9863..6b57b2fac 100644 --- a/Bugsnag/Helpers/BSGUtils.m +++ b/Bugsnag/Helpers/BSGUtils.m @@ -89,3 +89,10 @@ dispatch_queue_t BSGGetFileSystemQueue(void) { } return nil; } + +NSString * _Nullable BSGPreventInlining(NSString * _Nullable someValue) { + static NSString *lastValue = nil; + NSString *returnValue = lastValue; + lastValue = someValue; + return returnValue; +} diff --git a/Tests/BugsnagTests/BugsnagClientMirrorTest.m b/Tests/BugsnagTests/BugsnagClientMirrorTest.m index 3f9355c0f..cd5b592e5 100644 --- a/Tests/BugsnagTests/BugsnagClientMirrorTest.m +++ b/Tests/BugsnagTests/BugsnagClientMirrorTest.m @@ -132,6 +132,7 @@ - (void)setUp { @"systemState @16@0:8", @"thermalStateDidChange: v24@0:8@16", @"updateSession: v24@0:8@?16", + @"notifyErrorOrException:stackStripDepth:block: v40@0:8@16Q24@?32", ]]; // the following methods are implemented on Bugsnag but do not need to From bb4f7a2afaebe0bd24b7e379e61411a2dafdab5d Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Fri, 28 Jun 2024 14:28:20 +0200 Subject: [PATCH 4/6] Manually export BugsnagCorrelation (#1669) --- Bugsnag/include/Bugsnag/BugsnagCorrelation.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Bugsnag/include/Bugsnag/BugsnagCorrelation.h b/Bugsnag/include/Bugsnag/BugsnagCorrelation.h index c817a9821..e8ffbd329 100644 --- a/Bugsnag/include/Bugsnag/BugsnagCorrelation.h +++ b/Bugsnag/include/Bugsnag/BugsnagCorrelation.h @@ -7,12 +7,11 @@ // #import - -#ifndef BugsnagCorrelation_h -#define BugsnagCorrelation_h +#import NS_ASSUME_NONNULL_BEGIN +BUGSNAG_EXTERN @interface BugsnagCorrelation: NSObject @property (readwrite, nonatomic, strong, nullable) NSString *traceId; @@ -22,5 +21,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - -#endif /* BugsnagCorrelation_h */ From 73e84267dc5a4d69b4b73cf830d0dfa0910b23df Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 4 Jul 2024 07:56:05 +0200 Subject: [PATCH 5/6] Don't expose BugsnagCorrelation publicly --- Bugsnag.xcodeproj/project.pbxproj | 14 +++++------ Bugsnag/Client/BugsnagClient.m | 1 - ...elation+Private.h => BugsnagCorrelation.h} | 19 +++++++-------- Bugsnag/Payload/BugsnagCorrelation.m | 2 +- Bugsnag/Payload/BugsnagEvent+Private.h | 3 +++ Bugsnag/Payload/BugsnagEvent.m | 5 +++- Bugsnag/include/Bugsnag/BugsnagCorrelation.h | 10 ++++++-- Bugsnag/include/Bugsnag/BugsnagEvent.h | 5 ++-- .../BugsnagEventPersistLoadTest.m | 23 +++++++++++++++++++ 9 files changed, 57 insertions(+), 25 deletions(-) rename Bugsnag/Payload/{BugsnagCorrelation+Private.h => BugsnagCorrelation.h} (54%) diff --git a/Bugsnag.xcodeproj/project.pbxproj b/Bugsnag.xcodeproj/project.pbxproj index 69f20bfa6..4939f4dc0 100644 --- a/Bugsnag.xcodeproj/project.pbxproj +++ b/Bugsnag.xcodeproj/project.pbxproj @@ -737,10 +737,10 @@ 09E312F42BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E312EE2BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m */; }; 09E312F52BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E312EE2BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m */; }; 09E312F62BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E312EE2BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m */; }; - 09E312F82BF248E70081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 09E312F92BF248E80081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 09E312FA2BF248E90081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 09E312FB2BF248E90081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09E312F82BF248E70081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; }; + 09E312F92BF248E80081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; }; + 09E312FA2BF248E90081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; }; + 09E312FB2BF248E90081F219 /* BugsnagCorrelation.h in Headers */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; }; 09E312FC2BF2492C0081F219 /* BugsnagCorrelation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */; }; 09E312FE2BF34D6D0081F219 /* BugsnagCorrelation.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E312FD2BF34D6D0081F219 /* BugsnagCorrelation.m */; }; 09E312FF2BF34D6D0081F219 /* BugsnagCorrelation.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E312FD2BF34D6D0081F219 /* BugsnagCorrelation.m */; }; @@ -1577,9 +1577,8 @@ 093EB6652AFE4580006EB7E3 /* BSGTestCase.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BSGTestCase.mm; sourceTree = ""; }; 09E312ED2BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagCocoaPerformanceFromBugsnagCocoa.h; sourceTree = ""; }; 09E312EE2BF230660081F219 /* BugsnagCocoaPerformanceFromBugsnagCocoa.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BugsnagCocoaPerformanceFromBugsnagCocoa.m; sourceTree = ""; }; - 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagCorrelation.h; sourceTree = ""; }; + 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BugsnagCorrelation.h; path = ../include/Bugsnag/BugsnagCorrelation.h; sourceTree = ""; }; 09E312FD2BF34D6D0081F219 /* BugsnagCorrelation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BugsnagCorrelation.m; sourceTree = ""; }; - 09E313022BF34E5E0081F219 /* BugsnagCorrelation+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagCorrelation+Private.h"; sourceTree = ""; }; 09E3132E2BF3867C0081F219 /* BugsnagPerformanceBridgeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BugsnagPerformanceBridgeTests.m; sourceTree = ""; }; 3A700A8024A63A8E0068CD1B /* BugsnagThread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagThread.h; sourceTree = ""; }; 3A700A8124A63A8E0068CD1B /* BugsnagSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BugsnagSession.h; sourceTree = ""; }; @@ -2178,8 +2177,8 @@ 0126DED7257A87F40031A70C /* BugsnagAppWithState+Private.h */, 0089684B2486DA9400DC48C2 /* BugsnagBreadcrumb.m */, 0126DEDF257A89490031A70C /* BugsnagBreadcrumb+Private.h */, + 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */, 09E312FD2BF34D6D0081F219 /* BugsnagCorrelation.m */, - 09E313022BF34E5E0081F219 /* BugsnagCorrelation+Private.h */, 008968482486DA9400DC48C2 /* BugsnagDevice.m */, 0126DEE7257A8B0F0031A70C /* BugsnagDevice+Private.h */, 0089685A2486DA9500DC48C2 /* BugsnagDeviceWithState.m */, @@ -2261,7 +2260,6 @@ 3A700A8524A63A8E0068CD1B /* BugsnagBreadcrumb.h */, 3A700A8924A63A8E0068CD1B /* BugsnagClient.h */, 3A700A8D24A63A8E0068CD1B /* BugsnagConfiguration.h */, - 09E312F72BF248DD0081F219 /* BugsnagCorrelation.h */, 01C41A27288FD3EA00BAE31A /* BugsnagDefines.h */, 3A700A8F24A63A8E0068CD1B /* BugsnagDevice.h */, 3A700A9224A63A8E0068CD1B /* BugsnagDeviceWithState.h */, diff --git a/Bugsnag/Client/BugsnagClient.m b/Bugsnag/Client/BugsnagClient.m index dd1200d49..362ac68f2 100644 --- a/Bugsnag/Client/BugsnagClient.m +++ b/Bugsnag/Client/BugsnagClient.m @@ -53,7 +53,6 @@ #import "BugsnagBreadcrumbs.h" #import "BugsnagCollections.h" #import "BugsnagConfiguration+Private.h" -#import "BugsnagCorrelation+Private.h" #import "BugsnagDeviceWithState+Private.h" #import "BugsnagError+Private.h" #import "BugsnagErrorTypes.h" diff --git a/Bugsnag/Payload/BugsnagCorrelation+Private.h b/Bugsnag/Payload/BugsnagCorrelation.h similarity index 54% rename from Bugsnag/Payload/BugsnagCorrelation+Private.h rename to Bugsnag/Payload/BugsnagCorrelation.h index fafd4d181..ac5902987 100644 --- a/Bugsnag/Payload/BugsnagCorrelation+Private.h +++ b/Bugsnag/Payload/BugsnagCorrelation.h @@ -1,19 +1,22 @@ // -// BugsnagCorrelation+Private.h +// BugsnagCorrelation.h // Bugsnag // -// Created by Karl Stenerud on 14.05.24. +// Created by Karl Stenerud on 13.05.24. // Copyright © 2024 Bugsnag Inc. All rights reserved. // -#import "BugsnagCorrelation.h" - -#ifndef BugsnagCorrelation_Private_h -#define BugsnagCorrelation_Private_h +#import +#import NS_ASSUME_NONNULL_BEGIN -@interface BugsnagCorrelation () +BUGSNAG_EXTERN +@interface BugsnagCorrelation: NSObject + +@property (readonly, nonatomic, strong, nullable) NSString *traceId; + +@property (readonly, nonatomic, strong, nullable) NSString *spanId; - (instancetype) initWithTraceId:(NSString * _Nullable) traceId spanId:(NSString * _Nullable)spanId; @@ -24,5 +27,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END - -#endif /* BugsnagCorrelation_Private_h */ diff --git a/Bugsnag/Payload/BugsnagCorrelation.m b/Bugsnag/Payload/BugsnagCorrelation.m index 2eb4254c9..6b7caf2e3 100644 --- a/Bugsnag/Payload/BugsnagCorrelation.m +++ b/Bugsnag/Payload/BugsnagCorrelation.m @@ -6,7 +6,7 @@ // Copyright © 2024 Bugsnag Inc. All rights reserved. // -#import "BugsnagCorrelation+Private.h" +#import "BugsnagCorrelation.h" @implementation BugsnagCorrelation diff --git a/Bugsnag/Payload/BugsnagEvent+Private.h b/Bugsnag/Payload/BugsnagEvent+Private.h index 266e8cd78..72d066094 100644 --- a/Bugsnag/Payload/BugsnagEvent+Private.h +++ b/Bugsnag/Payload/BugsnagEvent+Private.h @@ -9,6 +9,7 @@ #import "BSGDefines.h" #import "BSGFeatureFlagStore.h" #import "BugsnagInternals.h" +#import "BugsnagCorrelation.h" NS_ASSUME_NONNULL_BEGIN @@ -47,6 +48,8 @@ BSG_OBJC_DIRECT_MEMBERS @property (readwrite, nonnull, nonatomic) BugsnagUser *user; +@property (readwrite, nonatomic, strong, nullable) BugsnagCorrelation *correlation; + - (instancetype)initWithKSReport:(NSDictionary *)KSReport; - (instancetype)initWithUserData:(NSDictionary *)event; diff --git a/Bugsnag/Payload/BugsnagEvent.m b/Bugsnag/Payload/BugsnagEvent.m index ede81274a..52dc3aacb 100644 --- a/Bugsnag/Payload/BugsnagEvent.m +++ b/Bugsnag/Payload/BugsnagEvent.m @@ -23,7 +23,6 @@ #import "BugsnagBreadcrumbs.h" #import "BugsnagCollections.h" #import "BugsnagConfiguration+Private.h" -#import "BugsnagCorrelation+Private.h" #import "BugsnagDeviceWithState+Private.h" #import "BugsnagError+Private.h" #import "BugsnagHandledState.h" @@ -545,6 +544,10 @@ - (void)setUser:(NSString *_Nullable)userId self.user = [[BugsnagUser alloc] initWithId:userId name:name emailAddress:email]; } +- (void) setCorrelationTraceId:(NSString *_Nonnull)traceId spanId:(NSString *_Nonnull)spanId { + self.correlation = [[BugsnagCorrelation alloc] initWithTraceId:traceId spanId:spanId]; +} + /** * Read the user from a persisted KSCrash report * @param event the KSCrash report diff --git a/Bugsnag/include/Bugsnag/BugsnagCorrelation.h b/Bugsnag/include/Bugsnag/BugsnagCorrelation.h index e8ffbd329..ac5902987 100644 --- a/Bugsnag/include/Bugsnag/BugsnagCorrelation.h +++ b/Bugsnag/include/Bugsnag/BugsnagCorrelation.h @@ -14,9 +14,15 @@ NS_ASSUME_NONNULL_BEGIN BUGSNAG_EXTERN @interface BugsnagCorrelation: NSObject -@property (readwrite, nonatomic, strong, nullable) NSString *traceId; +@property (readonly, nonatomic, strong, nullable) NSString *traceId; -@property (readwrite, nonatomic, strong, nullable) NSString *spanId; +@property (readonly, nonatomic, strong, nullable) NSString *spanId; + +- (instancetype) initWithTraceId:(NSString * _Nullable) traceId spanId:(NSString * _Nullable)spanId; + +- (instancetype) initWithJsonDictionary:(NSDictionary * _Nullable) dict; + +- (NSDictionary *) toJsonDictionary; @end diff --git a/Bugsnag/include/Bugsnag/BugsnagEvent.h b/Bugsnag/include/Bugsnag/BugsnagEvent.h index e0720e00a..c0a4b7847 100644 --- a/Bugsnag/include/Bugsnag/BugsnagEvent.h +++ b/Bugsnag/include/Bugsnag/BugsnagEvent.h @@ -11,7 +11,6 @@ #import #import #import -#import @class BugsnagConfiguration; @class BugsnagHandledState; @@ -113,8 +112,6 @@ BUGSNAG_EXTERN */ @property (strong, nullable, nonatomic) id originalError; -@property (readwrite, nonatomic, strong, nullable) BugsnagCorrelation *correlation; - // ============================================================================= // MARK: - User // ============================================================================= @@ -135,4 +132,6 @@ BUGSNAG_EXTERN withEmail:(NSString *_Nullable)email andName:(NSString *_Nullable)name; +- (void) setCorrelationTraceId:(NSString *_Nonnull)traceId spanId:(NSString *_Nonnull)spanId; + @end diff --git a/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m b/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m index 10d9ef103..8ec9605ee 100644 --- a/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m +++ b/Tests/BugsnagTests/BugsnagEventPersistLoadTest.m @@ -21,6 +21,7 @@ #import "BugsnagSession+Private.h" #import "BugsnagStackframe.h" #import "BugsnagThread.h" +#import "BugsnagInternals.h" @interface BugsnagEventPersistLoadTest : BSGTestCase @property NSDictionary *eventData; @@ -360,4 +361,26 @@ - (void)testReactNativePromiseRejection { @"JSON representation of event should have the same number of errors / exceptions"); } +- (void)testCorrelationOverride { + NSString *traceId = @"123456789abcdef0123456789abcdef0"; + NSString *spanId = @"fedcba9876543210"; + BugsnagEvent *event = [self generateEventWithOverrides:@{ + @"correlation": @{ + @"traceId": traceId, + @"spanId": spanId, + } + }]; + + XCTAssertEqualObjects(traceId, event.correlation.traceId); + XCTAssertEqualObjects(spanId, event.correlation.spanId); + + traceId = @"fedcba9876543210fedcba9876543210"; + spanId = @"123456789abcdef0"; + [event setCorrelationTraceId:traceId spanId:spanId]; + NSDictionary *dict = [event toJsonWithRedactedKeys:nil]; + event = [[BugsnagEvent alloc] initWithJson:dict]; + XCTAssertEqualObjects(traceId, event.correlation.traceId); + XCTAssertEqualObjects(spanId, event.correlation.spanId); +} + @end From ec66f70c54667942a6347a85a95100c251ebeac0 Mon Sep 17 00:00:00 2001 From: Karl Stenerud Date: Thu, 4 Jul 2024 13:41:39 +0200 Subject: [PATCH 6/6] Release v6.30.0 --- .jazzy.yaml | 4 ++-- Bugsnag.podspec.json | 4 ++-- Bugsnag/Payload/BugsnagNotifier.m | 2 +- BugsnagNetworkRequestPlugin.podspec.json | 6 +++--- CHANGELOG.md | 12 ++++++++++++ Framework/Info.plist | 2 +- Tests/BugsnagTests/Info.plist | 2 +- Tests/TestHost-iOS/Info.plist | 2 +- VERSION | 2 +- 9 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.jazzy.yaml b/.jazzy.yaml index c1cab8809..051ca70b3 100644 --- a/.jazzy.yaml +++ b/.jazzy.yaml @@ -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.29.0/Bugsnag" +github_file_prefix: "https://github.com/bugsnag/bugsnag-cocoa/tree/v6.30.0/Bugsnag" github_url: "https://github.com/bugsnag/bugsnag-cocoa" hide_documentation_coverage: true module: "Bugsnag" -module_version: "6.29.0" +module_version: "6.30.0" objc: true output: "docs" readme: "README.md" diff --git a/Bugsnag.podspec.json b/Bugsnag.podspec.json index 2e5354142..56b984b3f 100644 --- a/Bugsnag.podspec.json +++ b/Bugsnag.podspec.json @@ -1,6 +1,6 @@ { "name": "Bugsnag", - "version": "6.29.0", + "version": "6.30.0", "summary": "The Bugsnag crash reporting framework for Apple platforms.", "homepage": "https://bugsnag.com", "license": "MIT", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.29.0" + "tag": "v6.30.0" }, "ios": { "frameworks": [ diff --git a/Bugsnag/Payload/BugsnagNotifier.m b/Bugsnag/Payload/BugsnagNotifier.m index 6e84d27d0..ef1d791d1 100644 --- a/Bugsnag/Payload/BugsnagNotifier.m +++ b/Bugsnag/Payload/BugsnagNotifier.m @@ -23,7 +23,7 @@ - (instancetype)init { #else _name = @"Bugsnag Objective-C"; #endif - _version = @"6.29.0"; + _version = @"6.30.0"; _url = @"https://github.com/bugsnag/bugsnag-cocoa"; _dependencies = @[]; } diff --git a/BugsnagNetworkRequestPlugin.podspec.json b/BugsnagNetworkRequestPlugin.podspec.json index c8038afd7..247d6721a 100644 --- a/BugsnagNetworkRequestPlugin.podspec.json +++ b/BugsnagNetworkRequestPlugin.podspec.json @@ -1,16 +1,16 @@ { "name": "BugsnagNetworkRequestPlugin", - "version": "6.29.0", + "version": "6.30.0", "summary": "Network request monitoring support for Bugsnag.", "homepage": "https://bugsnag.com", "license": "MIT", "authors": { "Bugsnag": "notifiers@bugsnag.com" }, - "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.29.0/BugsnagNetworkRequestPlugin/README.md", + "readme": "https://raw.githubusercontent.com/bugsnag/bugsnag-cocoa/v6.30.0/BugsnagNetworkRequestPlugin/README.md", "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.29.0" + "tag": "v6.30.0" }, "dependencies": { "Bugsnag": "~> 6.13" diff --git a/CHANGELOG.md b/CHANGELOG.md index ea381eaab..725a31f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ Changelog ========= +## 6.30.0 (2024-07-04) + +### Enhancements + +* Allow setting the correlation trace ID and span ID in an event, and harmonize the API with bugsnag-android. Note: This moves BugsnagCorrelation to a private API, which might cause minor breakage. + [1671](https://github.com/bugsnag/bugsnag-cocoa/pull/1671) + +### Bug Fixes + +* Ensure that all Bugsnag.notifyXYZ and BugsnagClient.notifyXYZ calls strip the correct number of stack frames, regardless of compiler optimization level. + [1668](https://github.com/bugsnag/bugsnag-cocoa/pull/1668) + ## 6.29.0 (2024-06-19) ### Enhancements diff --git a/Framework/Info.plist b/Framework/Info.plist index 2073f3c90..34c3136e1 100644 --- a/Framework/Info.plist +++ b/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.29.0 + 6.30.0 CFBundleVersion 1 diff --git a/Tests/BugsnagTests/Info.plist b/Tests/BugsnagTests/Info.plist index 8f7f2256b..6172fbf46 100644 --- a/Tests/BugsnagTests/Info.plist +++ b/Tests/BugsnagTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.29.0 + 6.30.0 CFBundleVersion 1 diff --git a/Tests/TestHost-iOS/Info.plist b/Tests/TestHost-iOS/Info.plist index 9c8ac151c..c5b1a316f 100644 --- a/Tests/TestHost-iOS/Info.plist +++ b/Tests/TestHost-iOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 6.29.0 + 6.30.0 CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/VERSION b/VERSION index 94ae9e992..137f5acd5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.29.0 +6.30.0