From 760d95314091cde61b794a182023c5b44053a92d Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 26 May 2023 11:00:29 +0200 Subject: [PATCH 01/26] ci: Build most UI tests with Xcode 14 (#3062) As you can only submit apps to the App Store with Xcode 14, there is no need to build all the UI tests with Xcode 13. --- .github/workflows/saucelabs-UI-tests.yml | 25 ++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/saucelabs-UI-tests.yml b/.github/workflows/saucelabs-UI-tests.yml index 3ae2a310a2a..c8a0c869cd4 100644 --- a/.github/workflows/saucelabs-UI-tests.yml +++ b/.github/workflows/saucelabs-UI-tests.yml @@ -24,17 +24,18 @@ on: jobs: build-ui-tests: - name: Build UITests with Xcode ${{matrix.xcode}} - runs-on: ${{matrix.runs-on}} + name: Build UITests + runs-on: ${{ matrix.runs-on }} + strategy: matrix: include: - runs-on: macos-12 xcode: '13.4.1' - - runs-on: macos-12 - xcode: '14.2' - + - runs-on: macos-13 + xcode: '14.3' + steps: - uses: actions/checkout@v3 - run: ./scripts/ci-select-xcode.sh ${{matrix.xcode}} @@ -84,26 +85,26 @@ jobs: path: | **/Test-iphoneos/iOS-Swift.app **/Test-iphoneos/iOS-SwiftUITests-Runner.app - + run-ui-tests-with-sauce: - name: Run UI Tests for iOS ${{ matrix.suite }} on Sauce Labs + name: Run UI Tests for ${{ matrix.suite }} on Sauce Labs runs-on: ubuntu-latest needs: build-ui-tests strategy: fail-fast: false matrix: include: - - xcode: '14.2' + - xcode: '14.3' suite: 'iOS-16' - - xcode: '13.4.1' + - xcode: '14.3' suite: 'iOS-15' # We want to test the frame tracker at 120 fps - - xcode: '13.4.1' + - xcode: '14.3' suite: 'iPhone-Pro' - - xcode: '13.4.1' + - xcode: '14.3' suite: 'iOS-14' - xcode: '13.4.1' @@ -117,7 +118,7 @@ jobs: - uses: actions/download-artifact@v3 with: - name: DerivedData-Xcode-${{matrix.xcode}} + name: DerivedData-Xcode-${{ matrix.xcode }} - run: npm install -g saucectl@0.107.2 From cfb310055c8a8d65272f39af7ae6556e55c42281 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 26 May 2023 11:14:33 +0200 Subject: [PATCH 02/26] build: Update Fastlane to 2.213.0 (#3065) Remove pinned Fastlane version as 2.213.0 contains a possible fix for WWDC certificate error, see https://github.com/fastlane/fastlane/pull/21271. --- .github/workflows/testflight.yml | 1 + Gemfile | 6 +----- Gemfile.lock | 30 ++++++++++++++++-------------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 8732c274a52..1539a609082 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -3,6 +3,7 @@ on: push: branches: - main + paths: - 'Sources/**' - 'Samples/iOS-Swift/**' diff --git a/Gemfile b/Gemfile index 2b072b8cb9b..0767766c40a 100644 --- a/Gemfile +++ b/Gemfile @@ -2,11 +2,7 @@ source "https://rubygems.org" gem "bundler", ">= 2" gem "cocoapods", ">= 1.9.1" -# Pin fastlane to 2.210.1 to avoid CI failure with "Could not install WWDR certificate". -# Although https://github.com/fastlane/fastlane/issues/20960 was fixed with -# https://github.com/fastlane/fastlane/releases/tag/2.212.0 we still see it happening, -# sometimes. We keep pinning to 2.210.1. -gem "fastlane", "= 2.210.1" +gem "fastlane" gem "rest-client" gem "xcpretty" gem "slather" diff --git a/Gemfile.lock b/Gemfile.lock index 8053e7c9413..86c712547a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,11 +3,12 @@ GEM specs: CFPropertyList (3.0.6) rexml - activesupport (7.0.4.3) + activesupport (6.1.7.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) + zeitwerk (~> 2.3) addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) algoliasearch (1.27.5) @@ -16,16 +17,16 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.723.0) - aws-sdk-core (3.170.0) + aws-partitions (1.769.0) + aws-sdk-core (3.173.1) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.63.0) + aws-sdk-kms (1.64.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.119.1) + aws-sdk-s3 (1.122.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -115,8 +116,8 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.6) - fastlane (2.210.1) + fastimage (2.2.7) + fastlane (2.213.0) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -140,7 +141,7 @@ GEM json (< 3.0.0) jwt (>= 2.1.0, < 3) mini_magick (>= 4.9.4, < 5.0.0) - multipart-post (~> 2.0.0) + multipart-post (>= 2.0.0, < 3.0.0) naturally (~> 2.2) optparse (~> 0.1.1) plist (>= 3.1.0, < 4.0.0) @@ -161,7 +162,7 @@ GEM fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.35.0) + google-apis-androidpublisher_v3 (0.42.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) @@ -192,7 +193,7 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.3.0) + googleauth (1.5.2) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -219,12 +220,12 @@ GEM minitest (5.18.0) molinillo (0.8.0) multi_json (1.15.0) - multipart-post (2.0.0) + multipart-post (2.3.0) nanaimo (0.3.0) nap (1.1.0) naturally (2.2.1) netrc (0.11.0) - nokogiri (1.14.3) + nokogiri (1.13.10) mini_portile2 (~> 2.8.0) racc (~> 1.4) optparse (0.1.1) @@ -293,6 +294,7 @@ GEM rouge (~> 2.0.7) xcpretty-travis-formatter (1.0.1) xcpretty (~> 0.2, >= 0.0.7) + zeitwerk (2.6.8) PLATFORMS ruby @@ -300,11 +302,11 @@ PLATFORMS DEPENDENCIES bundler (>= 2) cocoapods (>= 1.9.1) - fastlane (= 2.210.1) + fastlane fastlane-plugin-sentry rest-client slather xcpretty BUNDLED WITH - 2.3.26 + 2.4.7 From b9b0f0a4b268f1ed4b30104486d690931dab63e1 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Fri, 26 May 2023 11:21:22 +0200 Subject: [PATCH 03/26] chore: Remove precommit GH actions check (#3064) The precommit check fails when adding a valid macos-13 as a runner. --- .pre-commit-config.yaml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e0158713b70..19d4206ca97 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,13 +13,6 @@ repos: - id: end-of-file-fixer - id: no-commit-to-branch - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.23.0 - hooks: - - id: check-github-actions - - id: check-github-workflows - args: [--verbose] - - repo: local hooks: - id: format-clang From ed37eea52b7bb06a35b4d9958182f89a19e0c609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 13:20:30 +0200 Subject: [PATCH 04/26] build(deps): bump github/codeql-action from 2.3.3 to 2.3.5 (#3070) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.3.3 to 2.3.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/29b1f65c5e92e24fe6b6647da1eaabe529cec70f...0225834cc549ee0ca93cb085b92954821a145866) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e0fbb4c9379..28ec27eadea 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 - name: Initialize CodeQL - uses: github/codeql-action/init@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # pin@v2 + uses: github/codeql-action/init@0225834cc549ee0ca93cb085b92954821a145866 # pin@v2 with: languages: ${{ matrix.language }} @@ -37,4 +37,4 @@ jobs: -destination platform="iOS Simulator,OS=latest,name=iPhone 11 Pro" | xcpretty && exit ${PIPESTATUS[0]} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@29b1f65c5e92e24fe6b6647da1eaabe529cec70f # pin@v2 + uses: github/codeql-action/analyze@0225834cc549ee0ca93cb085b92954821a145866 # pin@v2 From 23e2db585acfb0529c726619e2d6e8acd020f487 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 May 2023 14:47:53 +0200 Subject: [PATCH 05/26] fix: Change Trace serialized value type of sampled (#3067) Changed the sampled value of the trace in the envelope from String to Bool. Co-authored-by: Philipp Hofmann --- CHANGELOG.md | 10 ++++++++++ Sentry.xcodeproj/project.pbxproj | 2 ++ Sources/Sentry/Public/SentrySampleDecision.h | 14 -------------- Sources/Sentry/SentrySampleDecision.m | 14 +++++--------- Sources/Sentry/SentrySpan.m | 3 ++- Sources/Sentry/SentrySpanContext.m | 3 ++- .../Sentry/include/SentrySampleDecision+Private.h | 6 ++++++ Tests/SentryTests/SentryTests-Bridging-Header.h | 1 + .../Transaction/SentrySpanContextTests.swift | 10 +++++----- .../SentryTests/Transaction/SentrySpanTests.swift | 4 ++-- .../SentryTransactionContextTests.swift | 2 +- 11 files changed, 36 insertions(+), 33 deletions(-) create mode 100644 Sources/Sentry/include/SentrySampleDecision+Private.h diff --git a/CHANGELOG.md b/CHANGELOG.md index a0ca7c7af15..1de5f182ec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## Unreleased + +### Breaking Changes + +- Removed `nameForSentrySampleDecision` which shouldn't have been public (#3067) + +### Fixes + +- Changed `Trace` serialized value of `sampled` from string to boolean (#3067) + ## 8.7.3 ### Fixes diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 1baa1a8b046..921b835f594 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -1691,6 +1691,7 @@ D86B6834294348A400B8B1FC /* SentryAttachment+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryAttachment+Private.h"; path = "include/SentryAttachment+Private.h"; sourceTree = ""; }; D86F419727C8FEFA00490520 /* SentryCoreDataMiddleware+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SentryCoreDataMiddleware+Extension.swift"; sourceTree = ""; }; D8751FA4274743710032F4DE /* SentryNSURLSessionTaskSearchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSURLSessionTaskSearchTests.swift; sourceTree = ""; }; + D8757D142A209F7300BFEFCC /* SentrySampleDecision+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentrySampleDecision+Private.h"; path = "include/SentrySampleDecision+Private.h"; sourceTree = ""; }; D875ED0A276CC84700422FAC /* SentryNSDataTrackerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryNSDataTrackerTests.swift; sourceTree = ""; }; D880E3A628573E87008A90DB /* SentryBaggageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryBaggageTests.swift; sourceTree = ""; }; D880E3B02860A5A0008A90DB /* SentryEvent+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SentryEvent+Private.h"; path = "include/SentryEvent+Private.h"; sourceTree = ""; }; @@ -3195,6 +3196,7 @@ 8E8C57A525EEFC42001CEEFA /* SentryTracesSampler.h */, 8E8C57A025EEFC07001CEEFA /* SentryTracesSampler.m */, 8E4A037725F6F52100000D77 /* SentrySampleDecision.h */, + D8757D142A209F7300BFEFCC /* SentrySampleDecision+Private.h */, 8453421128BE855D00C22EEC /* SentrySampleDecision.m */, 8E7C98302693E1CC00E6336C /* SentryTraceHeader.h */, 8E7C982D2693D56000E6336C /* SentryTraceHeader.m */, diff --git a/Sources/Sentry/Public/SentrySampleDecision.h b/Sources/Sentry/Public/SentrySampleDecision.h index 31a0dc79c38..4d20d847a90 100644 --- a/Sources/Sentry/Public/SentrySampleDecision.h +++ b/Sources/Sentry/Public/SentrySampleDecision.h @@ -19,17 +19,3 @@ typedef NS_ENUM(NSUInteger, SentrySampleDecision) { */ kSentrySampleDecisionNo }; - -static DEPRECATED_MSG_ATTRIBUTE("Use nameForSentrySampleDecision() instead.") - NSString *_Nonnull const SentrySampleDecisionNames[] - = { @"undecided", @"true", @"false" }; - -NS_ASSUME_NONNULL_BEGIN - -FOUNDATION_EXPORT NSString *const kSentrySampleDecisionNameUndecided; -FOUNDATION_EXPORT NSString *const kSentrySampleDecisionNameYes; -FOUNDATION_EXPORT NSString *const kSentrySampleDecisionNameNo; - -NSString *nameForSentrySampleDecision(SentrySampleDecision decision); - -NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentrySampleDecision.m b/Sources/Sentry/SentrySampleDecision.m index bc1b6107390..20f6642e48e 100644 --- a/Sources/Sentry/SentrySampleDecision.m +++ b/Sources/Sentry/SentrySampleDecision.m @@ -1,18 +1,14 @@ #import "SentrySampleDecision.h" -NSString *const kSentrySampleDecisionNameUndecided = @"undecided"; -NSString *const kSentrySampleDecisionNameYes = @"true"; -NSString *const kSentrySampleDecisionNameNo = @"false"; - -NSString * -nameForSentrySampleDecision(SentrySampleDecision decision) +NSNumber * +valueForSentrySampleDecision(SentrySampleDecision decision) { switch (decision) { case kSentrySampleDecisionUndecided: - return kSentrySampleDecisionNameUndecided; + return nil; case kSentrySampleDecisionYes: - return kSentrySampleDecisionNameYes; + return @YES; case kSentrySampleDecisionNo: - return kSentrySampleDecisionNameNo; + return @NO; } } diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 0b5a84e00ab..c5ed9c6ec77 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -7,6 +7,7 @@ #import "SentryLog.h" #import "SentryMeasurementValue.h" #import "SentryNoOpSpan.h" +#import "SentrySampleDecision+Private.h" #import "SentrySerializable.h" #import "SentrySpanContext.h" #import "SentrySpanId.h" @@ -184,7 +185,7 @@ - (NSDictionary *)serialize // Since we guard for 'undecided', we'll // either send it if it's 'true' or 'false'. if (self.sampled != kSentrySampleDecisionUndecided) { - [mutableDictionary setValue:nameForSentrySampleDecision(self.sampled) forKey:@"sampled"]; + [mutableDictionary setValue:valueForSentrySampleDecision(self.sampled) forKey:@"sampled"]; } if (self.spanDescription != nil) { diff --git a/Sources/Sentry/SentrySpanContext.m b/Sources/Sentry/SentrySpanContext.m index f5ea0fa649b..8f33b3667ae 100644 --- a/Sources/Sentry/SentrySpanContext.m +++ b/Sources/Sentry/SentrySpanContext.m @@ -1,6 +1,7 @@ #import "SentrySpanContext.h" #import "SentryId.h" #import "SentryLog.h" +#import "SentrySampleDecision+Private.h" #import "SentrySpanId.h" #import "SentryTraceOrigins.h" @@ -108,7 +109,7 @@ - (instancetype)initWithTraceId:(SentryId *)traceId // Since we guard for 'undecided', we'll // either send it if it's 'true' or 'false'. if (self.sampled != kSentrySampleDecisionUndecided) { - [mutabledictionary setValue:nameForSentrySampleDecision(self.sampled) forKey:@"sampled"]; + [mutabledictionary setValue:valueForSentrySampleDecision(self.sampled) forKey:@"sampled"]; } if (self.spanDescription != nil) { diff --git a/Sources/Sentry/include/SentrySampleDecision+Private.h b/Sources/Sentry/include/SentrySampleDecision+Private.h new file mode 100644 index 00000000000..93e781ec8e0 --- /dev/null +++ b/Sources/Sentry/include/SentrySampleDecision+Private.h @@ -0,0 +1,6 @@ +#import + +/** + Returns the value to use when serializing a SentrySampleDecision. + */ +NSNumber *valueForSentrySampleDecision(SentrySampleDecision decision); diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 1decb6f59f7..5013c9979ce 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -193,6 +193,7 @@ #import "SentryMeasurementValue.h" #import "SentryNSProcessInfoWrapper.h" #import "SentryPerformanceTracker+Testing.h" +#import "SentrySampleDecision+Private.h" #import "SentrySpanOperations.h" #import "SentryTimeToDisplayTracker.h" #import "SentryTracerConfiguration.h" diff --git a/Tests/SentryTests/Transaction/SentrySpanContextTests.swift b/Tests/SentryTests/Transaction/SentrySpanContextTests.swift index 9083e2dbc98..f62d7d240d8 100644 --- a/Tests/SentryTests/Transaction/SentrySpanContextTests.swift +++ b/Tests/SentryTests/Transaction/SentrySpanContextTests.swift @@ -52,7 +52,7 @@ class SentrySpanContextTests: XCTestCase { XCTAssertEqual(data["type"] as? String, SENTRY_TRACE_TYPE) XCTAssertEqual(data["op"] as? String, someOperation) XCTAssertEqual(data["description"] as? String, spanContext.spanDescription) - XCTAssertEqual(data["sampled"] as? String, "true") + XCTAssertEqual(data["sampled"] as? NSNumber, true) XCTAssertEqual(data["parent_span_id"] as? String, parentId.sentrySpanIdString) } @@ -68,9 +68,9 @@ class SentrySpanContextTests: XCTestCase { } func testSamplerDecisionNames() { - XCTAssertEqual(kSentrySampleDecisionNameUndecided, nameForSentrySampleDecision(.undecided)) - XCTAssertEqual(kSentrySampleDecisionNameNo, nameForSentrySampleDecision(.no)) - XCTAssertEqual(kSentrySampleDecisionNameYes, nameForSentrySampleDecision(.yes)) + XCTAssertNil(valueForSentrySampleDecision(.undecided)) + XCTAssertFalse(valueForSentrySampleDecision(.no).boolValue) + XCTAssertTrue(valueForSentrySampleDecision(.yes).boolValue) } func testSampledNoSerialization() { @@ -82,7 +82,7 @@ class SentrySpanContextTests: XCTestCase { let data = spanContext.serialize() - XCTAssertEqual(data["sampled"] as? String, "false") + XCTAssertEqual(data["sampled"] as? NSNumber, false) } func testSampleUndecidedSerialization() { diff --git a/Tests/SentryTests/Transaction/SentrySpanTests.swift b/Tests/SentryTests/Transaction/SentrySpanTests.swift index 10998d7e19c..635327a07ff 100644 --- a/Tests/SentryTests/Transaction/SentrySpanTests.swift +++ b/Tests/SentryTests/Transaction/SentrySpanTests.swift @@ -230,11 +230,11 @@ class SentrySpanTests: XCTestCase { XCTAssertEqual(serialization["op"] as? String, span.operation) XCTAssertEqual(serialization["description"] as? String, span.spanDescription) XCTAssertEqual(serialization["status"] as? String, nameForSentrySpanStatus(span.status)) - XCTAssertEqual(serialization["sampled"] as? String, nameForSentrySampleDecision(span.sampled)) + XCTAssertEqual(serialization["sampled"] as? NSNumber, valueForSentrySampleDecision(span.sampled)) XCTAssertEqual(serialization["timestamp"] as? TimeInterval, TestData.timestamp.timeIntervalSince1970) XCTAssertEqual(serialization["start_timestamp"] as? TimeInterval, TestData.timestamp.timeIntervalSince1970) XCTAssertEqual(serialization["type"] as? String, SENTRY_TRACE_TYPE) - XCTAssertEqual(serialization["sampled"] as? String, "true") + XCTAssertEqual(serialization["sampled"] as? NSNumber, true) XCTAssertNotNil(serialization["data"]) XCTAssertNotNil(serialization["tags"]) XCTAssertEqual((serialization["data"] as! Dictionary)[fixture.extraKey], fixture.extraValue) diff --git a/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift b/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift index eff73819574..aa62d71ee38 100644 --- a/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift +++ b/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift @@ -87,7 +87,7 @@ class SentryTransactionContextTests: XCTestCase { XCTAssertEqual(context.origin, actual["origin"] as? String) XCTAssertEqual(context.parentSpanId?.sentrySpanIdString, actual["parent_span_id"] as? String) XCTAssertEqual("trace", actual["type"] as? String) - XCTAssertEqual("true", actual["sampled"] as? String) + XCTAssertEqual(true, actual["sampled"] as? NSNumber) XCTAssertEqual("ui.load", actual["op"] as? String) XCTAssertNotNil(actual) From f797112d058b8306b76e7d0ccb8b3d5b8427f876 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 May 2023 14:49:17 +0200 Subject: [PATCH 06/26] Fix: Duplicated HTTP breadcrumbs (#3058) Prevent HTTP breadcrumbs to duplicate --- CHANGELOG.md | 9 +++++---- Sources/Sentry/SentryNetworkTracker.m | 18 +++++++++++++----- Sources/Sentry/include/SentryNetworkTracker.h | 2 ++ .../Network/SentryNetworkTrackerTests.swift | 16 ++++++++++++++++ scripts/no-changes-in-high-risk-files.sh | 2 +- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1de5f182ec0..7ab89b45c19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,14 @@ ## Unreleased -### Breaking Changes - -- Removed `nameForSentrySampleDecision` which shouldn't have been public (#3067) - ### Fixes - Changed `Trace` serialized value of `sampled` from string to boolean (#3067) +- Duplicated HTTP breadcrumbs (#3058) + +### Breaking Changes + +- Removed `nameForSentrySampleDecision` which shouldn't have been public (#3067) ## 8.7.3 diff --git a/Sources/Sentry/SentryNetworkTracker.m b/Sources/Sentry/SentryNetworkTracker.m index dd01b2f0ac3..d9423e3bb14 100644 --- a/Sources/Sentry/SentryNetworkTracker.m +++ b/Sources/Sentry/SentryNetworkTracker.m @@ -2,6 +2,7 @@ #import "SentryBaggage.h" #import "SentryBreadcrumb.h" #import "SentryClient+Private.h" +#import "SentryDSN.h" #import "SentryEvent.h" #import "SentryException.h" #import "SentryHttpStatusCodeRange+Private.h" @@ -136,7 +137,7 @@ - (void)urlSessionTaskResume:(NSURLSessionTask *)sessionTask } // Don't measure requests to Sentry's backend - NSURL *apiUrl = [NSURL URLWithString:SentrySDK.options.dsn]; + NSURL *apiUrl = SentrySDK.options.parsedDsn.url; if ([url.host isEqualToString:apiUrl.host] && [url.path containsString:apiUrl.path]) { return; } @@ -259,7 +260,7 @@ - (void)urlSessionTask:(NSURLSessionTask *)sessionTask setState:(NSURLSessionTas } // Don't measure requests to Sentry's backend - NSURL *apiUrl = [NSURL URLWithString:SentrySDK.options.dsn]; + NSURL *apiUrl = SentrySDK.options.parsedDsn.url; if ([url.host isEqualToString:apiUrl.host] && [url.path containsString:apiUrl.path]) { return; } @@ -418,6 +419,13 @@ - (void)addBreadcrumbForSessionTask:(NSURLSessionTask *)sessionTask return; } + id hasBreadcrumb + = objc_getAssociatedObject(sessionTask, &SENTRY_NETWORK_REQUEST_TRACKER_BREADCRUMB); + if (hasBreadcrumb && [hasBreadcrumb isKindOfClass:NSNumber.class] && + [hasBreadcrumb boolValue]) { + return; + } + SentryLevel breadcrumbLevel = sessionTask.error != nil ? kSentryLevelError : kSentryLevelInfo; SentryBreadcrumb *breadcrumb = [[SentryBreadcrumb alloc] initWithLevel:breadcrumbLevel category:@"http"]; @@ -429,18 +437,18 @@ - (void)addBreadcrumbForSessionTask:(NSURLSessionTask *)sessionTask [NSNumber numberWithLongLong:sessionTask.countOfBytesSent]; breadcrumbData[@"response_body_size"] = [NSNumber numberWithLongLong:sessionTask.countOfBytesReceived]; - NSInteger responseStatusCode = [self urlResponseStatusCode:sessionTask.response]; - if (responseStatusCode != -1) { NSNumber *statusCode = [NSNumber numberWithInteger:responseStatusCode]; breadcrumbData[@"status_code"] = statusCode; breadcrumbData[@"reason"] = [NSHTTPURLResponse localizedStringForStatusCode:responseStatusCode]; } - breadcrumb.data = breadcrumbData; [SentrySDK addBreadcrumb:breadcrumb]; + + objc_setAssociatedObject(sessionTask, &SENTRY_NETWORK_REQUEST_TRACKER_BREADCRUMB, + [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSInteger)urlResponseStatusCode:(NSURLResponse *)response diff --git a/Sources/Sentry/include/SentryNetworkTracker.h b/Sources/Sentry/include/SentryNetworkTracker.h index 4b48aa185c9..237e55dbd43 100644 --- a/Sources/Sentry/include/SentryNetworkTracker.h +++ b/Sources/Sentry/include/SentryNetworkTracker.h @@ -6,6 +6,8 @@ NS_ASSUME_NONNULL_BEGIN static NSString *const SENTRY_NETWORK_REQUEST_OPERATION = @"http.client"; static NSString *const SENTRY_NETWORK_REQUEST_TRACKER_SPAN = @"SENTRY_NETWORK_REQUEST_TRACKER_SPAN"; +static NSString *const SENTRY_NETWORK_REQUEST_TRACKER_BREADCRUMB + = @"SENTRY_NETWORK_REQUEST_TRACKER_BREADCRUMB"; @interface SentryNetworkTracker : NSObject diff --git a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift index 28d7047cd99..623b1e8b372 100644 --- a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift @@ -370,6 +370,22 @@ class SentryNetworkTrackerTests: XCTestCase { XCTAssertEqual(breadcrumb!.data!["url"] as! String, SentryNetworkTrackerTests.testURL.absoluteString) XCTAssertEqual(breadcrumb!.data!["method"] as! String, "GET") } + + func testNoDuplicatedBreadcrumbs() { + let task = createDataTask() + let _ = spanForTask(task: task)! + + objc_removeAssociatedObjects(task) + + setTaskState(task, state: .completed) + setTaskState(task, state: .running) + setTaskState(task, state: .completed) + + let breadcrumbs = Dynamic(fixture.scope).breadcrumbArray as [Breadcrumb]? + let amount = breadcrumbs?.count ?? 0 + + XCTAssertEqual(amount, 1) + } func testWhenNoSpan_RemoveObserver() { let task = createDataTask() diff --git a/scripts/no-changes-in-high-risk-files.sh b/scripts/no-changes-in-high-risk-files.sh index 393d0475424..b14d595eca3 100755 --- a/scripts/no-changes-in-high-risk-files.sh +++ b/scripts/no-changes-in-high-risk-files.sh @@ -5,7 +5,7 @@ set -euo pipefail ACTUAL=$(shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m ./Sources/Sentry/SentryNetworkTracker.m ./Sources/Sentry/SentryUIViewControllerSwizzling.m ./Sources/Sentry/SentryNSDataSwizzling.m ./Sources/Sentry/SentrySubClassFinder.m ./Sources/Sentry/SentryCoreDataSwizzling.m ./Sources/Sentry/SentrySwizzleWrapper.m ./Sources/Sentry/include/SentrySwizzle.h ./Sources/Sentry/SentrySwizzle.m) EXPECTED="819d5ca5e3db2ac23c859b14c149b7f0754d3ae88bea1dba92c18f49a81da0e1 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m -84638ff38045afd8d145b9b4f42a4379296477b64be4b2f51a7e963417fbdc8a ./Sources/Sentry/SentryNetworkTracker.m +468d7922f2e3b720d95dcb77e08075f2f796a03a027b59da2d03faaa6a76f845 ./Sources/Sentry/SentryNetworkTracker.m 52cb473dcc8d13c0d4f6cd1429c3fc6e8588521660b714f4a2edb4eaf1401e9f ./Sources/Sentry/SentryUIViewControllerSwizzling.m e95e62ec7363984f20c78643bb7d992a41a740f97e1befb71525ac34caf88b37 ./Sources/Sentry/SentryNSDataSwizzling.m 9ad05dd8dd29788cba994736fdcd3bbde59a94e32612640d11f4f9c38ad6610e ./Sources/Sentry/SentrySubClassFinder.m From 4bdf3dcddf051263f02fc176f726bf663fc8fd27 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 May 2023 16:02:24 +0200 Subject: [PATCH 07/26] Update no-changes-in-high-risk-files.sh (#3073) --- scripts/no-changes-in-high-risk-files.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/no-changes-in-high-risk-files.sh b/scripts/no-changes-in-high-risk-files.sh index b14d595eca3..43b39152bfc 100755 --- a/scripts/no-changes-in-high-risk-files.sh +++ b/scripts/no-changes-in-high-risk-files.sh @@ -5,7 +5,7 @@ set -euo pipefail ACTUAL=$(shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m ./Sources/Sentry/SentryNetworkTracker.m ./Sources/Sentry/SentryUIViewControllerSwizzling.m ./Sources/Sentry/SentryNSDataSwizzling.m ./Sources/Sentry/SentrySubClassFinder.m ./Sources/Sentry/SentryCoreDataSwizzling.m ./Sources/Sentry/SentrySwizzleWrapper.m ./Sources/Sentry/include/SentrySwizzle.h ./Sources/Sentry/SentrySwizzle.m) EXPECTED="819d5ca5e3db2ac23c859b14c149b7f0754d3ae88bea1dba92c18f49a81da0e1 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m -468d7922f2e3b720d95dcb77e08075f2f796a03a027b59da2d03faaa6a76f845 ./Sources/Sentry/SentryNetworkTracker.m +fa37af7d82e22f1d3821b543aa6f284ef6c2d2e7eb1df364daf7a3d71cf1e479 ./Sources/Sentry/SentryNetworkTracker.m 52cb473dcc8d13c0d4f6cd1429c3fc6e8588521660b714f4a2edb4eaf1401e9f ./Sources/Sentry/SentryUIViewControllerSwizzling.m e95e62ec7363984f20c78643bb7d992a41a740f97e1befb71525ac34caf88b37 ./Sources/Sentry/SentryNSDataSwizzling.m 9ad05dd8dd29788cba994736fdcd3bbde59a94e32612640d11f4f9c38ad6610e ./Sources/Sentry/SentrySubClassFinder.m From 154f7957aeae4eb52783f77fc0308786bd528eab Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Tue, 30 May 2023 16:55:59 +0200 Subject: [PATCH 08/26] feat: Experimental support for Swift Async stacktraces (#3051) Adds support for stitching async Swift Concurrency frames using backtrace_async Co-authored-by: Philipp Hofmann --- .github/workflows/test.yml | 8 --- CHANGELOG.md | 4 ++ Sentry.xcodeproj/project.pbxproj | 16 +++-- Sources/Sentry/Public/SentryOptions.h | 6 ++ Sources/Sentry/SentryOptions.m | 7 ++- Sources/Sentry/SentrySwiftAsyncIntegration.m | 17 ++++++ .../include/SentrySwiftAsyncIntegration.h | 11 ++++ .../Tools/SentryCrashStackCursor_SelfThread.h | 2 + ....c => SentryCrashStackCursor_SelfThread.m} | 25 ++++++++ .../SentryStacktraceBuilderTests.swift | 58 ++++++++++++++++++- Tests/SentryTests/SentryOptionsTest.m | 22 ++++++- 11 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 Sources/Sentry/SentrySwiftAsyncIntegration.m create mode 100644 Sources/Sentry/include/SentrySwiftAsyncIntegration.h rename Sources/SentryCrash/Recording/Tools/{SentryCrashStackCursor_SelfThread.c => SentryCrashStackCursor_SelfThread.m} (75%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1c6cdc8577b..4573b93cf3f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -130,14 +130,6 @@ jobs: xcode: '14.3' test-destination-os: 'latest' - # MetricKit doesn't exist for tvOS, so we can still run unit tests with - # Xcode 12 for it. - # tvOS 14 - - runs-on: macos-11 - platform: 'tvOS' - xcode: '12.5.1' - test-destination-os: 'latest' - # tvOS 15 - runs-on: macos-12 platform: 'tvOS' diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab89b45c19..b12e25c374a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- Experimental support for Swift Async stacktraces (#3051) + ### Fixes - Changed `Trace` serialized value of `sampled` from string to boolean (#3067) diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 921b835f594..81d45caaa4f 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -190,7 +190,7 @@ 63FE710120DA4C1000CDBAE8 /* SentryCrashDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */; }; 63FE710320DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */; }; 63FE710520DA4C1000CDBAE8 /* SentryCrashLogger.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700920DA4C1000CDBAE8 /* SentryCrashLogger.c */; }; - 63FE710720DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.c */; }; + 63FE710720DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.m */; }; 63FE710920DA4C1000CDBAE8 /* SentryCrashFileUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700B20DA4C1000CDBAE8 /* SentryCrashFileUtils.h */; }; 63FE710B20DA4C1000CDBAE8 /* SentryCrashMach.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700C20DA4C1000CDBAE8 /* SentryCrashMach.c */; }; 63FE710D20DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700D20DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.c */; }; @@ -742,6 +742,8 @@ D8370B6C273DF20F00F66E2D /* SentryNSURLSessionTaskSearch.h in Headers */ = {isa = PBXBuildFile; fileRef = D8370B6B273DF20F00F66E2D /* SentryNSURLSessionTaskSearch.h */; }; D84793262788737D00BE8E99 /* SentryByteCountFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = D84793242788737D00BE8E99 /* SentryByteCountFormatter.m */; }; D8479328278873A100BE8E99 /* SentryByteCountFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = D8479327278873A100BE8E99 /* SentryByteCountFormatter.h */; }; + D84F833D2A1CC401005828E0 /* SentrySwiftAsyncIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D84F833B2A1CC401005828E0 /* SentrySwiftAsyncIntegration.h */; }; + D84F833E2A1CC401005828E0 /* SentrySwiftAsyncIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = D84F833C2A1CC401005828E0 /* SentrySwiftAsyncIntegration.m */; }; D85596F3280580F10041FF8B /* SentryScreenshotIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = D85596F1280580F10041FF8B /* SentryScreenshotIntegration.m */; }; D855AD62286ED6A4002573E1 /* SentryCrashTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D855AD61286ED6A4002573E1 /* SentryCrashTests.m */; }; D855B3E827D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D855B3E727D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift */; }; @@ -1060,7 +1062,7 @@ 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashDate.h; sourceTree = ""; }; 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMachineContext_Apple.h; sourceTree = ""; }; 63FE700920DA4C1000CDBAE8 /* SentryCrashLogger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashLogger.c; sourceTree = ""; }; - 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashStackCursor_SelfThread.c; sourceTree = ""; }; + 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentryCrashStackCursor_SelfThread.m; sourceTree = ""; }; 63FE700B20DA4C1000CDBAE8 /* SentryCrashFileUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashFileUtils.h; sourceTree = ""; }; 63FE700C20DA4C1000CDBAE8 /* SentryCrashMach.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMach.c; sourceTree = ""; }; 63FE700D20DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashStackCursor_MachineContext.c; sourceTree = ""; }; @@ -1671,6 +1673,8 @@ D8370B6B273DF20F00F66E2D /* SentryNSURLSessionTaskSearch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryNSURLSessionTaskSearch.h; path = include/SentryNSURLSessionTaskSearch.h; sourceTree = ""; }; D84793242788737D00BE8E99 /* SentryByteCountFormatter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryByteCountFormatter.m; sourceTree = ""; }; D8479327278873A100BE8E99 /* SentryByteCountFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryByteCountFormatter.h; path = include/SentryByteCountFormatter.h; sourceTree = ""; }; + D84F833B2A1CC401005828E0 /* SentrySwiftAsyncIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySwiftAsyncIntegration.h; path = include/SentrySwiftAsyncIntegration.h; sourceTree = ""; }; + D84F833C2A1CC401005828E0 /* SentrySwiftAsyncIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySwiftAsyncIntegration.m; sourceTree = ""; }; D85596F1280580F10041FF8B /* SentryScreenshotIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryScreenshotIntegration.m; sourceTree = ""; }; D855AD61286ED6A4002573E1 /* SentryCrashTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashTests.m; sourceTree = ""; }; D855B3E727D652AF00BCED76 /* SentryCoreDataTrackingIntegrationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCoreDataTrackingIntegrationTest.swift; sourceTree = ""; }; @@ -2436,7 +2440,7 @@ 63FE702B20DA4C1000CDBAE8 /* SentryCrashStackCursor_Backtrace.h */, 63FE700D20DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.c */, 63FE703120DA4C1000CDBAE8 /* SentryCrashStackCursor_MachineContext.h */, - 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.c */, + 63FE700A20DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.m */, 63FE702620DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.h */, 63FE703B20DA4C1000CDBAE8 /* SentryCrashStackCursor.c */, 63FE701C20DA4C1000CDBAE8 /* SentryCrashStackCursor.h */, @@ -2799,6 +2803,8 @@ 7BCFBD6E2681D0EE00BC27D8 /* SentryCrashScopeObserver.m */, 7B96571F26830C9100C66E25 /* SentryScopeSyncC.h */, 7B96572126830D2400C66E25 /* SentryScopeSyncC.c */, + D84F833B2A1CC401005828E0 /* SentrySwiftAsyncIntegration.h */, + D84F833C2A1CC401005828E0 /* SentrySwiftAsyncIntegration.m */, ); name = SentryCrash; sourceTree = ""; @@ -3445,6 +3451,7 @@ 7B98D7E425FB7A7200C5A389 /* SentryAppState.h in Headers */, 7BDEAA022632A4580001EA25 /* SentryOptions+Private.h in Headers */, A8AFFCCD29069C3E00967CD7 /* SentryHttpStatusCodeRange.h in Headers */, + D84F833D2A1CC401005828E0 /* SentrySwiftAsyncIntegration.h in Headers */, 15E0A8EA240F2C9000F044E3 /* SentrySerialization.h in Headers */, 63FE70EF20DA4C1000CDBAE8 /* SentryCrashMonitor_AppState.h in Headers */, 635B3F381EBC6E2500A6176D /* SentryAsynchronousOperation.h in Headers */, @@ -3898,6 +3905,7 @@ 7B8713B426415BAA006D6004 /* SentryAppStartTracker.m in Sources */, 7BDB03BB2513652900BAE198 /* SentryDispatchQueueWrapper.m in Sources */, 7B6C5EDE264E8DF00010D138 /* SentryFramesTracker.m in Sources */, + D84F833E2A1CC401005828E0 /* SentrySwiftAsyncIntegration.m in Sources */, 7B6438AB26A70F24000D0F65 /* UIViewController+Sentry.m in Sources */, 63AA76A31EB9CBAA00D153DE /* SentryDsn.m in Sources */, 63B818FA1EC34639002FDF4C /* SentryDebugMeta.m in Sources */, @@ -3974,7 +3982,7 @@ D8F6A2472885512100320515 /* SentryPredicateDescriptor.m in Sources */, A839D89A24864BA8003B7AFD /* SentrySystemEventBreadcrumbs.m in Sources */, 7D082B8323C628790029866B /* SentryMeta.m in Sources */, - 63FE710720DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.c in Sources */, + 63FE710720DA4C1000CDBAE8 /* SentryCrashStackCursor_SelfThread.m in Sources */, 63FE711120DA4C1000CDBAE8 /* SentryCrashDebug.c in Sources */, 7B883F49253D714C00879E62 /* SentryCrashUUIDConversion.c in Sources */, 63FE716720DA4C1100CDBAE8 /* SentryCrashCPU.c in Sources */, diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index 2b01121621b..64a8a6ac320 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -482,6 +482,12 @@ NS_SWIFT_NAME(Options) */ @property (nonatomic) BOOL enableTimeToFullDisplay; +/** + * @warning This is an experimental feature and may still have bugs. + * @brief Stitches the call to Swift Async functions in one consecutive stack trace. + * @note Default value is @c NO . + */ +@property (nonatomic, assign) BOOL swiftAsyncStacktraces; @end NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index bae6a901f97..8e056f0d6d1 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -43,7 +43,8 @@ - (void)setMeasurement:(SentryMeasurementValue *)measurement @"SentryAutoBreadcrumbTrackingIntegration", @"SentryAutoSessionTrackingIntegration", @"SentryAppStartTrackingIntegration", @"SentryWatchdogTerminationTrackingIntegration", @"SentryPerformanceTrackingIntegration", @"SentryNetworkTrackingIntegration", - @"SentryFileIOTrackingIntegration", @"SentryCoreDataTrackingIntegration" + @"SentryFileIOTrackingIntegration", @"SentryCoreDataTrackingIntegration", + @"SentrySwiftAsyncIntegration" ] .mutableCopy; @@ -106,6 +107,7 @@ - (instancetype)init self.enableCoreDataTracing = YES; _enableSwizzling = YES; self.sendClientReports = YES; + self.swiftAsyncStacktraces = NO; #if TARGET_OS_OSX NSString *dsn = [[[NSProcessInfo processInfo] environment] objectForKey:@"SENTRY_DSN"]; @@ -315,6 +317,9 @@ - (BOOL)validateOptions:(NSDictionary *)options [self setBool:options[@"enableWatchdogTerminationTracking"] block:^(BOOL value) { self->_enableWatchdogTerminationTracking = value; }]; + [self setBool:options[@"swiftAsyncStacktraces"] + block:^(BOOL value) { self->_swiftAsyncStacktraces = value; }]; + if ([options[@"sessionTrackingIntervalMillis"] isKindOfClass:[NSNumber class]]) { self.sessionTrackingIntervalMillis = [options[@"sessionTrackingIntervalMillis"] unsignedIntValue]; diff --git a/Sources/Sentry/SentrySwiftAsyncIntegration.m b/Sources/Sentry/SentrySwiftAsyncIntegration.m new file mode 100644 index 00000000000..4b3577fb553 --- /dev/null +++ b/Sources/Sentry/SentrySwiftAsyncIntegration.m @@ -0,0 +1,17 @@ +#import "SentrySwiftAsyncIntegration.h" +#import "SentryCrashStackCursor_SelfThread.h" + +@implementation SentrySwiftAsyncIntegration + +- (BOOL)installWithOptions:(nonnull SentryOptions *)options +{ + sentrycrashsc_setSwiftAsyncStitching(options.swiftAsyncStacktraces); + return options.swiftAsyncStacktraces; +} + +- (void)uninstall +{ + sentrycrashsc_setSwiftAsyncStitching(NO); +} + +@end diff --git a/Sources/Sentry/include/SentrySwiftAsyncIntegration.h b/Sources/Sentry/include/SentrySwiftAsyncIntegration.h new file mode 100644 index 00000000000..f180b500403 --- /dev/null +++ b/Sources/Sentry/include/SentrySwiftAsyncIntegration.h @@ -0,0 +1,11 @@ +#import "SentryBaseIntegration.h" +#import "SentryIntegrationProtocol.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SentrySwiftAsyncIntegration : SentryBaseIntegration + +@end + +NS_ASSUME_NONNULL_END diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h b/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h index 46b4d679bca..e4ad9232ee5 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.h @@ -42,6 +42,8 @@ extern "C" { */ void sentrycrashsc_initSelfThread(SentryCrashStackCursor *cursor, int skipEntries); +void sentrycrashsc_setSwiftAsyncStitching(bool enabled); + #ifdef __cplusplus } #endif diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c b/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.m similarity index 75% rename from Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c rename to Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.m index 0f827a38015..13c47e1e0c3 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.c +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashStackCursor_SelfThread.m @@ -39,10 +39,35 @@ typedef struct { uintptr_t backtrace[0]; } SelfThreadContext; +static BOOL stitchSwiftAsync = NO; + +void +sentrycrashsc_setSwiftAsyncStitching(bool enabled) +{ + stitchSwiftAsync = enabled; +} + void sentrycrashsc_initSelfThread(SentryCrashStackCursor *cursor, int skipEntries) { SelfThreadContext *context = (SelfThreadContext *)cursor->context; + +// backtrace_async api is only available from xcode 13 +#if __clang_major__ >= 13 + int backtraceLength; + if (@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)) { + if (stitchSwiftAsync) { + backtraceLength + = (int)backtrace_async((void **)context->backtrace, MAX_BACKTRACE_LENGTH, NULL); + } else { + backtraceLength = backtrace((void **)context->backtrace, MAX_BACKTRACE_LENGTH); + } + } else { + backtraceLength = backtrace((void **)context->backtrace, MAX_BACKTRACE_LENGTH); + } +#else int backtraceLength = backtrace((void **)context->backtrace, MAX_BACKTRACE_LENGTH); +#endif + sentrycrashsc_initWithBacktrace(cursor, context->backtrace, backtraceLength, skipEntries + 1); } diff --git a/Tests/SentryTests/SentryCrash/SentryStacktraceBuilderTests.swift b/Tests/SentryTests/SentryCrash/SentryStacktraceBuilderTests.swift index 13966ded8cc..02a7eab3f86 100644 --- a/Tests/SentryTests/SentryCrash/SentryStacktraceBuilderTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryStacktraceBuilderTests.swift @@ -67,7 +67,63 @@ class SentryStacktraceBuilderTests: XCTestCase { XCTAssertTrue(filteredFrames.count == 1, "The frames must be ordered from caller to callee, or oldest to youngest.") } - + + func testConcurrentStacktraces() { + guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return } + + SentrySDK.start { options in + options.dsn = TestConstants.dsnAsString(username: "SentryStacktraceBuilderTests") + options.swiftAsyncStacktraces = true + } + + let waitForAsyncToRun = expectation(description: "Wait async functions") + Task { + let filteredFrames = await self.firstFrame() + waitForAsyncToRun.fulfill() + XCTAssertGreaterThanOrEqual(filteredFrames, 3, "The Stacktrace must include the async callers.") + } + wait(for: [waitForAsyncToRun], timeout: 1) + } + + func testConcurrentStacktraces_noStitching() { + guard #available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) else { return } + + SentrySDK.start { options in + options.dsn = TestConstants.dsnAsString(username: "SentryStacktraceBuilderTests") + options.swiftAsyncStacktraces = false + } + + let waitForAsyncToRun = expectation(description: "Wait async functions") + Task { + let filteredFrames = await self.firstFrame() + waitForAsyncToRun.fulfill() + XCTAssertGreaterThanOrEqual(filteredFrames, 1, "The Stacktrace must have only one function.") + } + wait(for: [waitForAsyncToRun], timeout: 1) + } + + @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) + func firstFrame() async -> Int { + return await innerFrame1() + } + + @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) + func innerFrame1() async -> Int { + await Task { @MainActor in }.value + return await innerFrame2() + } + + @available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) + func innerFrame2() async -> Int { + let needed = ["firstFrame", "innerFrame1", "innerFrame2"] + let actual = fixture.sut.buildStacktraceForCurrentThreadAsyncUnsafe()! + let filteredFrames = actual.frames + .compactMap({ $0.function }) + .filter { needed.contains(where: $0.contains) } + return filteredFrames.count + + } + func asyncFrame1(expect: XCTestExpectation) { fixture.queue.asyncAfter(deadline: DispatchTime.now()) { self.asyncFrame2(expect: expect) diff --git a/Tests/SentryTests/SentryOptionsTest.m b/Tests/SentryTests/SentryOptionsTest.m index 341c5482600..93bbfeb7a2a 100644 --- a/Tests/SentryTests/SentryOptionsTest.m +++ b/Tests/SentryTests/SentryOptionsTest.m @@ -534,7 +534,8 @@ - (void)testNSNull_SetsDefaultValue @"enableCaptureFailedRequests" : [NSNull null], @"failedRequestStatusCodes" : [NSNull null], @"enableTimeToFullDisplay" : [NSNull null], - @"enableTracing" : [NSNull null] + @"enableTracing" : [NSNull null], + @"swiftAsyncStacktraces" : [NSNull null] } didFailWithError:nil]; @@ -586,6 +587,7 @@ - (void)assertDefaultValues:(SentryOptions *)options XCTAssertEqual(YES, options.enableSwizzling); XCTAssertEqual(YES, options.enableFileIOTracing); XCTAssertEqual(YES, options.enableAutoBreadcrumbTracking); + XCTAssertFalse(options.swiftAsyncStacktraces); #if SENTRY_HAS_METRIC_KIT if (@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, *)) { @@ -1185,6 +1187,24 @@ - (void)testUrlSessionDelegate XCTAssertNotNil(options.urlSessionDelegate); } +- (void)testDefaultSwiftAsyncStacktraces +{ + SentryOptions *options = [[SentryOptions alloc] init]; + XCTAssertFalse(options.swiftAsyncStacktraces); +} + +- (void)testInitialSwiftAsyncStacktraces +{ + SentryOptions *options = [self getValidOptions:@{}]; + XCTAssertFalse(options.swiftAsyncStacktraces); +} + +- (void)testInitialSwiftAsyncStacktracesYes +{ + SentryOptions *options = [self getValidOptions:@{ @"swiftAsyncStacktraces" : @YES }]; + XCTAssertTrue(options.swiftAsyncStacktraces); +} + - (void)assertArrayEquals:(NSArray *)expected actual:(NSArray *)actual { XCTAssertEqualObjects([expected sortedArrayUsingSelector:@selector(compare:)], From fb8db4a0ae86920919c96319ffaa83f100c4e892 Mon Sep 17 00:00:00 2001 From: Roman Tysiachnik Date: Wed, 31 May 2023 10:48:39 +0200 Subject: [PATCH 09/26] fix: Expose SentrySwiftUI and SentryPrivate schemes for Carthage (#3071) Fixes issue #2951 and, in addition, exposes SentrySwiftUI, since otherwise there's no way to build it for clients that use carthage. --- CHANGELOG.md | 1 + Sentry.xcodeproj/project.pbxproj | 4 -- .../xcschemes/SentryPrivate.xcscheme | 67 +++++++++++++++++++ .../xcschemes/SentrySwiftUI.xcscheme | 67 +++++++++++++++++++ 4 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 Sentry.xcodeproj/xcshareddata/xcschemes/SentryPrivate.xcscheme create mode 100644 Sentry.xcodeproj/xcshareddata/xcschemes/SentrySwiftUI.xcscheme diff --git a/CHANGELOG.md b/CHANGELOG.md index b12e25c374a..6101151d66e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Changed `Trace` serialized value of `sampled` from string to boolean (#3067) - Duplicated HTTP breadcrumbs (#3058) +- Expose SentryPrivate and SentrySwiftUI schemes for cartahge clients that have `--no-use-binaries` option (#3071) ### Breaking Changes diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 81d45caaa4f..1266c226fb8 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -5218,7 +5218,6 @@ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.SentrySwiftUI; - SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_EMIT_LOC_STRINGS = YES; @@ -5258,7 +5257,6 @@ MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.SentrySwiftUI; - SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = Sources/SentrySwiftUI/SentrySwiftUI.h; @@ -5296,7 +5294,6 @@ MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.SentrySwiftUI; - SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = Sources/SentrySwiftUI/SentrySwiftUI.h; @@ -5334,7 +5331,6 @@ MARKETING_VERSION = 1.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.sentry.SentrySwiftUI; - SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = Sources/SentrySwiftUI/SentrySwiftUI.h; diff --git a/Sentry.xcodeproj/xcshareddata/xcschemes/SentryPrivate.xcscheme b/Sentry.xcodeproj/xcshareddata/xcschemes/SentryPrivate.xcscheme new file mode 100644 index 00000000000..c1a798f9d35 --- /dev/null +++ b/Sentry.xcodeproj/xcshareddata/xcschemes/SentryPrivate.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sentry.xcodeproj/xcshareddata/xcschemes/SentrySwiftUI.xcscheme b/Sentry.xcodeproj/xcshareddata/xcschemes/SentrySwiftUI.xcscheme new file mode 100644 index 00000000000..8ed1c486c91 --- /dev/null +++ b/Sentry.xcodeproj/xcshareddata/xcschemes/SentrySwiftUI.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + From f58745174a321dca6ef0a15c1c18723c38bb1fbd Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Wed, 31 May 2023 10:50:53 +0200 Subject: [PATCH 10/26] chore: Readd precommit GH actions check (#3074) Was removed with https://github.com/getsentry/sentry-cocoa/pull/3064, cause it caused problems. Which are fixed now with v 0.23.01. --- .pre-commit-config.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 19d4206ca97..64b8ddc279c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,13 @@ repos: - id: end-of-file-fixer - id: no-commit-to-branch + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.23.1 + hooks: + - id: check-github-actions + - id: check-github-workflows + args: [--verbose] + - repo: local hooks: - id: format-clang From c78683b1b3d2c0b86f068616fd84c40c09db266d Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 31 May 2023 14:33:20 -0800 Subject: [PATCH 11/26] ref: convert last sprintf call to snprintf (#3077) --- CHANGELOG.md | 1 + Sources/SentryCrash/Recording/SentryCrashReport.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6101151d66e..6ec8ba913ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Changed `Trace` serialized value of `sampled` from string to boolean (#3067) - Duplicated HTTP breadcrumbs (#3058) - Expose SentryPrivate and SentrySwiftUI schemes for cartahge clients that have `--no-use-binaries` option (#3071) +- Convert last remaining `sprintf` call to `snprintf` (#3077) ### Breaking Changes diff --git a/Sources/SentryCrash/Recording/SentryCrashReport.c b/Sources/SentryCrash/Recording/SentryCrashReport.c index 29e63088a8a..93963fa55db 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReport.c +++ b/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -917,7 +917,7 @@ writeNotableStackContents(const SentryCrashReportWriter *const writer, for (uintptr_t address = lowAddress; address < highAddress; address += sizeof(address)) { if (sentrycrashmem_copySafely( (void *)address, &contentsAsPointer, sizeof(contentsAsPointer))) { - sprintf(nameBuffer, "stack@%p", (void *)address); + snprintf(nameBuffer, sizeof(nameBuffer), "stack@%p", (void *)address); writeMemoryContentsIfNotable(writer, nameBuffer, contentsAsPointer); } } From 69d87595b411be6c93e72de62bc47457202fb72d Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Thu, 1 Jun 2023 09:03:26 +0200 Subject: [PATCH 12/26] ci: Use macOS 13 and Xcode 14.3 wherever possible (#3075) Use macOS 13 with Xcode 14.3 to speed up the build, as the macOS 13 GH image is faster than macOS 12. Co-authored-by: Dhiogo Ramos Brustolin Co-authored-by: Andrew McKnight --- .github/workflows/benchmarking.yml | 4 +-- .github/workflows/build.yml | 32 +++++++------------- .github/workflows/codeql-analysis.yml | 4 +-- .github/workflows/format-code.yml | 2 +- .github/workflows/lint.yml | 8 ++--- .github/workflows/profile-data-generator.yml | 4 +-- .github/workflows/test.yml | 14 ++++----- .github/workflows/testflight.yml | 2 +- scripts/ci-select-xcode.sh | 4 +-- 9 files changed, 32 insertions(+), 42 deletions(-) diff --git a/.github/workflows/benchmarking.yml b/.github/workflows/benchmarking.yml index 0b880706fcd..5dbe6090bb6 100644 --- a/.github/workflows/benchmarking.yml +++ b/.github/workflows/benchmarking.yml @@ -23,7 +23,7 @@ on: jobs: build-benchmark-test-target: name: Build app and test runner - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - run: ./scripts/ci-select-xcode.sh @@ -96,7 +96,7 @@ jobs: app-metrics: name: Collect app metrics - runs-on: macos-12 + runs-on: macos-13 steps: - name: Git checkout uses: actions/checkout@v3 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c69a56eaa66..57dec996977 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: # With this we catch potential issues already in the PR. ios-swift-release: name: Release Build of iOS Swift - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - run: ./scripts/ci-select-xcode.sh @@ -40,7 +40,7 @@ jobs: build-sample: name: Sample ${{ matrix.scheme }} - runs-on: macos-12 + runs-on: macos-13 strategy: fail-fast: false matrix: @@ -68,7 +68,7 @@ jobs: runs-on: macos-12 steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh + - run: ./scripts/ci-select-xcode.sh 13.4.1 - run: make build-for-watchos # Disable code signing. We just want to make sure these compile. @@ -82,17 +82,10 @@ jobs: build-xcframework: name: Build XCFramework - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - - # We need to use Xcode 13 to be compatible with Xcode 13. Using Xcode 14 for compiling and building - # the sample with Xcode 13 leads to - # - # this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.7.2 - # (swiftlang-5.7.2.135.5 clang-1400.0.29.51)', while this compiler is 'Apple Swift version 5.6.1 - # (swiftlang-5.6.0.323.66 clang-1316.0.20.12)'). Please select a toolchain which matches the SDK. - - run: ./scripts/ci-select-xcode.sh 13.4.1 + - run: ./scripts/ci-select-xcode.sh - run: make build-xcframework shell: sh @@ -113,18 +106,15 @@ jobs: build-xcframework.log validate-xcframework: - name: Validate XCFramework Xcode ${{ matrix.xcode }} - runs-on: macos-12 + name: Validate XCFramework + runs-on: macos-13 needs: build-xcframework - strategy: - matrix: - xcode: ['13.4.1', '14.2'] steps: - uses: actions/checkout@v3 - uses: actions/download-artifact@v3 with: name: ${{ github.sha }} - - run: ./scripts/ci-select-xcode.sh ${{ matrix.xcode }} + - run: ./scripts/ci-select-xcode.sh - run: make build-xcframework-sample shell: sh @@ -133,7 +123,7 @@ jobs: # See https://github.community/t/github-sha-isnt-the-value-expected/17903/17906. validate-spm: name: Validate Swift Package Manager - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - name: Set SPM revision to current git commit @@ -150,7 +140,7 @@ jobs: validate-spm-dynamic: name: Validate Swift Package Manager Dynamic - runs-on: macos-11 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - name: Set SPM revision to current git commit @@ -167,7 +157,7 @@ jobs: swift-build: name: Build with Swift - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - run: swift build diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 28ec27eadea..c3924d25987 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -12,7 +12,7 @@ on: jobs: analyze: name: Analyze - runs-on: macos-11 + runs-on: macos-13 strategy: fail-fast: false @@ -34,7 +34,7 @@ jobs: -workspace Sentry.xcworkspace -scheme Sentry -configuration Release - -destination platform="iOS Simulator,OS=latest,name=iPhone 11 Pro" | xcpretty && exit ${PIPESTATUS[0]} + -destination platform="iOS Simulator,OS=latest,name=iPhone 14 Pro" | xcpretty && exit ${PIPESTATUS[0]} - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@0225834cc549ee0ca93cb085b92954821a145866 # pin@v2 diff --git a/.github/workflows/format-code.yml b/.github/workflows/format-code.yml index c998579e620..ab01941efe7 100644 --- a/.github/workflows/format-code.yml +++ b/.github/workflows/format-code.yml @@ -13,7 +13,7 @@ jobs: # if necessary format-code: name: Format Code - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 ## Update internal list of formulae to the latest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5ad233a3051..f7fad723290 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ on: jobs: swift-lint: name: Swift Lint - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - name: Run SwiftLint @@ -34,7 +34,7 @@ jobs: xcode-analyze: name: Xcode Analyze - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - run: ./scripts/ci-select-xcode.sh @@ -42,7 +42,7 @@ jobs: lint-podspec: name: pod lint ${{ matrix.podspec}} ${{ matrix.library_type }} ${{ matrix.platform}} - runs-on: macos-12 + runs-on: macos-13 strategy: matrix: podspec: ['Sentry', 'SentrySwiftUI'] @@ -63,7 +63,7 @@ jobs: steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh '14.3' + - run: ./scripts/ci-select-xcode.sh - run: pod repo update - name: Validate HybridPod Podspec run: pod lib lint ./Tests/HybridSDKTest/HybridPod.podspec --allow-warnings --verbose --platforms=ios "--include-podspecs={SentryPrivate.podspec,Sentry.podspec}" diff --git a/.github/workflows/profile-data-generator.yml b/.github/workflows/profile-data-generator.yml index dc2e513d458..b09d4fcfc07 100644 --- a/.github/workflows/profile-data-generator.yml +++ b/.github/workflows/profile-data-generator.yml @@ -12,10 +12,10 @@ on: jobs: build-profile-data-generator-targets: name: Build app and test runner - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh 13.4.1 + - run: ./scripts/ci-select-xcode.sh - name: Install SentryCli run: brew install getsentry/tools/sentry-cli - name: Cache Carthage dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4573b93cf3f..a5da5be84be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ on: jobs: build-test-server: name: Build test server - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - name: Cache for Test Server @@ -246,7 +246,7 @@ jobs: # that adds a significant overhead. thread-sanitizer: name: Unit iOS - Thread Sanitizer - runs-on: macos-12 + runs-on: macos-13 # When there are threading issues the tests sometimes keep hanging timeout-minutes: 20 @@ -287,7 +287,7 @@ jobs: steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh "14.3" + - run: ./scripts/ci-select-xcode.sh # GitHub Actions sometimes fail to launch the UI tests. Therefore we retry - name: Run Fastlane @@ -315,8 +315,8 @@ jobs: xcode: '13.4.1' device: 'iPhone 8 (15.2)' - - runs-on: macos-12 - xcode: '14.1' + - runs-on: macos-13 + xcode: '14.3' device: 'iPhone 8 (16.1)' steps: @@ -339,11 +339,11 @@ jobs: ui-tests-address-sanitizer: name: UI Tests with Address Sanitizer - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh 13.4.1 + - run: ./scripts/ci-select-xcode.sh # GitHub Actions sometimes fail to launch the UI tests. Therefore we retry - name: Run Fastlane diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 1539a609082..1f1df4470e7 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -21,7 +21,7 @@ jobs: runs-on: macos-13 steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh 14.3 + - run: ./scripts/ci-select-xcode.sh - run: bundle install # We upload a new version to TestFlight on every commit on main diff --git a/scripts/ci-select-xcode.sh b/scripts/ci-select-xcode.sh index 605c4641a0a..8a8e7c87ad1 100755 --- a/scripts/ci-select-xcode.sh +++ b/scripts/ci-select-xcode.sh @@ -7,8 +7,8 @@ set -euo pipefail -# 13.4.1 is the default -XCODE_VERSION="${1:-13.4.1}" +# 14.3 is the default +XCODE_VERSION="${1:-14.3}" sudo xcode-select -s /Applications/Xcode_${XCODE_VERSION}.app/Contents/Developer swiftc --version From 79a9b4f3c8d3e9549c4a32fb6b588b09ba3bfdc8 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Thu, 1 Jun 2023 18:46:25 -0800 Subject: [PATCH 13/26] test: add triggers to build/test for changes in xcodeproj (#3078) --- .github/workflows/build.yml | 1 + .github/workflows/test.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 57dec996977..83da19b7f9f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,7 @@ on: - 'fastlane/**' - 'scripts/ci-select-xcode.sh' - Sentry.xcworkspace + - Sentry.xcodeproj - Gemfile.lock jobs: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a5da5be84be..702e01999bd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,9 +17,9 @@ on: - 'scripts/ci-select-xcode.sh' - 'scripts/xcode-test.sh' - '.codecov.yml' + - Sentry.xcodeproj - # run the workflow any time an Xcode scheme changes for any tested target - - 'Sentry.xcodeproj/xcshareddata/xcschemes/Sentry.xcscheme' + # run the workflow any time an Xcode scheme changes for a sample app - 'Samples/tvOS-Swift/tvOS-Swift.xcodeproj/xcshareddata/xcschemes/tvOS-Swift.xcscheme' - 'Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS13-Swift.xcscheme' - 'Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme' From 6943de0faec429fe6e29ae8c9cdb31770ad05e94 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Fri, 2 Jun 2023 10:19:23 +0200 Subject: [PATCH 14/26] fix: Cache binary images to be used for crashes (#2939) During crashes we use 2 async-signal-unsafe functions _dyld_get_image_header and _dyld_get_image_name. This may lead to a crash report not being properly saved to disk. This proposal will cache binary images during runtime and use it when the app crashes. Co-authored-by: Andrew McKnight Co-authored-by: Philipp Hofmann --- CHANGELOG.md | 1 + .../xcschemes/macOS-Swift.xcscheme | 4 +- Samples/macOS-Swift/macOS-Swift/Info.plist | 2 +- Sentry.xcodeproj/project.pbxproj | 12 + Sources/Sentry/SentryCrashIntegration.m | 3 + Sources/Sentry/SentryCrashWrapper.m | 11 + Sources/Sentry/include/SentryCrashWrapper.h | 4 + .../Recording/SentryCrashBinaryImageCache.c | 180 +++++++++++ .../Recording/SentryCrashBinaryImageCache.h | 22 ++ .../SentryCrash/Recording/SentryCrashReport.c | 55 ++-- .../SentryCrashIntegrationTests.swift | 33 ++- .../SentryCrash/SentryBinaryImageCacheTests.m | 280 ++++++++++++++++++ .../SentryCrash/TestSentryCrashWrapper.h | 4 + .../SentryCrash/TestSentryCrashWrapper.m | 12 + .../SentryTests/SentryTests-Bridging-Header.h | 1 + 15 files changed, 591 insertions(+), 33 deletions(-) create mode 100644 Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.c create mode 100644 Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.h create mode 100644 Tests/SentryTests/SentryCrash/SentryBinaryImageCacheTests.m diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ec8ba913ce..d58214af39d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Experimental support for Swift Async stacktraces (#3051) +- Cache binary images to be used for crashes (#2939) ### Fixes diff --git a/Samples/macOS-Swift/macOS-Swift.xcodeproj/xcshareddata/xcschemes/macOS-Swift.xcscheme b/Samples/macOS-Swift/macOS-Swift.xcodeproj/xcshareddata/xcschemes/macOS-Swift.xcscheme index 77ac7d4caa6..28d31182327 100644 --- a/Samples/macOS-Swift/macOS-Swift.xcodeproj/xcshareddata/xcschemes/macOS-Swift.xcscheme +++ b/Samples/macOS-Swift/macOS-Swift.xcodeproj/xcshareddata/xcschemes/macOS-Swift.xcscheme @@ -32,8 +32,8 @@ NSMainStoryboardFile Main NSPrincipalClass - SentryCrashExceptionApplication + NSApplication NSSupportsAutomaticTermination NSSupportsSuddenTermination diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index 1266c226fb8..21e4fc64b28 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -757,6 +757,8 @@ D85D3BEA278DF63D001B2889 /* SentryByteCountFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85D3BE9278DF63D001B2889 /* SentryByteCountFormatterTests.swift */; }; D8603DD6284F8497000E1227 /* SentryBaggage.m in Sources */ = {isa = PBXBuildFile; fileRef = D8603DD4284F8497000E1227 /* SentryBaggage.m */; }; D8603DD8284F894C000E1227 /* SentryBaggage.h in Headers */ = {isa = PBXBuildFile; fileRef = D8603DD7284F894C000E1227 /* SentryBaggage.h */; }; + D865892F29D6ECA7000BE151 /* SentryCrashBinaryImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = D865892D29D6ECA7000BE151 /* SentryCrashBinaryImageCache.h */; }; + D865893029D6ECA7000BE151 /* SentryCrashBinaryImageCache.c in Sources */ = {isa = PBXBuildFile; fileRef = D865892E29D6ECA7000BE151 /* SentryCrashBinaryImageCache.c */; }; D867063D27C3BC2400048851 /* SentryCoreDataTrackingIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D867063A27C3BC2400048851 /* SentryCoreDataTrackingIntegration.h */; }; D867063E27C3BC2400048851 /* SentryCoreDataSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = D867063B27C3BC2400048851 /* SentryCoreDataSwizzling.h */; }; D867063F27C3BC2400048851 /* SentryCoreDataTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = D867063C27C3BC2400048851 /* SentryCoreDataTracker.h */; }; @@ -797,6 +799,7 @@ D8CB741B2947286500A5F964 /* SentryEnvelopeItemHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CB741A2947286500A5F964 /* SentryEnvelopeItemHeader.m */; }; D8CB742B294B1DD000A5F964 /* SentryUIApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CB742A294B1DD000A5F964 /* SentryUIApplicationTests.swift */; }; D8CB742E294B294B00A5F964 /* MockUIScene.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CB742D294B294B00A5F964 /* MockUIScene.m */; }; + D8CCFC632A1520C900DE232E /* SentryBinaryImageCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CCFC622A1520C900DE232E /* SentryBinaryImageCacheTests.m */; }; D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; }; D8F6A2472885512100320515 /* SentryPredicateDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = D8F6A2452885512100320515 /* SentryPredicateDescriptor.m */; }; D8F6A24B2885515C00320515 /* SentryPredicateDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = D8F6A24A2885515B00320515 /* SentryPredicateDescriptor.h */; }; @@ -1688,6 +1691,8 @@ D85D3BE9278DF63D001B2889 /* SentryByteCountFormatterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryByteCountFormatterTests.swift; sourceTree = ""; }; D8603DD4284F8497000E1227 /* SentryBaggage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryBaggage.m; sourceTree = ""; }; D8603DD7284F894C000E1227 /* SentryBaggage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryBaggage.h; path = include/SentryBaggage.h; sourceTree = ""; }; + D865892D29D6ECA7000BE151 /* SentryCrashBinaryImageCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryCrashBinaryImageCache.h; sourceTree = ""; }; + D865892E29D6ECA7000BE151 /* SentryCrashBinaryImageCache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SentryCrashBinaryImageCache.c; sourceTree = ""; }; D867063A27C3BC2400048851 /* SentryCoreDataTrackingIntegration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryCoreDataTrackingIntegration.h; path = include/SentryCoreDataTrackingIntegration.h; sourceTree = ""; }; D867063B27C3BC2400048851 /* SentryCoreDataSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryCoreDataSwizzling.h; path = include/SentryCoreDataSwizzling.h; sourceTree = ""; }; D867063C27C3BC2400048851 /* SentryCoreDataTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryCoreDataTracker.h; path = include/SentryCoreDataTracker.h; sourceTree = ""; }; @@ -1731,6 +1736,7 @@ D8CB742A294B1DD000A5F964 /* SentryUIApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIApplicationTests.swift; sourceTree = ""; }; D8CB742C294B294B00A5F964 /* MockUIScene.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockUIScene.h; sourceTree = ""; }; D8CB742D294B294B00A5F964 /* MockUIScene.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockUIScene.m; sourceTree = ""; }; + D8CCFC622A1520C900DE232E /* SentryBinaryImageCacheTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryBinaryImageCacheTests.m; sourceTree = ""; }; D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = ""; }; D8F01DE42A126B62008F4996 /* HybridPod.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = HybridPod.podspec; sourceTree = ""; }; D8F01DE52A126BF5008F4996 /* HybridTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HybridTest.swift; sourceTree = ""; }; @@ -2358,6 +2364,8 @@ 63FE704720DA4C1000CDBAE8 /* SentryCrashDoctor.m */, 63FE704C20DA4C1000CDBAE8 /* SentryCrashReport.h */, 63FE704420DA4C1000CDBAE8 /* SentryCrashReport.c */, + D865892D29D6ECA7000BE151 /* SentryCrashBinaryImageCache.h */, + D865892E29D6ECA7000BE151 /* SentryCrashBinaryImageCache.c */, 63FE704620DA4C1000CDBAE8 /* SentryCrashReportFields.h */, 63FE704820DA4C1000CDBAE8 /* SentryCrashReportFixer.h */, 63FE6FEA20DA4C1000CDBAE8 /* SentryCrashReportFixer.c */, @@ -2473,6 +2481,7 @@ isa = PBXGroup; children = ( 63FE71F120DA66EA00CDBAE8 /* Container+DeepSearch_Tests.m */, + D8CCFC622A1520C900DE232E /* SentryBinaryImageCacheTests.m */, 63FE71F620DA66EB00CDBAE8 /* FileBasedTestCase.h */, 63FE71D920DA66E700CDBAE8 /* FileBasedTestCase.m */, 7B7725D7292F5DC20015BBF9 /* SentryCrashInstallationTests.m */, @@ -3550,6 +3559,7 @@ 63FE710920DA4C1000CDBAE8 /* SentryCrashFileUtils.h in Headers */, 03F84D1F27DD414C008FE43F /* SentryAsyncSafeLogging.h in Headers */, 7BE3C76B2445C27A00A38442 /* SentryCurrentDateProvider.h in Headers */, + D865892F29D6ECA7000BE151 /* SentryCrashBinaryImageCache.h in Headers */, 6344DDB41EC309E000D9160D /* SentryCrashReportSink.h in Headers */, 7D427C62237B1D200046BAC8 /* SentrySDK.h in Headers */, D867063F27C3BC2400048851 /* SentryCoreDataTracker.h in Headers */, @@ -4090,6 +4100,7 @@ 8EAE9806261E87120073B6B3 /* SentryUIViewControllerPerformanceTracker.m in Sources */, D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */, 8EBF870926140D37001A6853 /* SentryPerformanceTracker.m in Sources */, + D865893029D6ECA7000BE151 /* SentryCrashBinaryImageCache.c in Sources */, 7BC9A20428F4166D001E7C4C /* SentryMeasurementValue.m in Sources */, D859696B27BECD8F0036A46E /* SentryCoreDataTrackingIntegration.m in Sources */, 7BD86EC7264A641D005439DB /* SentrySysctl.m in Sources */, @@ -4244,6 +4255,7 @@ 7B984A9F28E572AF001F4BEE /* CrashReport.swift in Sources */, 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */, 7BC6EC18255C44540059822A /* SentryDebugMetaTests.swift in Sources */, + D8CCFC632A1520C900DE232E /* SentryBinaryImageCacheTests.m in Sources */, A811D867248E2770008A41EA /* SentrySystemEventBreadcrumbsTest.swift in Sources */, 7B7725D8292F5DC20015BBF9 /* SentryCrashInstallationTests.m in Sources */, 7B82D54924E2A2D400EE670F /* SentryIdTests.swift in Sources */, diff --git a/Sources/Sentry/SentryCrashIntegration.m b/Sources/Sentry/SentryCrashIntegration.m index 47732bf5e2e..bf6203acdc5 100644 --- a/Sources/Sentry/SentryCrashIntegration.m +++ b/Sources/Sentry/SentryCrashIntegration.m @@ -140,6 +140,7 @@ - (void)startCrashHandler [SentryCrashIntegration sendAllSentryCrashReports]; } }; + [self.crashAdapter startBinaryImageCache]; [self.dispatchQueueWrapper dispatchOnce:&installationToken block:block]; } @@ -158,6 +159,8 @@ - (void)uninstall installationToken = 0; } + [self.crashAdapter stopBinaryImageCache]; + [NSNotificationCenter.defaultCenter removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; diff --git a/Sources/Sentry/SentryCrashWrapper.m b/Sources/Sentry/SentryCrashWrapper.m index 3616052fc6d..46da9fa046e 100644 --- a/Sources/Sentry/SentryCrashWrapper.m +++ b/Sources/Sentry/SentryCrashWrapper.m @@ -1,5 +1,6 @@ #import "SentryCrashWrapper.h" #import "SentryCrash.h" +#import "SentryCrashBinaryImageCache.h" #import "SentryCrashMonitor_AppState.h" #import "SentryCrashMonitor_System.h" #import @@ -80,6 +81,16 @@ - (bytes)appMemorySize return 0; } +- (void)startBinaryImageCache +{ + sentrycrashbic_startCache(); +} + +- (void)stopBinaryImageCache +{ + sentrycrashbic_stopCache(); +} + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryCrashWrapper.h b/Sources/Sentry/include/SentryCrashWrapper.h index 5f458589591..159b3cbcac8 100644 --- a/Sources/Sentry/include/SentryCrashWrapper.h +++ b/Sources/Sentry/include/SentryCrashWrapper.h @@ -11,6 +11,10 @@ SENTRY_NO_INIT + (instancetype)sharedInstance; +- (void)startBinaryImageCache; + +- (void)stopBinaryImageCache; + - (BOOL)crashedLastLaunch; - (NSTimeInterval)durationFromCrashStateInitToLastCrash; diff --git a/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.c b/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.c new file mode 100644 index 00000000000..d1b9e1edd10 --- /dev/null +++ b/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.c @@ -0,0 +1,180 @@ +#include "SentryCrashBinaryImageCache.h" +#include "SentryCrashDynamicLinker.h" +#include +#include +#include +#include +#include +#include + +#if TEST || TESTCI + +typedef void (*SentryRegisterImageCallback)(const struct mach_header *mh, intptr_t vmaddr_slide); +typedef void (*SentryRegisterFunction)(SentryRegisterImageCallback function); + +static SentryRegisterFunction _sentry_register_func_for_add_image + = &_dyld_register_func_for_add_image; +static SentryRegisterFunction _sentry_register_func_for_remove_image + = &_dyld_register_func_for_remove_image; + +static void (*SentryWillAddImageCallback)(void) = NULL; + +void +sentry_setRegisterFuncForAddImage(SentryRegisterFunction addFunction) +{ + _sentry_register_func_for_add_image = addFunction; +} + +void +sentry_setRegisterFuncForRemoveImage(SentryRegisterFunction removeFunction) +{ + _sentry_register_func_for_remove_image = removeFunction; +} + +void +sentry_setFuncForBeforeAdd(void (*callback)(void)) +{ + SentryWillAddImageCallback = callback; +} + +void +sentry_resetFuncForAddRemoveImage(void) +{ + _sentry_register_func_for_add_image = &_dyld_register_func_for_add_image; + _sentry_register_func_for_remove_image = &_dyld_register_func_for_remove_image; +} + +# define sentry_dyld_register_func_for_add_image(CALLBACK) \ + _sentry_register_func_for_add_image(CALLBACK); +# define sentry_dyld_register_func_for_remove_image(CALLBACK) \ + _sentry_register_func_for_remove_image(CALLBACK); +# define _will_add_image() \ + if (SentryWillAddImageCallback) \ + SentryWillAddImageCallback(); +#else +# define sentry_dyld_register_func_for_add_image(CALLBACK) \ + _dyld_register_func_for_add_image(CALLBACK) +# define sentry_dyld_register_func_for_remove_image(CALLBACK) \ + _dyld_register_func_for_remove_image(CALLBACK) +# define _will_add_image() +#endif + +typedef struct SentryCrashBinaryImageNode { + SentryCrashBinaryImage image; + bool available; + struct SentryCrashBinaryImageNode *next; +} SentryCrashBinaryImageNode; + +static SentryCrashBinaryImageNode rootNode = { 0 }; +static SentryCrashBinaryImageNode *tailNode = NULL; +static pthread_mutex_t binaryImagesMutex = PTHREAD_MUTEX_INITIALIZER; + +static void +binaryImageAdded(const struct mach_header *header, intptr_t slide) +{ + if (tailNode == NULL) { + return; + } + + Dl_info info; + if (!dladdr(header, &info) || info.dli_fname == NULL) { + return; + } + + SentryCrashBinaryImage binaryImage = { 0 }; + if (!sentrycrashdl_getBinaryImageForHeader( + (const void *)header, info.dli_fname, &binaryImage, false)) { + return; + } + + SentryCrashBinaryImageNode *newNode = malloc(sizeof(SentryCrashBinaryImageNode)); + newNode->available = true; + newNode->image = binaryImage; + newNode->next = NULL; + _will_add_image(); + pthread_mutex_lock(&binaryImagesMutex); + // Recheck tailNode as it could be null when + // stopped from another thread. + if (tailNode != NULL) { + tailNode->next = newNode; + tailNode = tailNode->next; + } else { + free(newNode); + } + pthread_mutex_unlock(&binaryImagesMutex); +} + +static void +binaryImageRemoved(const struct mach_header *header, intptr_t slide) +{ + SentryCrashBinaryImageNode *nextNode = &rootNode; + + while (nextNode != NULL) { + if (nextNode->image.address == (uint64_t)header) { + nextNode->available = false; + break; + } + nextNode = nextNode->next; + } +} + +void +sentrycrashbic_iterateOverImages(sentrycrashbic_imageIteratorCallback callback, void *context) +{ + /** + We can't use locks here because this is meant to be used during crashes, + where we can't use async unsafe functions. In order to avoid potential problems, + we choose an approach that doesn't remove nodes from the list. + */ + SentryCrashBinaryImageNode *nextNode = &rootNode; + + // If tailNode is null it means the cache was stopped, therefore we end the iteration. + // This will minimize any race condition effect without the need for locks. + while (nextNode != NULL && tailNode != NULL) { + if (nextNode->available) { + callback(&nextNode->image, context); + } + nextNode = nextNode->next; + } +} + +void +sentrycrashbic_startCache(void) +{ + pthread_mutex_lock(&binaryImagesMutex); + if (tailNode != NULL) { + // Already initialized + pthread_mutex_unlock(&binaryImagesMutex); + return; + } + tailNode = &rootNode; + rootNode.next = NULL; + pthread_mutex_unlock(&binaryImagesMutex); + + // During a call to _dyld_register_func_for_add_image() the callback func is called for every + // existing image + sentry_dyld_register_func_for_add_image(&binaryImageAdded); + sentry_dyld_register_func_for_remove_image(&binaryImageRemoved); +} + +void +sentrycrashbic_stopCache(void) +{ + pthread_mutex_lock(&binaryImagesMutex); + if (tailNode == NULL) { + pthread_mutex_unlock(&binaryImagesMutex); + return; + } + + SentryCrashBinaryImageNode *node = rootNode.next; + rootNode.next = NULL; + tailNode = NULL; + + while (node != NULL) { + SentryCrashBinaryImageNode *nextNode = node->next; + free(node); + node = nextNode; + } + + pthread_mutex_unlock(&binaryImagesMutex); +} diff --git a/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.h b/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.h new file mode 100644 index 00000000000..9e9cb793ef0 --- /dev/null +++ b/Sources/SentryCrash/Recording/SentryCrashBinaryImageCache.h @@ -0,0 +1,22 @@ +#ifndef SentryCrashBinaryImageCache_h +#define SentryCrashBinaryImageCache_h + +#include "SentryCrashDynamicLinker.h" +#include + +typedef void (*sentrycrashbic_imageIteratorCallback)(SentryCrashBinaryImage *, void *context); + +void sentrycrashbic_iterateOverImages(sentrycrashbic_imageIteratorCallback index, void *context); + +/** + * Starts the cache that will monitor binary image being loaded or removed. + */ +void sentrycrashbic_startCache(void); + +/** + * Stops the cache from monitoring binary image being loaded or removed. + * This will also clean the cache. + */ +void sentrycrashbic_stopCache(void); + +#endif /* SentryCrashBinaryImageCache_h */ diff --git a/Sources/SentryCrash/Recording/SentryCrashReport.c b/Sources/SentryCrash/Recording/SentryCrashReport.c index 93963fa55db..f193275f10c 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReport.c +++ b/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -27,6 +27,7 @@ #include "SentryCrashReport.h" +#include "SentryCrashBinaryImageCache.h" #include "SentryCrashCPU.h" #include "SentryCrashCachedData.h" #include "SentryCrashDynamicLinker.h" @@ -1159,42 +1160,44 @@ writeAllThreads(const SentryCrashReportWriter *const writer, const char *const k * * @param key The object key, if needed. * - * @param index Which image to write about. + * @param image Which image to write about. */ static void -writeBinaryImage( - const SentryCrashReportWriter *const writer, const char *const key, const int index) +writeBinaryImage(const SentryCrashReportWriter *const writer, const char *const key, + SentryCrashBinaryImage *image) { - SentryCrashBinaryImage image = { 0 }; - if (!sentrycrashdl_getBinaryImage(index, &image, /*isCrash*/ true)) { - return; - } - writer->beginObject(writer, key); { - writer->addUIntegerElement(writer, SentryCrashField_ImageAddress, image.address); - writer->addUIntegerElement(writer, SentryCrashField_ImageVmAddress, image.vmAddress); - writer->addUIntegerElement(writer, SentryCrashField_ImageSize, image.size); - writer->addStringElement(writer, SentryCrashField_Name, image.name); - writer->addUUIDElement(writer, SentryCrashField_UUID, image.uuid); - writer->addIntegerElement(writer, SentryCrashField_CPUType, image.cpuType); - writer->addIntegerElement(writer, SentryCrashField_CPUSubType, image.cpuSubType); - writer->addUIntegerElement(writer, SentryCrashField_ImageMajorVersion, image.majorVersion); - writer->addUIntegerElement(writer, SentryCrashField_ImageMinorVersion, image.minorVersion); + writer->addUIntegerElement(writer, SentryCrashField_ImageAddress, image->address); + writer->addUIntegerElement(writer, SentryCrashField_ImageVmAddress, image->vmAddress); + writer->addUIntegerElement(writer, SentryCrashField_ImageSize, image->size); + writer->addStringElement(writer, SentryCrashField_Name, image->name); + writer->addUUIDElement(writer, SentryCrashField_UUID, image->uuid); + writer->addIntegerElement(writer, SentryCrashField_CPUType, image->cpuType); + writer->addIntegerElement(writer, SentryCrashField_CPUSubType, image->cpuSubType); + writer->addUIntegerElement(writer, SentryCrashField_ImageMajorVersion, image->majorVersion); + writer->addUIntegerElement(writer, SentryCrashField_ImageMinorVersion, image->minorVersion); writer->addUIntegerElement( - writer, SentryCrashField_ImageRevisionVersion, image.revisionVersion); - if (image.crashInfoMessage != NULL) { + writer, SentryCrashField_ImageRevisionVersion, image->revisionVersion); + if (image->crashInfoMessage != NULL) { writer->addStringElement( - writer, SentryCrashField_ImageCrashInfoMessage, image.crashInfoMessage); + writer, SentryCrashField_ImageCrashInfoMessage, image->crashInfoMessage); } - if (image.crashInfoMessage2 != NULL) { + if (image->crashInfoMessage2 != NULL) { writer->addStringElement( - writer, SentryCrashField_ImageCrashInfoMessage2, image.crashInfoMessage2); + writer, SentryCrashField_ImageCrashInfoMessage2, image->crashInfoMessage2); } } writer->endContainer(writer); } +static void +binaryImagesIteratorCallback(SentryCrashBinaryImage *image, void *context) +{ + SentryCrashReportWriter *writer = (SentryCrashReportWriter *)context; + writeBinaryImage(writer, NULL, image); +} + /** Write information about all images to the report. * * @param writer The writer. @@ -1204,14 +1207,8 @@ writeBinaryImage( static void writeBinaryImages(const SentryCrashReportWriter *const writer, const char *const key) { - const int imageCount = sentrycrashdl_imageCount(); - writer->beginArray(writer, key); - { - for (int iImg = 0; iImg < imageCount; iImg++) { - writeBinaryImage(writer, NULL, iImg); - } - } + sentrycrashbic_iterateOverImages(&binaryImagesIteratorCallback, (void *)writer); writer->endContainer(writer); } diff --git a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift index 05be88571fc..b45fc7731e1 100644 --- a/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/SentryCrash/SentryCrashIntegrationTests.swift @@ -175,7 +175,38 @@ class SentryCrashIntegrationTests: NotificationCenterTestCase { XCTAssertEqual(session, fileManager.readCurrentSession()) XCTAssertNil(fileManager.readCrashedSession()) } - + + func testBinaryImageCacheStartAndStop() { + let (sut, _) = givenSutWithGlobalHub() + + sut.install(with: Options()) + + XCTAssertTrue(fixture.sentryCrash.binaryCacheStarted) + + var imagesCounter = 0 + + sentrycrashbic_iterateOverImages({ _, context in + guard let counter = context?.assumingMemoryBound(to: Int.self) else { + return + } + counter.pointee += 1 + }, &imagesCounter) + XCTAssertGreaterThan(imagesCounter, 0) + + sut.uninstall() + imagesCounter = 0 + + sentrycrashbic_iterateOverImages({ _, context in + guard let counter = context?.assumingMemoryBound(to: Int.self) else { + return + } + counter.pointee += 1 + }, &imagesCounter) + + XCTAssertEqual(imagesCounter, 0) + XCTAssertTrue(fixture.sentryCrash.binaryCacheStopped) + } + func testEndSessionAsCrashed_NoCurrentSession() { let (sut, _) = givenSutWithGlobalHub() diff --git a/Tests/SentryTests/SentryCrash/SentryBinaryImageCacheTests.m b/Tests/SentryTests/SentryCrash/SentryBinaryImageCacheTests.m new file mode 100644 index 00000000000..592f96c3a91 --- /dev/null +++ b/Tests/SentryTests/SentryCrash/SentryBinaryImageCacheTests.m @@ -0,0 +1,280 @@ +#import "SentryCrashBinaryImageCache.h" +#import "SentryCrashWrapper.h" +#import +#include + +// Exposing test only functions from `SentryCrashBinaryImageCache.m` +void sentry_setRegisterFuncForAddImage(void *addFunction); +void sentry_setRegisterFuncForRemoveImage(void *removeFunction); +void sentry_resetFuncForAddRemoveImage(void); +void sentry_setFuncForBeforeAdd(void (*callback)(void)); + +static void (*addBinaryImage)(const struct mach_header *mh, intptr_t vmaddr_slide); +static void (*removeBinaryImage)(const struct mach_header *mh, intptr_t vmaddr_slide); +static NSMutableArray *mach_headers_test_cache; +static NSMutableArray *mach_headers_expect_array; + +static void +sentry_register_func_for_add_image( + void (*func)(const struct mach_header *mh, intptr_t vmaddr_slide)) +{ + addBinaryImage = func; + + if (mach_headers_expect_array) { + for (NSUInteger i = 0; i < mach_headers_expect_array.count; i++) { + NSValue *header = mach_headers_expect_array[i]; + func(header.pointerValue, 0); + } + } +} + +static void +sentry_register_func_for_remove_image( + void (*func)(const struct mach_header *mh, intptr_t vmaddr_slide)) +{ + removeBinaryImage = func; +} + +static void +cacheMachHeaders(const struct mach_header *mh, __unused intptr_t vmaddr_slide) +{ + [mach_headers_test_cache addObject:[NSValue valueWithPointer:mh]]; +} + +static void +countNumberOfImagesInCache(__unused SentryCrashBinaryImage *image, void *context) +{ + int *counter = context; + (*counter)++; +} + +static void +addBinaryImageToArray(SentryCrashBinaryImage *image, void *context) +{ + NSMutableArray *array = (__bridge NSMutableArray *)context; + [array addObject:[NSValue valueWithPointer:image]]; +} + +dispatch_semaphore_t delaySemaphore = NULL; +dispatch_semaphore_t delayCalled = NULL; +static void +delayAddBinaryImage(void) +{ + if (delayCalled) { + dispatch_semaphore_signal(delayCalled); + } + if (delaySemaphore) { + dispatch_semaphore_wait(delaySemaphore, DISPATCH_TIME_FOREVER); + } +} + +@interface SentryBinaryImageCacheTests : XCTestCase + +@end + +@implementation SentryBinaryImageCacheTests + ++ (void)setUp +{ + // Create a test cache of actual binary images to be used during tests. + mach_headers_test_cache = [NSMutableArray array]; + _dyld_register_func_for_add_image(&cacheMachHeaders); +} + +- (void)setUp +{ + sentry_setRegisterFuncForAddImage(&sentry_register_func_for_add_image); + sentry_setRegisterFuncForRemoveImage(&sentry_register_func_for_remove_image); + + // Copying the first 5 images from the temporary list. + // 5 is a magic number. + mach_headers_expect_array = + [mach_headers_test_cache subarrayWithRange:NSMakeRange(0, 5)].mutableCopy; +} + +- (void)tearDown +{ + sentry_resetFuncForAddRemoveImage(); + sentrycrashbic_stopCache(); + sentry_setFuncForBeforeAdd(NULL); +} + +- (void)testStartCache +{ + [[SentryCrashWrapper sharedInstance] startBinaryImageCache]; + [self assertBinaryImageCacheLength:5]; +} + +- (void)testStartCacheTwice +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; +} + +- (void)testStopCache +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + sentrycrashbic_stopCache(); + [self assertBinaryImageCacheLength:0]; +} + +- (void)testStopCacheTwice +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + sentrycrashbic_stopCache(); + [self assertBinaryImageCacheLength:0]; + sentrycrashbic_stopCache(); + [self assertBinaryImageCacheLength:0]; +} + +- (void)testAddNewImage +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + addBinaryImage([mach_headers_test_cache[5] pointerValue], 0); + mach_headers_expect_array = + [mach_headers_test_cache subarrayWithRange:NSMakeRange(0, 6)].mutableCopy; + [self assertBinaryImageCacheLength:6]; + [self assertCachedBinaryImages]; + + addBinaryImage([mach_headers_test_cache[6] pointerValue], 0); + mach_headers_expect_array = + [mach_headers_test_cache subarrayWithRange:NSMakeRange(0, 7)].mutableCopy; + [self assertBinaryImageCacheLength:7]; + [self assertCachedBinaryImages]; +} + +- (void)testAddInvalidHeader +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + addBinaryImage(0, 0); + [self assertBinaryImageCacheLength:5]; +} + +- (void)testAddNewImageAfterStopping +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + sentrycrashbic_stopCache(); + addBinaryImage([mach_headers_test_cache[6] pointerValue], 0); + [self assertBinaryImageCacheLength:0]; +} + +- (void)testRemoveImageFromTail +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + removeBinaryImage([mach_headers_expect_array[4] pointerValue], 0); + [self assertBinaryImageCacheLength:4]; + [self assertCachedBinaryImages]; + + removeBinaryImage([mach_headers_expect_array[3] pointerValue], 0); + [self assertBinaryImageCacheLength:3]; + [self assertCachedBinaryImages]; +} + +- (void)testRemoveImageFromBeginning +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + removeBinaryImage([mach_headers_expect_array[0] pointerValue], 0); + [self assertBinaryImageCacheLength:4]; + [mach_headers_expect_array removeObjectAtIndex:0]; + [self assertCachedBinaryImages]; + + removeBinaryImage([mach_headers_expect_array[0] pointerValue], 0); + [self assertBinaryImageCacheLength:3]; + [mach_headers_expect_array removeObjectAtIndex:0]; + [self assertCachedBinaryImages]; +} + +- (void)testRemoveImageAddAgain +{ + sentrycrashbic_startCache(); + [self assertBinaryImageCacheLength:5]; + + removeBinaryImage([mach_headers_expect_array[0] pointerValue], 0); + [self assertBinaryImageCacheLength:4]; + + NSValue *removeItem = mach_headers_expect_array[0]; + [mach_headers_expect_array removeObjectAtIndex:0]; + [self assertCachedBinaryImages]; + + addBinaryImage(removeItem.pointerValue, 0); + [self assertBinaryImageCacheLength:5]; + [mach_headers_expect_array insertObject:removeItem atIndex:4]; + [self assertCachedBinaryImages]; +} + +- (void)testAddBinaryImageInParallel +{ + sentrycrashbic_startCache(); + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_group_t group = dispatch_group_create(); + + for (NSUInteger i = 5; i < mach_headers_test_cache.count; i++) { + dispatch_group_enter(group); + dispatch_group_async(group, queue, ^{ + addBinaryImage([mach_headers_test_cache[i] pointerValue], 0); + dispatch_group_leave(group); + }); + } + dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); + + [self assertBinaryImageCacheLength:(int)mach_headers_test_cache.count]; +} + +- (void)testCloseCacheWhileAdding +{ + sentrycrashbic_startCache(); + sentry_setFuncForBeforeAdd(&delayAddBinaryImage); + delaySemaphore = dispatch_semaphore_create(0); + delayCalled = dispatch_semaphore_create(0); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), + ^{ addBinaryImage([mach_headers_test_cache[6] pointerValue], 0); }); + + intptr_t result + = dispatch_semaphore_wait(delayCalled, dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC)); + sentrycrashbic_stopCache(); + dispatch_semaphore_signal(delaySemaphore); + [self assertBinaryImageCacheLength:0]; + XCTAssertEqual(result, 0); +} + +- (void)assertBinaryImageCacheLength:(int)expected +{ + int counter = 0; + sentrycrashbic_iterateOverImages(countNumberOfImagesInCache, &counter); + XCTAssertEqual(counter, expected); +} + +- (void)assertCachedBinaryImages +{ + NSArray *cached = [self binaryImageCacheToArray]; + for (NSUInteger i = 0; i < cached.count; i++) { + SentryCrashBinaryImage *binaryImage = [cached[i] pointerValue]; + struct mach_header *header = [mach_headers_expect_array[i] pointerValue]; + XCTAssertEqual(binaryImage->address, (uint64_t)header); + } +} + +- (NSArray *)binaryImageCacheToArray +{ + NSMutableArray *result = [NSMutableArray array]; + sentrycrashbic_iterateOverImages(addBinaryImageToArray, (__bridge void *)(result)); + return result; +} + +@end diff --git a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h index 052456cc023..7d61ab46c24 100644 --- a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h +++ b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.h @@ -33,6 +33,10 @@ SENTRY_NO_INIT @property (nonatomic, assign) uint64_t internalFreeStorageSize; +@property (nonatomic) BOOL binaryCacheStarted; + +@property (nonatomic) BOOL binaryCacheStopped; + @end NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m index 5f8cac49d29..b4882f9a5cf 100644 --- a/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m +++ b/Tests/SentryTests/SentryCrash/TestSentryCrashWrapper.m @@ -21,6 +21,18 @@ + (instancetype)sharedInstance return instance; } +- (void)startBinaryImageCache +{ + _binaryCacheStarted = YES; + [super startBinaryImageCache]; +} + +- (void)stopBinaryImageCache +{ + [super stopBinaryImageCache]; + _binaryCacheStopped = YES; +} + - (BOOL)crashedLastLaunch { return self.internalCrashedLastLaunch; diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 5013c9979ce..1a6456d6d54 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -186,6 +186,7 @@ #import "UIViewController+Sentry.h" #import "URLSessionTaskMock.h" @import SentryPrivate; +#import "SentryCrashBinaryImageCache.h" #import "SentryDispatchFactory.h" #import "SentryDispatchSourceWrapper.h" #import "SentryEnvelopeAttachmentHeader.h" From f0283e8a2f36ffe2b9fd314eec9d87aff9b4922b Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Mon, 5 Jun 2023 08:38:16 +0200 Subject: [PATCH 15/26] Fix a data race for SentryId.empty (#3072) Initialize the SentryId.empty in the class initializer to fix a data race. --- CHANGELOG.md | 1 + Sources/Sentry/SentryId.m | 13 ++++++++++--- Tests/SentryTests/Protocol/SentryIdTests.swift | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d58214af39d..9a3db85a0fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixes +- Fix a data race for `SentryId.empty` (#3072) - Changed `Trace` serialized value of `sampled` from string to boolean (#3067) - Duplicated HTTP breadcrumbs (#3058) - Expose SentryPrivate and SentrySwiftUI schemes for cartahge clients that have `--no-use-binaries` option (#3071) diff --git a/Sources/Sentry/SentryId.m b/Sources/Sentry/SentryId.m index 618054200e0..4b09fb20c69 100644 --- a/Sources/Sentry/SentryId.m +++ b/Sources/Sentry/SentryId.m @@ -16,6 +16,16 @@ @implementation SentryId static SentryId *_empty = nil; ++ (void)initialize +{ + if (self == [SentryId class]) { + // Initialize the empty here instead of using a lazy load approach in the getter to avoid + // using a lock to prevent data races. Empty is used at a couple of places in the SDK, so + // potentially minimizing the memory footprint doesn't apply. + _empty = [[SentryId alloc] initWithUUIDString:emptyUUIDString]; + } +} + - (instancetype)init { return [self initWithUUID:[NSUUID UUID]]; @@ -84,9 +94,6 @@ - (NSUInteger)hash + (SentryId *)empty { - if (nil == _empty) { - _empty = [[SentryId alloc] initWithUUIDString:emptyUUIDString]; - } return _empty; } diff --git a/Tests/SentryTests/Protocol/SentryIdTests.swift b/Tests/SentryTests/Protocol/SentryIdTests.swift index 8341dde9237..33b0a3be439 100644 --- a/Tests/SentryTests/Protocol/SentryIdTests.swift +++ b/Tests/SentryTests/Protocol/SentryIdTests.swift @@ -80,4 +80,10 @@ class SentryIdTests: XCTestCase { func testHash_IsDifferentWhenObjectsAreDifferent() { XCTAssertNotEqual(SentryId(uuid: UUID()).hash, SentryId(uuid: fixture.uuid).hash) } + + func testConcurrentReadsOfEmpty() { + testConcurrentModifications { _ in + XCTAssertNotNil(SentryId.empty) + } + } } From a6c634b6f5c58a4c5cd277389c5abdd21c0f8684 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:55:55 +0200 Subject: [PATCH 16/26] build(deps): bump github/codeql-action from 2.3.5 to 2.3.6 (#3080) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.3.5 to 2.3.6. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0225834cc549ee0ca93cb085b92954821a145866...83f0fe6c4988d98a455712a27f0255212bba9bd4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c3924d25987..e6540480ac7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 - name: Initialize CodeQL - uses: github/codeql-action/init@0225834cc549ee0ca93cb085b92954821a145866 # pin@v2 + uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # pin@v2 with: languages: ${{ matrix.language }} @@ -37,4 +37,4 @@ jobs: -destination platform="iOS Simulator,OS=latest,name=iPhone 14 Pro" | xcpretty && exit ${PIPESTATUS[0]} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0225834cc549ee0ca93cb085b92954821a145866 # pin@v2 + uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # pin@v2 From 6c35c60d8264d312a841b651584b0a842f7e57f3 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 6 Jun 2023 17:37:27 +0200 Subject: [PATCH 17/26] ci: Several SwiftLint fixes (#3083) SwiftLint was not running properly locally and in CI. This is fixed now by always using the latest swiftlint version in CI. Futhermore, I had to apply a couple of fixes for SwiftLint and added extra configuration files for different directories. --- .github/workflows/lint.yml | 3 +- .swiftlint.yml | 19 ++-- CONTRIBUTING.md | 2 +- Makefile | 2 +- Samples/.swiftlint.yml | 10 ++ Samples/TrendingMovies/.swiftlint.yml | 12 +++ .../iOS-SwiftUI/iOS-SwiftUI/UIKitScreen.swift | 4 - SentryTestUtils/.swiftlint.yml | 8 ++ Tests/.swiftlint.yml | 95 +++---------------- ...SentryUIViewControllerSwizzlingTests.swift | 2 + .../Networking/SentryHttpTransportTests.swift | 22 ++--- .../SentryTransportAdapterTests.swift | 4 +- .../Networking/TestResponseFactory.swift | 4 +- .../Protocol/SentryBreadcrumbTests.swift | 4 +- .../Protocol/SentryEnvelopeTests.swift | 8 +- Tests/SentryTests/Protocol/TestData.swift | 4 +- Tests/SentryTests/SentryClientTests.swift | 14 ++- Tests/SentryTests/SentrySDKTests.swift | 8 +- Tests/SentryTests/SentryScopeSwiftTests.swift | 4 +- Tests/SentryTests/TestLogOutput.swift | 6 +- .../SentryTransactionContextTests.swift | 4 +- Utils/VersionBump/.swiftlint.yml | 5 + 22 files changed, 94 insertions(+), 150 deletions(-) create mode 100755 Samples/.swiftlint.yml create mode 100755 Samples/TrendingMovies/.swiftlint.yml create mode 100755 SentryTestUtils/.swiftlint.yml create mode 100755 Utils/VersionBump/.swiftlint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f7fad723290..e517e72464f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -29,8 +29,9 @@ jobs: runs-on: macos-13 steps: - uses: actions/checkout@v3 + - run: swiftlint --version - name: Run SwiftLint - run: swiftlint + run: swiftlint --strict xcode-analyze: name: Xcode Analyze diff --git a/.swiftlint.yml b/.swiftlint.yml index 12b61379d63..514f5222fbf 100755 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -7,6 +7,7 @@ excluded: - vendor - test-server/.build/ - Tests/Perf + - SentryTestUtils/Dynamic/** only_rules: #- attributes @@ -84,24 +85,26 @@ only_rules: - void_return - weak_delegate - yoda_condition + identifier_name: allowed_symbols: - i - _ min_length: - 2 - - 1 -force_try: - severity: warning -force_unwrapping: - severity: error -overridden_super_call: - severity: error + max_length: + warning: 50 + error: 50 + + line_length: - - 220 + - 1000 type_name: min_length: - 2 - 1 + max_length: + warning: 50 + error: 50 large_tuple: - 3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ee01a1853e..2968b001a28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,7 +89,7 @@ This means if homebrew updates the [formula](https://formulae.brew.sh/formula/) ## Linting -We use [Swiftlint](https://github.com/realm/SwiftLint) and Clang-Format. For Swiftlint we keep a seperate [config file](/Tests/.swiftlint) for the tests. To run all the linters locally execute: +We use [Swiftlint](https://github.com/realm/SwiftLint) and Clang-Format. For SwiftLint, we keep a multiple config files for the tests and samples, cause some rules don't make sense for testing and sample code. To run all the linters locally execute: ```sh make lint diff --git a/Makefile b/Makefile index d49bfa63d89..a7f6eea6645 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ endif lint: @echo "--> Running Swiftlint and Clang-Format" ./scripts/check-clang-format.py -r Sources Tests - swiftlint + swiftlint --strict .PHONY: lint no-changes-in-high-risk-files: diff --git a/Samples/.swiftlint.yml b/Samples/.swiftlint.yml new file mode 100755 index 00000000000..7cfae587f6c --- /dev/null +++ b/Samples/.swiftlint.yml @@ -0,0 +1,10 @@ +parent_config: ../.swiftlint.yml + +disabled_rules: + - force_cast + - force_try + - force_unwrapping + - identifier_name + - object_literal + - private_outlet + - unused_optional_binding diff --git a/Samples/TrendingMovies/.swiftlint.yml b/Samples/TrendingMovies/.swiftlint.yml new file mode 100755 index 00000000000..25b66cbff90 --- /dev/null +++ b/Samples/TrendingMovies/.swiftlint.yml @@ -0,0 +1,12 @@ +parent_config: ../.swiftlint.yml + +disabled_rules: + - todo + - object_literal + - line_length + - file_length + - cyclomatic_complexity + - switch_case_on_newline + - type_body_length + - function_body_length + - identifier_name diff --git a/Samples/iOS-SwiftUI/iOS-SwiftUI/UIKitScreen.swift b/Samples/iOS-SwiftUI/iOS-SwiftUI/UIKitScreen.swift index 1b6c15d716d..626038ea938 100644 --- a/Samples/iOS-SwiftUI/iOS-SwiftUI/UIKitScreen.swift +++ b/Samples/iOS-SwiftUI/iOS-SwiftUI/UIKitScreen.swift @@ -5,10 +5,6 @@ import UIKit class CustomViewController: UIViewController { - override func loadView() { - super.loadView() - } - override func viewDidLoad() { super.viewDidLoad() let label = UILabel(frame: self.view.bounds) diff --git a/SentryTestUtils/.swiftlint.yml b/SentryTestUtils/.swiftlint.yml new file mode 100755 index 00000000000..40fa2a1c4d7 --- /dev/null +++ b/SentryTestUtils/.swiftlint.yml @@ -0,0 +1,8 @@ +parent_config: ../.swiftlint.yml + +disabled_rules: + - force_cast + - force_try + - force_unwrapping + - identifier_name + - large_tuple diff --git a/Tests/.swiftlint.yml b/Tests/.swiftlint.yml index 6f2625b241f..263ad62c028 100755 --- a/Tests/.swiftlint.yml +++ b/Tests/.swiftlint.yml @@ -1,88 +1,15 @@ -excluded: - - DependencyManagerTests -whitelist_rules: - #- attributes - - class_delegate_protocol - - closing_brace - - closure_end_indentation - - closure_parameter_position - - closure_spacing - - colon - - comma - - compiler_protocol_init - #- conditional_returns_on_newline - - control_statement - - custom_rules - - cyclomatic_complexity - - dynamic_inline - - empty_count - - empty_parameters - - empty_parentheses_with_trailing_closure - - explicit_init - #- file_header - - file_length - - first_where - # - force_cast - # - force_try - # - force_unwrapping +parent_config: ../.swiftlint.yml + +disabled_rules: + - force_cast + - force_try + - force_unwrapping - function_body_length - - function_parameter_count - - generic_type_name - - implicit_getter - - large_tuple - - leading_whitespace - - legacy_cggeometry_functions - - legacy_constant - - legacy_constructor - - legacy_nsgeometry_functions - - line_length - - mark - #- missing_docs - #- nesting - - nimble_operator - - number_separator - - object_literal - - opening_brace - - operator_usage_whitespace - - operator_whitespace - - overridden_super_call - - private_outlet - - private_unit_test - - prohibited_super_call - - redundant_nil_coalescing - - redundant_optional_initialization - - redundant_string_enum_value - - redundant_void_return - - return_arrow_whitespace - - shorthand_operator - - sorted_imports - - statement_position - - switch_case_on_newline - - syntactic_sugar - - todo - - trailing_comma - - trailing_newline - - trailing_semicolon - #- trailing_whitespace - #- type_body_length - - type_name - - unused_closure_parameter - - unused_enumerated - - unused_optional_binding - - valid_ibinspectable - identifier_name - - vertical_parameter_alignment - - vertical_whitespace - - void_return + - large_tuple + - type_body_length - weak_delegate -identifier_name: - min_length: - - 2 - - 1 -line_length: - - 220 -type_name: - min_length: - - 2 - - 1 +file_length: + warning: 1000 + error: 1000 diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift index 382634e88fa..3163fb4d551 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift @@ -286,12 +286,14 @@ class MockApplication: NSObject, SentryUIApplicationProtocol { } } +// swiftlint:disable prohibited_super_call class ViewWithLoadViewController: UIViewController { override func loadView() { super.loadView() // empty on purpose } } +// swiftlint:enable prohibited_super_call class ObjectWithWindowsProperty: NSObject { var resultOfWindows: Any? diff --git a/Tests/SentryTests/Networking/SentryHttpTransportTests.swift b/Tests/SentryTests/Networking/SentryHttpTransportTests.swift index 6a26c87d455..2877705633d 100644 --- a/Tests/SentryTests/Networking/SentryHttpTransportTests.swift +++ b/Tests/SentryTests/Networking/SentryHttpTransportTests.swift @@ -99,18 +99,16 @@ class SentryHttpTransportTests: XCTestCase { } var sut: SentryHttpTransport { - get { - return SentryHttpTransport( - options: options, - fileManager: fileManager, - requestManager: requestManager, - requestBuilder: requestBuilder, - rateLimits: rateLimits, - envelopeRateLimit: EnvelopeRateLimit(rateLimits: rateLimits), - dispatchQueueWrapper: dispatchQueueWrapper, - reachability: reachability - ) - } + return SentryHttpTransport( + options: options, + fileManager: fileManager, + requestManager: requestManager, + requestBuilder: requestBuilder, + rateLimits: rateLimits, + envelopeRateLimit: EnvelopeRateLimit(rateLimits: rateLimits), + dispatchQueueWrapper: dispatchQueueWrapper, + reachability: reachability + ) } } diff --git a/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift b/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift index 1201eccc0f8..979652f914e 100644 --- a/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift +++ b/Tests/SentryTests/Networking/SentryTransportAdapterTests.swift @@ -12,9 +12,7 @@ class SentryTransportAdapterTests: XCTestCase { let attachment = Attachment(data: Data(), filename: "test.txt") var sut: SentryTransportAdapter { - get { - return SentryTransportAdapter(transport: transport, options: options) - } + return SentryTransportAdapter(transport: transport, options: options) } } diff --git a/Tests/SentryTests/Networking/TestResponseFactory.swift b/Tests/SentryTests/Networking/TestResponseFactory.swift index 17f827146e5..c3efb4d93f7 100644 --- a/Tests/SentryTests/Networking/TestResponseFactory.swift +++ b/Tests/SentryTests/Networking/TestResponseFactory.swift @@ -8,7 +8,7 @@ struct TestResponseFactory { statusCode: 429, httpVersion: "1.1", headerFields: ["Retry-After": headerValue]) - if nil == response { + if response == nil { XCTFail("Response could not be created") } return response! @@ -20,7 +20,7 @@ struct TestResponseFactory { statusCode: 200, httpVersion: "1.1", headerFields: ["X-Sentry-Rate-Limits": headerValue]) - if nil == response { + if response == nil { XCTFail("Response could not be created") } return response! diff --git a/Tests/SentryTests/Protocol/SentryBreadcrumbTests.swift b/Tests/SentryTests/Protocol/SentryBreadcrumbTests.swift index 5a824e818fe..14fee72fc6c 100644 --- a/Tests/SentryTests/Protocol/SentryBreadcrumbTests.swift +++ b/Tests/SentryTests/Protocol/SentryBreadcrumbTests.swift @@ -24,9 +24,7 @@ class SentryBreadcrumbTests: XCTestCase { } var dateAs8601String: String { - get { - return (date as NSDate).sentry_toIso8601String() - } + return (date as NSDate).sentry_toIso8601String() } } diff --git a/Tests/SentryTests/Protocol/SentryEnvelopeTests.swift b/Tests/SentryTests/Protocol/SentryEnvelopeTests.swift index 00c1889f110..515bbc59792 100644 --- a/Tests/SentryTests/Protocol/SentryEnvelopeTests.swift +++ b/Tests/SentryTests/Protocol/SentryEnvelopeTests.swift @@ -24,11 +24,9 @@ class SentryEnvelopeTests: XCTestCase { } var breadcrumb: Breadcrumb { - get { - let crumb = Breadcrumb(level: SentryLevel.debug, category: "ui.lifecycle") - crumb.message = "first breadcrumb" - return crumb - } + let crumb = Breadcrumb(level: SentryLevel.debug, category: "ui.lifecycle") + crumb.message = "first breadcrumb" + return crumb } var event: Event { diff --git a/Tests/SentryTests/Protocol/TestData.swift b/Tests/SentryTests/Protocol/TestData.swift index 3209afc21f1..dd8a9f29308 100644 --- a/Tests/SentryTests/Protocol/TestData.swift +++ b/Tests/SentryTests/Protocol/TestData.swift @@ -9,9 +9,7 @@ class TestData { static let timestamp = Date(timeIntervalSince1970: 10) static var timestampAs8601String: String { - get { - (timestamp as NSDate).sentry_toIso8601String() - } + (timestamp as NSDate).sentry_toIso8601String() } static let sdk = ["name": SentryMeta.sdkName, "version": SentryMeta.versionString] static let context: [String: [String: Any]] = ["context": ["c": "a", "date": timestamp]] diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index 0257c815db0..90f4ed95330 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -105,14 +105,12 @@ class SentryClientTest: XCTestCase { } var scope: Scope { - get { - let scope = Scope() - scope.setEnvironment(environment) - scope.setTag(value: "value", key: "key") - scope.addAttachment(TestData.dataAttachment) - scope.setContext(value: [SentryDeviceContextFreeMemoryKey: 2_000], key: "device") - return scope - } + let scope = Scope() + scope.setEnvironment(environment) + scope.setTag(value: "value", key: "key") + scope.addAttachment(TestData.dataAttachment) + scope.setContext(value: [SentryDeviceContextFreeMemoryKey: 2_000], key: "device") + return scope } var eventWithCrash: Event { diff --git a/Tests/SentryTests/SentrySDKTests.swift b/Tests/SentryTests/SentrySDKTests.swift index 02e5ba81774..f9f72fb6bbd 100644 --- a/Tests/SentryTests/SentrySDKTests.swift +++ b/Tests/SentryTests/SentrySDKTests.swift @@ -23,11 +23,9 @@ class SentrySDKTests: XCTestCase { } var scopeWithBlockApplied: Scope { - get { - let scope = self.scope - scopeBlock(scope) - return scope - } + let scope = self.scope + scopeBlock(scope) + return scope } let message = "message" diff --git a/Tests/SentryTests/SentryScopeSwiftTests.swift b/Tests/SentryTests/SentryScopeSwiftTests.swift index 810b7129848..a064a301b15 100644 --- a/Tests/SentryTests/SentryScopeSwiftTests.swift +++ b/Tests/SentryTests/SentryScopeSwiftTests.swift @@ -74,9 +74,7 @@ class SentryScopeSwiftTests: XCTestCase { } var dateAs8601String: String { - get { - (date as NSDate).sentry_toIso8601String() - } + (date as NSDate).sentry_toIso8601String() } } diff --git a/Tests/SentryTests/TestLogOutput.swift b/Tests/SentryTests/TestLogOutput.swift index c5cbc2b8d12..14e17f578a3 100644 --- a/Tests/SentryTests/TestLogOutput.swift +++ b/Tests/SentryTests/TestLogOutput.swift @@ -9,10 +9,8 @@ class TestLogOutput: SentryLogOutput { var callSuperWhenLogging = true var loggedMessages: [String] { - get { - queue.sync { - return _loggedMessages - } + queue.sync { + return _loggedMessages } } diff --git a/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift b/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift index aa62d71ee38..353b27e3a49 100644 --- a/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift +++ b/Tests/SentryTests/Transaction/SentryTransactionContextTests.swift @@ -73,9 +73,7 @@ class SentryTransactionContextTests: XCTestCase { } private var contextWithAllParams: TransactionContext { - get { - return TransactionContext(name: transactionName, nameSource: nameSource, operation: operation, origin: origin, trace: traceID, spanId: spanID, parentSpanId: parentSpanID, sampled: sampled, parentSampled: parentSampled) - } + return TransactionContext(name: transactionName, nameSource: nameSource, operation: operation, origin: origin, trace: traceID, spanId: spanID, parentSpanId: parentSpanID, sampled: sampled, parentSampled: parentSampled) } func testSerialize() { diff --git a/Utils/VersionBump/.swiftlint.yml b/Utils/VersionBump/.swiftlint.yml new file mode 100755 index 00000000000..46dae46e4f1 --- /dev/null +++ b/Utils/VersionBump/.swiftlint.yml @@ -0,0 +1,5 @@ +parent_config: ../.swiftlint.yml + +disabled_rules: + - force_try + From 4be2b3cc4896d43b6bbd2cd141e39367c5da4325 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 6 Jun 2023 17:38:00 +0200 Subject: [PATCH 18/26] ci: Fix running profile data generator (#3088) Roll back to macos-12 with Xcode 13.4.1. --- .github/workflows/profile-data-generator.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/profile-data-generator.yml b/.github/workflows/profile-data-generator.yml index b09d4fcfc07..b87dbf50a79 100644 --- a/.github/workflows/profile-data-generator.yml +++ b/.github/workflows/profile-data-generator.yml @@ -8,14 +8,15 @@ on: paths: - 'Sources/Sentry/Public/**' - 'Samples/TrendingMovies/**' + - '.github/workflows/profile-data-generator.yml' jobs: build-profile-data-generator-targets: name: Build app and test runner - runs-on: macos-13 + runs-on: macos-12 steps: - uses: actions/checkout@v3 - - run: ./scripts/ci-select-xcode.sh + - run: ./scripts/ci-select-xcode.sh 13.4.1 - name: Install SentryCli run: brew install getsentry/tools/sentry-cli - name: Cache Carthage dependencies From 29e126421d84c8380a3a0854d5398e6aeb8ed8f9 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 6 Jun 2023 17:40:35 +0200 Subject: [PATCH 19/26] chore: Update brewfile lock (#3086) Update clang-format from 16.0.1 to 16.0.5, swiftlint from 0.51.0 to 0.52.2, pre-commit from 3.2.2 to 3.3.2. --- Brewfile.lock.json | 90 +++++++++---------- ...SentryUIViewControllerSwizzlingTests.swift | 1 - 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/Brewfile.lock.json b/Brewfile.lock.json index a7f4c281bd6..7774d15e906 100644 --- a/Brewfile.lock.json +++ b/Brewfile.lock.json @@ -2,45 +2,45 @@ "entries": { "brew": { "clang-format": { - "version": "16.0.1", + "version": "16.0.5", "bottle": { "rebuild": 0, "root_url": "https://ghcr.io/v2/homebrew/core", "files": { "arm64_ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:dbca9b47fcd77a077009c3a621317f6d71a5a9405b26eaf8d520d744d772f8fc", - "sha256": "dbca9b47fcd77a077009c3a621317f6d71a5a9405b26eaf8d520d744d772f8fc" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:4999701a9b9b1eb6c77a932a3ad4a9cdad3b48e5df2710fbe2245aa4ebef0e74", + "sha256": "4999701a9b9b1eb6c77a932a3ad4a9cdad3b48e5df2710fbe2245aa4ebef0e74" }, "arm64_monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:ac7f3d41d27ee7d73a4b6cde1a4846f804521aa2e0d760081665054336789c37", - "sha256": "ac7f3d41d27ee7d73a4b6cde1a4846f804521aa2e0d760081665054336789c37" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:d97ee31e129cfb18880bc07055fdea534b1249b6fc8d7112fda193d5747e0dc9", + "sha256": "d97ee31e129cfb18880bc07055fdea534b1249b6fc8d7112fda193d5747e0dc9" }, "arm64_big_sur": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:1dbdbf41154048fed19dadab9e2dc0ddba8f00abf9ac9087bbeb7aa8c3558a9c", - "sha256": "1dbdbf41154048fed19dadab9e2dc0ddba8f00abf9ac9087bbeb7aa8c3558a9c" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:df7d7feaac7fae25eab0ce65e041b565afc4e7d8cd5e1fac8df760c0871ccb69", + "sha256": "df7d7feaac7fae25eab0ce65e041b565afc4e7d8cd5e1fac8df760c0871ccb69" }, "ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:4cb18af7045788305bf95f884d6b8c92dd9531a5c516b353b9be9e660d69cebe", - "sha256": "4cb18af7045788305bf95f884d6b8c92dd9531a5c516b353b9be9e660d69cebe" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:24289ea7db364c5bd80436b23d6b57ff2eceadb6eb2d642c4923a06a3d7e0991", + "sha256": "24289ea7db364c5bd80436b23d6b57ff2eceadb6eb2d642c4923a06a3d7e0991" }, "monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:c0e6a1315527c5288357b75f40c21878dd247a34c73305d51a5d63b44b6cdeb7", - "sha256": "c0e6a1315527c5288357b75f40c21878dd247a34c73305d51a5d63b44b6cdeb7" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:ea03ccb84e28e3dc33ce784a46c370541dedf384f6cf0a0b6c92516428b089f9", + "sha256": "ea03ccb84e28e3dc33ce784a46c370541dedf384f6cf0a0b6c92516428b089f9" }, "big_sur": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:1ba739d546f0c4e0393ff109b7db573b9e3aa810ceaabe4d6149dfefff758791", - "sha256": "1ba739d546f0c4e0393ff109b7db573b9e3aa810ceaabe4d6149dfefff758791" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:d9a8507efa7f62a1cdff91a72aebe8e431ae5fdc31d57b2cdaf0bc151bdd7b2c", + "sha256": "d9a8507efa7f62a1cdff91a72aebe8e431ae5fdc31d57b2cdaf0bc151bdd7b2c" }, "x86_64_linux": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:ea55aa3ee0174aac67d9b782636eb6999746f909b0bbbfdf2c14c4cfa1b1bb76", - "sha256": "ea55aa3ee0174aac67d9b782636eb6999746f909b0bbbfdf2c14c4cfa1b1bb76" + "url": "https://ghcr.io/v2/homebrew/core/clang-format/blobs/sha256:fe95f8c1dc10e48d20124d8eb1c5b7c15424a50589f79d1bbccd07718bfd5406", + "sha256": "fe95f8c1dc10e48d20124d8eb1c5b7c15424a50589f79d1bbccd07718bfd5406" } } } @@ -60,35 +60,35 @@ } }, "swiftlint": { - "version": "0.51.0", + "version": "0.52.2", "bottle": { "rebuild": 0, "root_url": "https://ghcr.io/v2/homebrew/core", "files": { "arm64_ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:512ecb595769f901cf75b32313b17a4e670940245ff24f755ff1a3977a15da83", - "sha256": "512ecb595769f901cf75b32313b17a4e670940245ff24f755ff1a3977a15da83" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:1cf375ddb9588a5edc7612a05ecb73bde1d8e0ca275585c4795b2b3a45b6e5ce", + "sha256": "1cf375ddb9588a5edc7612a05ecb73bde1d8e0ca275585c4795b2b3a45b6e5ce" }, "arm64_monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:4341feca59da7d9918517c9017487bd810d4a32d3ea3125323c65f65945c9402", - "sha256": "4341feca59da7d9918517c9017487bd810d4a32d3ea3125323c65f65945c9402" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:bea6bfec66796dc30cc6d73a81b5d2f4acfa7e4b87c2275a1d0c5cf0bf674757", + "sha256": "bea6bfec66796dc30cc6d73a81b5d2f4acfa7e4b87c2275a1d0c5cf0bf674757" }, "ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:2b2ce72f4e9b9f6a9f8014415d7a2662024cf3747f2e0a593375c2b3095e7033", - "sha256": "2b2ce72f4e9b9f6a9f8014415d7a2662024cf3747f2e0a593375c2b3095e7033" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:4bcd696a45d1875da26a4e300b7ca8c278b4c89dd06e3ed4d347eac4408b2ebf", + "sha256": "4bcd696a45d1875da26a4e300b7ca8c278b4c89dd06e3ed4d347eac4408b2ebf" }, "monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:06926e0e327742f4dbbd7528b1a5a847a57227062780ec7502bb0d7e1ad3f9d8", - "sha256": "06926e0e327742f4dbbd7528b1a5a847a57227062780ec7502bb0d7e1ad3f9d8" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:e715578d85f186adf13db75536a27d90bc8e41561a5d3613d2b0d6e71e43829e", + "sha256": "e715578d85f186adf13db75536a27d90bc8e41561a5d3613d2b0d6e71e43829e" }, "x86_64_linux": { "cellar": "/home/linuxbrew/.linuxbrew/Cellar", - "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:ef46916b9f189ce18045273a0a0f2d155a1bb3bea1ac5e1c866f6df080d9dfbf", - "sha256": "ef46916b9f189ce18045273a0a0f2d155a1bb3bea1ac5e1c866f6df080d9dfbf" + "url": "https://ghcr.io/v2/homebrew/core/swiftlint/blobs/sha256:d7a7c638e47bd9b1e1d48eed4ecf747eb4d2462386029cd3d848aa0130513381", + "sha256": "d7a7c638e47bd9b1e1d48eed4ecf747eb4d2462386029cd3d848aa0130513381" } } } @@ -187,45 +187,45 @@ } }, "pre-commit": { - "version": "3.2.2", + "version": "3.3.2", "bottle": { "rebuild": 0, "root_url": "https://ghcr.io/v2/homebrew/core", "files": { "arm64_ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57", - "sha256": "90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:236c394b092cc2f0f6f650ee50b14c3660634f4a3cf6902f8a8cf27227acd929", + "sha256": "236c394b092cc2f0f6f650ee50b14c3660634f4a3cf6902f8a8cf27227acd929" }, "arm64_monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57", - "sha256": "90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:459b8a36eb20d684eea0eff22d47a140900c0a59bb81c19f69fff4f798dc7623", + "sha256": "459b8a36eb20d684eea0eff22d47a140900c0a59bb81c19f69fff4f798dc7623" }, "arm64_big_sur": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57", - "sha256": "90c79ea1e7bd4fb55397c8adcc9ad286450979741e09b7f24de282e4534fbe57" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:1ea75a9334c106db102523cc4c16a33faea8a5594e17ae68a1e04b48055c43e9", + "sha256": "1ea75a9334c106db102523cc4c16a33faea8a5594e17ae68a1e04b48055c43e9" }, "ventura": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286", - "sha256": "a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:a731ce715260980fd09f8baba753047eb4f704779e8b22509bdfe1d0a8b59a9b", + "sha256": "a731ce715260980fd09f8baba753047eb4f704779e8b22509bdfe1d0a8b59a9b" }, "monterey": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286", - "sha256": "a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:89ae87d1b95baa1ee14a020cd8b03f10d37e913b1ad9dabe94e34be623e77d2c", + "sha256": "89ae87d1b95baa1ee14a020cd8b03f10d37e913b1ad9dabe94e34be623e77d2c" }, "big_sur": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286", - "sha256": "a1fc70dbe722cb6f87906b5aba130fc6216aecdacf9ceec6e29cf0a5b331a286" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:80d1060c3b531102f422d0dac9c726a650f6933a3118723c6f4d55ed1100f8a2", + "sha256": "80d1060c3b531102f422d0dac9c726a650f6933a3118723c6f4d55ed1100f8a2" }, "x86_64_linux": { "cellar": ":any_skip_relocation", - "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:ce69251f16c2ec65391afdfb8a5862c691c2b142331cf1a874038da29a0a5242", - "sha256": "ce69251f16c2ec65391afdfb8a5862c691c2b142331cf1a874038da29a0a5242" + "url": "https://ghcr.io/v2/homebrew/core/pre-commit/blobs/sha256:45d757989b4610fb0a48ef96c268f20541f09ce971dee33070b9a1878e87f687", + "sha256": "45d757989b4610fb0a48ef96c268f20541f09ce971dee33070b9a1878e87f687" } } } @@ -287,12 +287,12 @@ "macOS": "12.6" }, "ventura": { - "HOMEBREW_VERSION": "4.0.14", + "HOMEBREW_VERSION": "4.0.21", "HOMEBREW_PREFIX": "/opt/homebrew", "Homebrew/homebrew-core": "api", - "CLT": "14.3.0.0.1.1679647830", - "Xcode": "14.3", - "macOS": "13.3.1" + "CLT": "14.3.1.0.1.1683849156", + "Xcode": "14.3.1", + "macOS": "13.4" } } } diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift index 3163fb4d551..d24e0ff4524 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift @@ -289,7 +289,6 @@ class MockApplication: NSObject, SentryUIApplicationProtocol { // swiftlint:disable prohibited_super_call class ViewWithLoadViewController: UIViewController { override func loadView() { - super.loadView() // empty on purpose } } From 31ac4381c380e8fd5d91fa07562d3a3bb2c3cf72 Mon Sep 17 00:00:00 2001 From: Philipp Hofmann Date: Tue, 6 Jun 2023 17:42:17 +0200 Subject: [PATCH 20/26] chore: Run Linters as pre commit check (#3087) Run make lint as a pre-commit check. --- .pre-commit-config.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 64b8ddc279c..54ae71c236f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,6 +38,14 @@ repos: args: - "format-swift" + - id: lint + name: Run Linters + entry: make + language: system + types_or: ["swift", "objective-c", "objective-c++", "c", "c++" ] + args: + - "lint" + - id: no-changes-in-high-risk-files name: No Changes in High Risk Files entry: make From 60dd0f5656d961f9a9d604ceaf8dd5d99efd393d Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Wed, 7 Jun 2023 11:24:02 +0200 Subject: [PATCH 21/26] fix: SentryUIViewControllerSwizzlingTests (#3089) Fixed SentryUIViewControllerSwizzlingTests because it broke with latest swift/xcode updates --- Sources/Sentry/SentryNSProcessInfoWrapper.mm | 24 +++++++++++++++++-- .../include/SentryNSProcessInfoWrapper.h | 4 ++++ ...SentryUIViewControllerSwizzlingTests.swift | 4 ++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Sources/Sentry/SentryNSProcessInfoWrapper.mm b/Sources/Sentry/SentryNSProcessInfoWrapper.mm index d92bc3bace4..3c0b842fb73 100644 --- a/Sources/Sentry/SentryNSProcessInfoWrapper.mm +++ b/Sources/Sentry/SentryNSProcessInfoWrapper.mm @@ -1,6 +1,26 @@ #import "SentryNSProcessInfoWrapper.h" -@implementation SentryNSProcessInfoWrapper +@implementation SentryNSProcessInfoWrapper { +#if TEST + NSString *_executablePath; +} +- (void)setProcessPath:(NSString *)path +{ + _executablePath = path; +} +# define EXECUTABLE_PATH _executablePath; + +- (instancetype)init +{ + self = [super init]; + _executablePath = NSBundle.mainBundle.bundlePath; + return self; +} + +#else +} +# define EXECUTABLE_PATH NSBundle.mainBundle.executablePath; +#endif + (SentryNSProcessInfoWrapper *)shared { @@ -17,7 +37,7 @@ - (NSString *)processDirectoryPath - (NSString *)processPath { - return NSBundle.mainBundle.executablePath; + return EXECUTABLE_PATH; } - (NSUInteger)processorCount diff --git a/Sources/Sentry/include/SentryNSProcessInfoWrapper.h b/Sources/Sentry/include/SentryNSProcessInfoWrapper.h index 8263bd33075..ab3be20a061 100644 --- a/Sources/Sentry/include/SentryNSProcessInfoWrapper.h +++ b/Sources/Sentry/include/SentryNSProcessInfoWrapper.h @@ -8,6 +8,10 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, nonatomic, readonly) NSString *processPath; @property (readonly) NSUInteger processorCount; +#if TEST +- (void)setProcessPath:(NSString *)path; +#endif + @end NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift index d24e0ff4524..f159e4e24e6 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryUIViewControllerSwizzlingTests.swift @@ -88,6 +88,9 @@ class SentryUIViewControllerSwizzlingTests: XCTestCase { } func testViewControllerWithLoadView_TransactionBoundToScope() { + let d = class_getImageName(type(of: self))! + fixture.processInfoWrapper.setProcessPath(String(cString: d)) + fixture.sut.start() let controller = ViewWithLoadViewController() @@ -328,6 +331,7 @@ class TestSubClassFinder: SentrySubClassFinder { var invocations = Invocations<(imageName: String, block: (AnyClass) -> Void)>() override func actOnSubclassesOfViewController(inImage imageName: String, block: @escaping (AnyClass) -> Void) { invocations.record((imageName, block)) + super.actOnSubclassesOfViewController(inImage: imageName, block: block) } } From 9fa5d2786900a303bf419b3adcbf2810c0bb8c14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 08:58:55 +0200 Subject: [PATCH 22/26] build(deps): bump github/codeql-action from 2.3.6 to 2.13.4 (#3093) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.3.6 to 2.13.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/83f0fe6c4988d98a455712a27f0255212bba9bd4...cdcdbb579706841c47f7063dda365e292e5cad7a) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e6540480ac7..33e191a4f92 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v3 - name: Initialize CodeQL - uses: github/codeql-action/init@83f0fe6c4988d98a455712a27f0255212bba9bd4 # pin@v2 + uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # pin@v2 with: languages: ${{ matrix.language }} @@ -37,4 +37,4 @@ jobs: -destination platform="iOS Simulator,OS=latest,name=iPhone 14 Pro" | xcpretty && exit ${PIPESTATUS[0]} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@83f0fe6c4988d98a455712a27f0255212bba9bd4 # pin@v2 + uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # pin@v2 From bfa34879a6aca231223b0b3070bc27fab68a70cf Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Wed, 14 Jun 2023 16:45:57 +0200 Subject: [PATCH 23/26] Update SentryNSProcessInfoWrapper.mm (#3096) --- Sources/Sentry/SentryNSProcessInfoWrapper.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Sentry/SentryNSProcessInfoWrapper.mm b/Sources/Sentry/SentryNSProcessInfoWrapper.mm index 3c0b842fb73..87b289041e0 100644 --- a/Sources/Sentry/SentryNSProcessInfoWrapper.mm +++ b/Sources/Sentry/SentryNSProcessInfoWrapper.mm @@ -8,7 +8,7 @@ - (void)setProcessPath:(NSString *)path { _executablePath = path; } -# define EXECUTABLE_PATH _executablePath; +# define SENTRY_BINARY_EXECUTABLE_PATH _executablePath; - (instancetype)init { @@ -19,7 +19,7 @@ - (instancetype)init #else } -# define EXECUTABLE_PATH NSBundle.mainBundle.executablePath; +# define SENTRY_BINARY_EXECUTABLE_PATH NSBundle.mainBundle.executablePath; #endif + (SentryNSProcessInfoWrapper *)shared @@ -37,7 +37,7 @@ - (NSString *)processDirectoryPath - (NSString *)processPath { - return EXECUTABLE_PATH; + return SENTRY_BINARY_EXECUTABLE_PATH; } - (NSUInteger)processorCount From 253bb7145527585db28fe308f7eeeef63cd1266a Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Wed, 14 Jun 2023 16:54:00 +0200 Subject: [PATCH 24/26] Update CHANGELOG.md (#3097) --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a3db85a0fb..a2d88e8e01e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,16 @@ ### Fixes - Fix a data race for `SentryId.empty` (#3072) -- Changed `Trace` serialized value of `sampled` from string to boolean (#3067) - Duplicated HTTP breadcrumbs (#3058) - Expose SentryPrivate and SentrySwiftUI schemes for cartahge clients that have `--no-use-binaries` option (#3071) - Convert last remaining `sprintf` call to `snprintf` (#3077) +## 8.7.4 + +### Fixes + +- Changed `Trace` serialized value of `sampled` from string to boolean (#3067) + ### Breaking Changes - Removed `nameForSentrySampleDecision` which shouldn't have been public (#3067) From 3eb2a52d9b476f1ca690dc95b1671bd7d627e193 Mon Sep 17 00:00:00 2001 From: Andrew McKnight Date: Wed, 14 Jun 2023 11:08:23 -0800 Subject: [PATCH 25/26] fix: avoid inserting a nil into the gpu data dictionary literal (#3092) --- CHANGELOG.md | 1 + Sources/Sentry/SentryProfiler.mm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2d88e8e01e..e04b404a96b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Duplicated HTTP breadcrumbs (#3058) - Expose SentryPrivate and SentrySwiftUI schemes for cartahge clients that have `--no-use-binaries` option (#3071) - Convert last remaining `sprintf` call to `snprintf` (#3077) +- Fix a crash when serializing profiling data (#3092) ## 8.7.4 diff --git a/Sources/Sentry/SentryProfiler.mm b/Sources/Sentry/SentryProfiler.mm index 1e1c707d4c6..899ff4f7e65 100644 --- a/Sources/Sentry/SentryProfiler.mm +++ b/Sources/Sentry/SentryProfiler.mm @@ -143,7 +143,7 @@ @"value" : obj[@"value"], }]; }]; - if (useMostRecentRecording && slicedGPUEntries.count == 0) { + if (useMostRecentRecording && slicedGPUEntries.count == 0 && nearestPredecessorValue != nil) { [slicedGPUEntries addObject:@ { @"elapsed_since_start_ns" : @"0", @"value" : nearestPredecessorValue, From d277532e1c8af813981ba01f591b15bbdd735615 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 14 Jun 2023 19:22:21 +0000 Subject: [PATCH 26/26] release: 8.8.0 --- CHANGELOG.md | 2 +- Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj | 8 ++++---- Sentry.podspec | 4 ++-- SentryPrivate.podspec | 2 +- SentrySwiftUI.podspec | 4 ++-- Sources/Configuration/Sentry.xcconfig | 2 +- Sources/Configuration/SentryPrivate.xcconfig | 2 +- Sources/Sentry/SentryMeta.m | 2 +- Tests/HybridSDKTest/HybridPod.podspec | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e04b404a96b..4481f795692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 8.8.0 ### Features diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj index d6309148c37..88a5fb107dd 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj @@ -1196,7 +1196,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.7.3; + MARKETING_VERSION = 8.8.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Development io.sentry.sample.iOS-Swift"; @@ -1225,7 +1225,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.7.3; + MARKETING_VERSION = 8.8.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift"; @@ -1870,7 +1870,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.7.3; + MARKETING_VERSION = 8.8.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match Development io.sentry.sample.iOS-Swift.Clip"; @@ -1905,7 +1905,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 8.7.3; + MARKETING_VERSION = 8.8.0; PRODUCT_BUNDLE_IDENTIFIER = "io.sentry.sample.iOS-Swift.Clip"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore io.sentry.sample.iOS-Swift.Clip"; diff --git a/Sentry.podspec b/Sentry.podspec index 119cf157316..be7758cc5ad 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sentry" - s.version = "8.7.3" + s.version = "8.8.0" s.summary = "Sentry client for cocoa" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -27,7 +27,7 @@ Pod::Spec.new do |s| } s.default_subspecs = ['Core'] - s.dependency "SentryPrivate", "8.7.3" + s.dependency "SentryPrivate", "8.8.0" s.subspec 'Core' do |sp| sp.source_files = "Sources/Sentry/**/*.{h,hpp,m,mm,c,cpp}", diff --git a/SentryPrivate.podspec b/SentryPrivate.podspec index c7b151ba298..4120fac7bfc 100644 --- a/SentryPrivate.podspec +++ b/SentryPrivate.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentryPrivate" - s.version = "8.7.3" + s.version = "8.8.0" s.summary = "Sentry Private Library." s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" diff --git a/SentrySwiftUI.podspec b/SentrySwiftUI.podspec index 702cfad49fd..6ac2c60936b 100644 --- a/SentrySwiftUI.podspec +++ b/SentrySwiftUI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentrySwiftUI" - s.version = "8.7.3" + s.version = "8.8.0" s.summary = "Sentry client for SwiftUI" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -19,5 +19,5 @@ Pod::Spec.new do |s| s.watchos.framework = 'WatchKit' s.source_files = "Sources/SentrySwiftUI/**/*.{swift,h,m}" - s.dependency 'Sentry', "8.7.3" + s.dependency 'Sentry', "8.8.0" end diff --git a/Sources/Configuration/Sentry.xcconfig b/Sources/Configuration/Sentry.xcconfig index f48d7bd5eb8..0ddfa3a9e47 100644 --- a/Sources/Configuration/Sentry.xcconfig +++ b/Sources/Configuration/Sentry.xcconfig @@ -2,6 +2,6 @@ PRODUCT_NAME = Sentry INFOPLIST_FILE = Sources/Sentry/Info.plist PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry -CURRENT_PROJECT_VERSION = 8.7.3 +CURRENT_PROJECT_VERSION = 8.8.0 MODULEMAP_FILE = $(SRCROOT)/Sources/Sentry/Sentry.modulemap diff --git a/Sources/Configuration/SentryPrivate.xcconfig b/Sources/Configuration/SentryPrivate.xcconfig index 0d3dadd0489..a9a6a78dc4e 100644 --- a/Sources/Configuration/SentryPrivate.xcconfig +++ b/Sources/Configuration/SentryPrivate.xcconfig @@ -1,3 +1,3 @@ PRODUCT_NAME = SentryPrivate MACH_O_TYPE = staticlib -CURRENT_PROJECT_VERSION = 8.7.3 +CURRENT_PROJECT_VERSION = 8.8.0 diff --git a/Sources/Sentry/SentryMeta.m b/Sources/Sentry/SentryMeta.m index a0be151f83d..b9c3d59df00 100644 --- a/Sources/Sentry/SentryMeta.m +++ b/Sources/Sentry/SentryMeta.m @@ -5,7 +5,7 @@ @implementation SentryMeta // Don't remove the static keyword. If you do the compiler adds the constant name to the global // symbol table and it might clash with other constants. When keeping the static keyword the // compiler replaces all occurrences with the value. -static NSString *versionString = @"8.7.3"; +static NSString *versionString = @"8.8.0"; static NSString *sdkName = @"sentry.cocoa"; + (NSString *)versionString diff --git a/Tests/HybridSDKTest/HybridPod.podspec b/Tests/HybridSDKTest/HybridPod.podspec index e48d594bd6c..80c3983e91c 100644 --- a/Tests/HybridSDKTest/HybridPod.podspec +++ b/Tests/HybridSDKTest/HybridPod.podspec @@ -13,6 +13,6 @@ Pod::Spec.new do |s| s.requires_arc = true s.frameworks = 'Foundation' s.swift_versions = "5.5" - s.dependency "Sentry/HybridSDK", "8.7.3" + s.dependency "Sentry/HybridSDK", "8.8.0" s.source_files = "HybridTest.swift" end