From fd7d01a7cc1839edd925f5105e1a11acbef9917e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 13 Apr 2026 09:21:31 +0200 Subject: [PATCH 1/2] chore(deps): bump sentry-cocoa to 9.10.0 --- modules/sentry-cocoa | 2 +- src/Sentry.Bindings.Cocoa/ApiDefinitions.cs | 33 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/sentry-cocoa b/modules/sentry-cocoa index d459ff99b1..3a22ecd00a 160000 --- a/modules/sentry-cocoa +++ b/modules/sentry-cocoa @@ -1 +1 @@ -Subproject commit d459ff99b1912c9603c9e607e030b4b98e2e199a +Subproject commit 3a22ecd00ad1398747bfd587e44df82716908dd3 diff --git a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs index e1137149e8..9a56e35d80 100644 --- a/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs +++ b/src/Sentry.Bindings.Cocoa/ApiDefinitions.cs @@ -158,6 +158,10 @@ interface SentryBaggage [NullAllowed, Export("replayId", ArgumentSemantic.Strong)] string ReplayId { get; set; } + // @property (readonly, nonatomic) NSString * _Nullable orgId; + [NullAllowed, Export("orgId")] + string OrgId { get; } + // -(instancetype _Nonnull)initWithTraceId:(SentryId * _Nonnull)traceId publicKey:(NSString * _Nonnull)publicKey releaseName:(NSString * _Nullable)releaseName environment:(NSString * _Nullable)environment transaction:(NSString * _Nullable)transaction sampleRate:(NSString * _Nullable)sampleRate sampled:(NSString * _Nullable)sampled replayId:(NSString * _Nullable)replayId; [Export("initWithTraceId:publicKey:releaseName:environment:transaction:sampleRate:sampled:replayId:")] NativeHandle Constructor(SentryId traceId, string publicKey, [NullAllowed] string releaseName, [NullAllowed] string environment, [NullAllowed] string transaction, [NullAllowed] string sampleRate, [NullAllowed] string sampled, [NullAllowed] string replayId); @@ -166,6 +170,10 @@ interface SentryBaggage [Export("initWithTraceId:publicKey:releaseName:environment:transaction:sampleRate:sampleRand:sampled:replayId:")] NativeHandle Constructor(SentryId traceId, string publicKey, [NullAllowed] string releaseName, [NullAllowed] string environment, [NullAllowed] string transaction, [NullAllowed] string sampleRate, [NullAllowed] string sampleRand, [NullAllowed] string sampled, [NullAllowed] string replayId); + // -(instancetype _Nonnull)initWithTraceId:(SentryId * _Nonnull)traceId publicKey:(NSString * _Nonnull)publicKey releaseName:(NSString * _Nullable)releaseName environment:(NSString * _Nullable)environment transaction:(NSString * _Nullable)transaction sampleRate:(NSString * _Nullable)sampleRate sampleRand:(NSString * _Nullable)sampleRand sampled:(NSString * _Nullable)sampled replayId:(NSString * _Nullable)replayId orgId:(NSString * _Nullable)orgId; + [Export("initWithTraceId:publicKey:releaseName:environment:transaction:sampleRate:sampleRand:sampled:replayId:orgId:")] + NativeHandle Constructor(SentryId traceId, string publicKey, [NullAllowed] string releaseName, [NullAllowed] string environment, [NullAllowed] string transaction, [NullAllowed] string sampleRate, [NullAllowed] string sampleRand, [NullAllowed] string sampled, [NullAllowed] string replayId, [NullAllowed] string orgId); + // -(NSString * _Nonnull)toHTTPHeaderWithOriginalBaggage:(NSDictionary * _Nullable)originalBaggage; [Export("toHTTPHeaderWithOriginalBaggage:")] string ToHTTPHeaderWithOriginalBaggage([NullAllowed] NSDictionary originalBaggage); @@ -1368,6 +1376,10 @@ interface SentryTraceContext : SentrySerializable [NullAllowed, Export("replayId")] string ReplayId { get; } + // @property (readonly, nonatomic) NSString * _Nullable orgId; + [NullAllowed, Export("orgId")] + string OrgId { get; } + // -(SentryBaggage * _Nonnull)toBaggage; [Export("toBaggage")] SentryBaggage ToBaggage(); @@ -1656,6 +1668,11 @@ interface PrivateSentrySDKOnly [Static] [Export("setLogOutput:")] void SetLogOutput(Action output); + + // +(void)ignoreNextSignal:(int)signum; + [Static] + [Export("ignoreNextSignal:")] + void IgnoreNextSignal(int signum); } // @interface SentryOptions : NSObject @@ -1987,6 +2004,18 @@ interface SentryOptions [Export("spotlightUrl")] string SpotlightUrl { get; set; } + // @property (nonatomic) BOOL strictTraceContinuation; + [Export("strictTraceContinuation")] + bool StrictTraceContinuation { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable orgId; + [NullAllowed, Export("orgId")] + string OrgId { get; set; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable effectiveOrgId; + [NullAllowed, Export("effectiveOrgId")] + string EffectiveOrgId { get; } + // @property (nonatomic, strong) SentryExperimentalOptions * _Nonnull experimental; [Export("experimental", ArgumentSemantic.Strong)] SentryExperimentalOptions Experimental { get; set; } @@ -2129,6 +2158,10 @@ interface SentryDsn // -(NSURL * _Nonnull)getEnvelopeEndpoint __attribute__((warn_unused_result(""))); [Export("getEnvelopeEndpoint")] NSUrl EnvelopeEndpoint { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable orgId; + [NullAllowed, Export("orgId")] + string OrgId { get; } } // @interface SentryExperimentalOptions : NSObject From dc98de1c1a257f42a3132688cfc99e75b2bd3031 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 24 Mar 2026 16:36:27 +0100 Subject: [PATCH 2/2] fix(ios): preload Cocoa crash handlers for managed runtime interop - Build sentry-cocoa with SENTRY_CRASH_MANAGED_RUNTIME to preload signal handlers and exclude EXC_BAD_ACCESS/EXC_ARITHMETIC from Mach monitoring - Call PrivateSentrySDKOnly.IgnoreNextSignal(SIGABRT) from MarshalManagedException to prevent duplicate native crash events - Update iOS integration tests to expect no duplicate events (#3954) Co-Authored-By: Claude Opus 4.6 (1M context) --- integration-test/ios.Tests.ps1 | 16 +++++----------- scripts/build-sentry-cocoa.sh | 9 ++++++--- .../RuntimeMarshalManagedExceptionIntegration.cs | 6 ++++++ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/integration-test/ios.Tests.ps1 b/integration-test/ios.Tests.ps1 index 3c38696f69..7ec6eee0b5 100644 --- a/integration-test/ios.Tests.ps1 +++ b/integration-test/ios.Tests.ps1 @@ -99,9 +99,8 @@ Describe 'iOS app (, )' -ForEach @( $result.HasErrors() | Should -BeFalse $result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.ApplicationException`"" - # TODO: fix redundant SIGABRT (#3954) - { $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGABRT`"" } | Should -Throw - { $result.Envelopes() | Should -HaveCount 1 } | Should -Throw + $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`"" + $result.Envelopes() | Should -HaveCount 1 } It 'captures native crash ()' { @@ -112,7 +111,7 @@ Describe 'iOS app (, )' -ForEach @( } $result.HasErrors() | Should -BeFalse - $result.Envelopes() | Should -AnyElementMatch "`"type`":`"EXC_[A-Z_]+`"" + $result.Envelopes() | Should -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`"" $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"System.\w+Exception`"" $result.Envelopes() | Should -HaveCount 1 } @@ -126,12 +125,7 @@ Describe 'iOS app (, )' -ForEach @( $result.HasErrors() | Should -BeFalse $result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.NullReferenceException`"" - # TODO: fix redundant EXC_BAD_ACCESS in Release (#3954) - if ($configuration -eq 'Release') { - { $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"EXC_BAD_ACCESS`"" } | Should -Throw - } else { - $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"EXC_BAD_ACCESS`"" - $result.Envelopes() | Should -HaveCount 1 - } + $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"(EXC_[A-Z_]+|SIG[A-Z]+)`"" + $result.Envelopes() | Should -HaveCount 1 } } diff --git a/scripts/build-sentry-cocoa.sh b/scripts/build-sentry-cocoa.sh index 6e18143f1a..f3ef2b7558 100755 --- a/scripts/build-sentry-cocoa.sh +++ b/scripts/build-sentry-cocoa.sh @@ -50,7 +50,8 @@ xcodebuild archive -project Sentry.xcodeproj \ -sdk "$ios_sdk" \ -archivePath ./Carthage/output-ios.xcarchive \ SKIP_INSTALL=NO \ - BUILD_LIBRARY_FOR_DISTRIBUTION=YES + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1' ./scripts/remove-architectures.sh ./Carthage/output-ios.xcarchive arm64e xcodebuild archive -project Sentry.xcodeproj \ -scheme Sentry \ @@ -58,7 +59,8 @@ xcodebuild archive -project Sentry.xcodeproj \ -sdk "$ios_simulator_sdk" \ -archivePath ./Carthage/output-iossimulator.xcarchive \ SKIP_INSTALL=NO \ - BUILD_LIBRARY_FOR_DISTRIBUTION=YES + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1' xcodebuild -create-xcframework \ -framework ./Carthage/output-ios.xcarchive/Products/Library/Frameworks/Sentry.framework \ -framework ./Carthage/output-iossimulator.xcarchive/Products/Library/Frameworks/Sentry.framework \ @@ -73,7 +75,8 @@ xcodebuild archive -project Sentry.xcodeproj \ -destination 'generic/platform=macOS,variant=Mac Catalyst' \ -archivePath ./Carthage/output-maccatalyst.xcarchive \ SKIP_INSTALL=NO \ - BUILD_LIBRARY_FOR_DISTRIBUTION=YES + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + GCC_PREPROCESSOR_DEFINITIONS='$(inherited) SENTRY_CRASH_MANAGED_RUNTIME=1' ./scripts/remove-architectures.sh ./Carthage/output-maccatalyst.xcarchive arm64e xcodebuild -create-xcframework \ -framework ./Carthage/output-maccatalyst.xcarchive/Products/Library/Frameworks/Sentry.framework \ diff --git a/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs b/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs index 396221cb79..5397a2c0d4 100644 --- a/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs +++ b/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs @@ -43,6 +43,12 @@ internal void Handle(object sender, MarshalManagedExceptionEventArgs e) // This is likely a terminal exception so try to send the crash report before shutting down _hub?.Flush(); + + // The Xamarin runtime will call abort() after this handler returns, which raises + // SIGABRT. Tell SentryCrash to ignore it on this thread so we don't get a duplicate + // native crash event for a managed exception we've already captured. + const int SIGABRT = 6; + SentryCocoaHybridSdk.IgnoreNextSignal(SIGABRT); } } }