Skip to content

Commit 2a35e7a

Browse files
jpnurmiclaude
andcommitted
fix(android): preload NDK integration for CoreCLR
Enable the io.sentry.ndk.preload metadata so that SentryNdkPreloadProvider installs sentry-native's signal handlers before .NET/CoreCLR. This ensures the correct handler chain order (.NET -> sentry-native -> debuggerd) where .NET handles managed exceptions first, and native crashes chain to sentry-native. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4c0a863 commit 2a35e7a

5 files changed

Lines changed: 37 additions & 4 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
<Project>
22
<!-- Don't include parent Directory.Build.targets -->
3+
4+
<!-- Needed for SetAndroidNdkPreload (buildTransitive doesn't apply via ProjectReference) -->
5+
<Import Project="../src/Sentry/buildTransitive/Sentry.props" Condition="Exists('../src/Sentry/buildTransitive/Sentry.props')" />
6+
<Import Project="../src/Sentry/buildTransitive/Sentry.targets" Condition="Exists('../src/Sentry/buildTransitive/Sentry.targets')" />
37
</Project>

integration-test/android.Tests.ps1

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ BeforeDiscovery {
1818
}
1919

2020
$cases = @(
21-
@{ configuration = 'Release' }
22-
@{ configuration = 'Debug' }
21+
@{ configuration = 'Release'; runtime = 'mono' }
22+
@{ configuration = 'Release'; runtime = 'coreclr' }
23+
@{ configuration = 'Debug'; runtime = 'mono' }
24+
@{ configuration = 'Debug'; runtime = 'coreclr' }
2325
)
24-
Describe 'MAUI app (<dotnet_version>, <configuration>)' -ForEach $cases -Skip:(-not $script:emulator) {
26+
Describe 'MAUI app (<dotnet_version>, <configuration>, <runtime>)' -ForEach $cases -Skip:(-not $script:emulator) {
2527
BeforeAll {
2628
$tfm = "$dotnet_version-android$(GetAndroidTpv $dotnet_version)"
2729

@@ -38,10 +40,12 @@ Describe 'MAUI app (<dotnet_version>, <configuration>)' -ForEach $cases -Skip:(-
3840
$rid = "android-$arch"
3941

4042
Write-Host "::group::Build Sentry.Maui.Device.IntegrationTestApp.csproj"
43+
$useMonoRuntime = if ($runtime -eq 'mono') { 'true' } else { 'false' }
4144
dotnet build Sentry.Maui.Device.IntegrationTestApp.csproj `
4245
--configuration $configuration `
4346
--framework $tfm `
44-
--runtime $rid
47+
--runtime $rid `
48+
-p:UseMonoRuntime=$useMonoRuntime
4549
| ForEach-Object { Write-Host $_ }
4650
Write-Host '::endgroup::'
4751
$LASTEXITCODE | Should -Be 0

src/Sentry/Platforms/Android/SentrySdk.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ private static void InitSentryAndroidSdk(SentryOptions options)
6565
o.SessionTrackingIntervalMillis = (long)options.AutoSessionTrackingInterval.TotalMilliseconds;
6666
o.ShutdownTimeoutMillis = (long)options.ShutdownTimeout.TotalMilliseconds;
6767
var signalHandlerStrategy = options.Native.ExperimentalOptions.SignalHandlerStrategy;
68+
if (signalHandlerStrategy == SignalHandlerStrategy.ChainAtStart
69+
&& Type.GetType("Mono.RuntimeStructs") == null)
70+
{
71+
options.LogDebug(
72+
"SignalHandlerStrategy.ChainAtStart is not compatible with .NET CoreCLR runtime. " +
73+
"Falling back to SignalHandlerStrategy.Default.");
74+
signalHandlerStrategy = SignalHandlerStrategy.Default;
75+
}
6876
if (signalHandlerStrategy == SignalHandlerStrategy.ChainAtStart
6977
&& System.Environment.Version is { Major: 10, Minor: 0, Build: < 4 })
7078
{

src/Sentry/buildTransitive/Sentry.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
<_SentryTargetFrameworkVersion>$([MSBuild]::GetTargetFrameworkVersion($(TargetFramework)))</_SentryTargetFrameworkVersion>
66
<_SentryIsNet8OrGreater>$([MSBuild]::VersionGreaterThanOrEquals($(_SentryTargetFrameworkVersion), 8.0))</_SentryIsNet8OrGreater>
77
<_SentryIsNet9OrGreater>$([MSBuild]::VersionGreaterThanOrEquals($(_SentryTargetFrameworkVersion), 9.0))</_SentryIsNet9OrGreater>
8+
<_SentryIsNet10OrGreater>$([MSBuild]::VersionGreaterThanOrEquals($(_SentryTargetFrameworkVersion), 10.0))</_SentryIsNet10OrGreater>
89
</PropertyGroup>
910
</Project>

src/Sentry/buildTransitive/Sentry.targets

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@
281281
</ItemGroup>
282282
</Target>
283283

284+
<!-- Preload NDK to ensure sentry-native's signal handlers are installed before .NET runtime's.
285+
Disabled on Mono until: https://github.com/dotnet/runtime/pull/125835 -->
286+
<Target Name="SetAndroidNdkPreload"
287+
BeforeTargets="GetAssemblyAttributes"
288+
Condition="'$(AndroidApplication)' == 'True'
289+
and $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'
290+
and '$(_SentryIsNet10OrGreater)' == 'true'
291+
and '$(UseMonoRuntime)' != 'true'">
292+
<ItemGroup>
293+
<AssemblyAttribute Include="Android.App.MetaData">
294+
<_Parameter1>io.sentry.ndk.preload</_Parameter1>
295+
<Value>true</Value>
296+
</AssemblyAttribute>
297+
</ItemGroup>
298+
</Target>
299+
284300
<!-- Upload Android ProGuard mapping file to Sentry after the build. -->
285301
<Target Name="UploadAndroidProGuardMappingFileToSentry" AfterTargets="Build" DependsOnTargets="PrepareSentryCLI"
286302
Condition="'$(SentryCLI)' != '' and '$(SentryUploadAndroidProGuardMapping)' == 'true' And '$(AndroidProguardMappingFile)' != ''">

0 commit comments

Comments
 (0)