From e2d10039c0fe8fc12aac9de21280ccbd14aac11a Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Mon, 27 Oct 2025 12:29:20 +0100 Subject: [PATCH 1/3] feat: allow configuring native signal handler strategy on Android --- integration-test/android.Tests.ps1 | 9 ++------- integration-test/net9-maui/MauiProgram.cs | 1 + .../Android/BindableNativeSentryOptions.cs | 4 ++++ src/Sentry/Platforms/Android/NativeOptions.cs | 9 +++++++++ src/Sentry/Platforms/Android/SentrySdk.cs | 6 +++++- .../Android/SignalHandlerStrategy.cs | 19 +++++++++++++++++++ 6 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/Sentry/Platforms/Android/SignalHandlerStrategy.cs 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 +} From 543b3e36088d66cf081298aa9c8f505af1580f69 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Fri, 2 Jan 2026 15:56:43 +0100 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d113a93e..3e654bc6b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Extended `SentryThread` by `Main` to allow indication whether the thread is considered the current main thread ([#4807](https://github.com/getsentry/sentry-dotnet/pull/4807)) +- Allow configuring native signal handler strategy on Android ([#4676](https://github.com/getsentry/sentry-dotnet/pull/4676)) ## 6.0.0 From bda8f1baf1fc095a9a0787e6e888278244d3a583 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 10 Feb 2026 21:42:05 +0100 Subject: [PATCH 3/3] Try what happens with 10.0.103 --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 4264d6fe6c..b4a89d2d6e 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "10.0.102", - "workloadVersion": "10.0.101.1", + "version": "10.0.103", + "workloadVersion": "10.0.103", "rollForward": "disable", "allowPrerelease": false }