diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cc59b8f81..310d274d47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Features
+
+- Auto-suppress `SIGABRT` for uncaught managed exceptions on iOS ([#4523](https://github.com/getsentry/sentry-dotnet/pull/4523))
+
### Fixes
- Fail when building Blazor WASM with Profiling. We don't support profiling in Blazor WebAssembly projects. ([#4512](https://github.com/getsentry/sentry-dotnet/pull/4512))
diff --git a/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs b/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs
index 396221cb79..4ffee1a827 100644
--- a/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs
+++ b/src/Sentry/Platforms/Cocoa/RuntimeMarshalManagedExceptionIntegration.cs
@@ -32,6 +32,11 @@ internal void Handle(object sender, MarshalManagedExceptionEventArgs e)
if (e.Exception is { } ex)
{
+ // The Obj-C runtime is about to abort. Tag the upcoming duplicate native SIGABRT event for filtering it
+ // out in ProcessOnBeforeSend.
+ // TODO: define "_captured_by_sentry-dotnet" as a constant somewhere
+ SentryCocoaSdk.ConfigureScope(scope => scope.SetTagValue("SIGABRT", "_captured_by_sentry-dotnet"));
+
ex.SetSentryMechanism(
"Runtime.MarshalManagedException",
"This exception was caught by the .NET Runtime Marshal Managed Exception global error handler. " +
diff --git a/src/Sentry/Platforms/Cocoa/SentryOptions.cs b/src/Sentry/Platforms/Cocoa/SentryOptions.cs
index 02ce449556..50a87e5b92 100644
--- a/src/Sentry/Platforms/Cocoa/SentryOptions.cs
+++ b/src/Sentry/Platforms/Cocoa/SentryOptions.cs
@@ -207,11 +207,12 @@ internal NativeOptions(SentryOptions options)
/// convenient.
///
///
+ /// TODO: Explain auto (null) vs. true vs. false.
/// Enabling this may prevent the capture of SIGABRT originating from native (not managed) code... so it may
/// prevent the capture of genuine native SIGABRT errors.
///
///
- public bool SuppressSignalAborts { get; set; } = false;
+ public bool? SuppressSignalAborts { get; set; } = null;
///
///
diff --git a/src/Sentry/Platforms/Cocoa/SentrySdk.cs b/src/Sentry/Platforms/Cocoa/SentrySdk.cs
index 9cd167dc0e..8cb5b41a85 100644
--- a/src/Sentry/Platforms/Cocoa/SentrySdk.cs
+++ b/src/Sentry/Platforms/Cocoa/SentrySdk.cs
@@ -200,25 +200,28 @@ private static CocoaSdk.SentryHttpStatusCodeRange[] GetFailedRequestStatusCodes(
///
internal static CocoaSdk.SentryEvent? ProcessOnBeforeSend(SentryOptions options, CocoaSdk.SentryEvent evt, IHub hub)
{
- if (hub is DisabledHub)
- {
- return evt;
- }
-
// When we have an unhandled managed exception, we send that to Sentry twice - once managed and once native.
// The managed exception is what a .NET developer would expect, and it is sent by the Sentry.NET SDK
// But we also get a native SIGABRT since it crashed the application, which is sent by the Sentry Cocoa SDK.
// There should only be one exception on the event in this case
- if ((options.Native.SuppressSignalAborts || options.Native.SuppressExcBadAccess) && evt.Exceptions?.Length == 1)
+ if (evt.Exceptions?.Length == 1)
{
// It will match the following characteristics
var ex = evt.Exceptions[0];
+ // TODO: define "_captured_by_sentry-dotnet" as a constant somewhere
+ if (options.Native.SuppressSignalAborts == null && ex.Type == evt.Tags?["_captured_by_sentry-dotnet"]?.ToString())
+ {
+ options.LogDebug("Discarded {0} error ({1}). Captured as managed exception instead.", ex.Type,
+ ex.Value);
+ return null;
+ }
+
// Thankfully, sometimes we can see Xamarin's unhandled exception handler on the stack trace, so we can filter
// them out. Here is the function that calls abort(), which we will use as a filter:
// https://github.com/xamarin/xamarin-macios/blob/c55fbdfef95028ba03d0f7a35aebca03bd76f852/runtime/runtime.m#L1114-L1122
- if (options.Native.SuppressSignalAborts && ex.Type == "SIGABRT" && ex.Value == "Signal 6, Code 0" &&
+ if (options.Native.SuppressSignalAborts == true && ex.Type == "SIGABRT" && ex.Value == "Signal 6, Code 0" &&
ex.Stacktrace?.Frames.Any(f => f.Function == "xamarin_unhandled_exception_handler") is true)
{
// Don't send it
@@ -239,6 +242,11 @@ private static CocoaSdk.SentryHttpStatusCodeRange[] GetFailedRequestStatusCodes(
}
}
+ if (hub is DisabledHub)
+ {
+ return evt;
+ }
+
// We run our SIGABRT checks first before running managed processors.
// Because we delegate to user code, we need to catch/log exceptions.
try