diff --git a/integration-test/android.Tests.ps1 b/integration-test/android.Tests.ps1 index f7910a5af3..51c9498d09 100644 --- a/integration-test/android.Tests.ps1 +++ b/integration-test/android.Tests.ps1 @@ -169,13 +169,8 @@ Describe 'MAUI app (, )' -ForEach @( Dump-ServerErrors -Result $result $result.HasErrors() | Should -BeFalse $result.Envelopes() | Should -AnyElementMatch "`"type`":`"System.NullReferenceException`"" - # TODO: fix redundant SIGSEGV in Release (#3954) - if ($configuration -eq "Release") { - { $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGSEGV`"" } | Should -Throw - } else { - $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGSEGV`"" - $result.Envelopes() | Should -HaveCount 1 - } + $result.Envelopes() | Should -Not -AnyElementMatch "`"type`":`"SIGSEGV`"" + $result.Envelopes() | Should -HaveCount 1 } It 'Delivers battery breadcrumbs in main thread ()' { diff --git a/integration-test/net9-maui/MauiProgram.cs b/integration-test/net9-maui/MauiProgram.cs index e1c619cdb5..60fe53ac10 100644 --- a/integration-test/net9-maui/MauiProgram.cs +++ b/integration-test/net9-maui/MauiProgram.cs @@ -14,6 +14,7 @@ public static MauiApp CreateMauiApp() { #if ANDROID options.Dsn = "{{SENTRY_DSN}}"; + options.Native.SignalHandlerStrategy = Sentry.Android.SignalHandlerStrategy.ChainAtStart; #endif options.Debug = false; options.DiagnosticLevel = SentryLevel.Error; diff --git a/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs b/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs index f573c1e817..d03f61bd1c 100644 --- a/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs +++ b/src/Sentry/Platforms/Android/BindableNativeSentryOptions.cs @@ -1,3 +1,5 @@ +using Sentry.Android; + // ReSharper disable once CheckNamespace namespace Sentry; @@ -24,6 +26,7 @@ public class NativeOptions public bool? EnableAutoActivityLifecycleTracing { get; set; } public bool? EnableActivityLifecycleTracingAutoFinish { get; set; } public bool? EnableUserInteractionTracing { get; set; } + public SignalHandlerStrategy? SignalHandlerStrategy { get; set; } public bool? AttachThreads { get; set; } public TimeSpan? ConnectionTimeout { get; set; } public bool? EnableNdk { get; set; } @@ -66,6 +69,7 @@ public void ApplyTo(SentryOptions.NativeOptions options) options.EnableAutoActivityLifecycleTracing = EnableAutoActivityLifecycleTracing ?? options.EnableAutoActivityLifecycleTracing; options.EnableActivityLifecycleTracingAutoFinish = EnableActivityLifecycleTracingAutoFinish ?? options.EnableActivityLifecycleTracingAutoFinish; options.EnableUserInteractionTracing = EnableUserInteractionTracing ?? options.EnableUserInteractionTracing; + options.SignalHandlerStrategy = SignalHandlerStrategy ?? options.SignalHandlerStrategy; options.AttachThreads = AttachThreads ?? options.AttachThreads; options.ConnectionTimeout = ConnectionTimeout ?? options.ConnectionTimeout; options.EnableNdk = EnableNdk ?? options.EnableNdk; diff --git a/src/Sentry/Platforms/Android/NativeOptions.cs b/src/Sentry/Platforms/Android/NativeOptions.cs index ea50ff1f81..1ddf57a8e8 100644 --- a/src/Sentry/Platforms/Android/NativeOptions.cs +++ b/src/Sentry/Platforms/Android/NativeOptions.cs @@ -1,3 +1,5 @@ +using Sentry.Android; + // ReSharper disable once CheckNamespace namespace Sentry; @@ -152,6 +154,13 @@ internal NativeOptions(SentryOptions options) /// public bool EnableUserInteractionTracing { get; set; } = false; + /// + /// Gets or sets the strategy for how Sentry Native's signal handler interacts with the CLR/Mono + /// signal handler. + /// The default value is SignalHandlerStrategy.Default (enabled). + /// + public SignalHandlerStrategy SignalHandlerStrategy { get; set; } = SignalHandlerStrategy.Default; + // ---------- From SentryOptions.java ---------- /// diff --git a/src/Sentry/Platforms/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs index 6b92b601ec..2d12ef9ad7 100644 --- a/src/Sentry/Platforms/Android/SentrySdk.cs +++ b/src/Sentry/Platforms/Android/SentrySdk.cs @@ -64,7 +64,11 @@ private static void InitSentryAndroidSdk(SentryOptions options) o.ServerName = options.ServerName; o.SessionTrackingIntervalMillis = (long)options.AutoSessionTrackingInterval.TotalMilliseconds; o.ShutdownTimeoutMillis = (long)options.ShutdownTimeout.TotalMilliseconds; - o.SetNativeHandlerStrategy(JavaSdk.Android.Core.NdkHandlerStrategy.SentryHandlerStrategyDefault); + o.SetNativeHandlerStrategy(options.Native.SignalHandlerStrategy switch + { + SignalHandlerStrategy.ChainAtStart => NdkHandlerStrategy.SentryHandlerStrategyChainAtStart, + _ => NdkHandlerStrategy.SentryHandlerStrategyDefault + }); if (options.CacheDirectoryPath is { } cacheDirectoryPath) { diff --git a/src/Sentry/Platforms/Android/SignalHandlerStrategy.cs b/src/Sentry/Platforms/Android/SignalHandlerStrategy.cs new file mode 100644 index 0000000000..75b84dc8c3 --- /dev/null +++ b/src/Sentry/Platforms/Android/SignalHandlerStrategy.cs @@ -0,0 +1,19 @@ +namespace Sentry.Android; + +/// +/// Defines how Sentry Native's signal handler interacts with the CLR/Mono +/// signal handler. +/// +public enum SignalHandlerStrategy +{ + /// + /// Invokes the CLR/Mono signal handler at the end of Sentry Native's signal + /// handler. + /// + Default, + /// + /// Invokes the CLR/Mono signal handler at the start of Sentry Native's + /// signal handler. + /// + ChainAtStart +}