Skip to content

feat: Support reading .NET 11 Android assembly stores - #5577

Open
jamescrosswell wants to merge 7 commits into
feat/assemblystore-zstdfrom
feat/assemblystore-index-sizing
Open

jamescrosswell wants to merge 7 commits into
feat/assemblystore-zstdfrom
feat/assemblystore-index-sizing

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #5575 (itself stacked on #5574) — this PR's diff is only the index-entry sizing change. Together the three PRs make .NET 11 Android APKs readable for symbolication.

Closes #5454

Summary

  • StoreReader.Prepare() inferred the index entry layout from the ABI bitness (64-bit hash on 64-bit ABIs), plus a compile-time #if NET10_0_OR_GREATER for the ignore byte. But upstream's generator picks the hash width by runtime: CoreCLR writes 32-bit CRC32 name hashes on every ABI, MonoVM writes xxHash sized by bitness (AssemblyStoreGenerator.cs). A .NET 11 x86_64 store has 60 entries in 540 bytes — 9 bytes each — so we read past the index and Prepare() threw EndOfStreamException.
  • The entry size is now index_size / index_entry_count, as upstream does. Only the two v3/v4 layouts (9 and 13 bytes) are accepted; anything else, or a size that doesn't divide evenly, throws as a corrupt index. Upstream's v2 layouts are intentionally not ported (v2 support was dropped in feat: add support for .NET 11 preview 7 #5529).
  • The dead #if NET10_0_OR_GREATER branch is gone.
  • Debug images on CoreCLR. Reading the store isn't enough on its own: on .NET 11 Module.FullyQualifiedName is <Unknown> for assemblies loaded from the store, so DebugStackTrace returned before ever calling the assembly reader and events had no debug_meta. When an assembly reader is configured it now falls back to Module.ScopeName (the file name the store is indexed by). Modules that do have a location still pass FullyQualifiedName, so Mono behaviour is unchanged.
  • ATTRIBUTION.txt now records the v3 and v4 upstream sync points, not just the original baseline.

Tests

  • The net11.0 APK tests in AndroidAssemblyReaderTests are re-enabled — 29 run on net11.0 (previously 9); the 8 still skipped are the Mono AOT permutations .NET 11 can't produce.
  • CreatesCorrectArchiveReader now expects an AndroidAssemblyStoreReader on .NET 11: the AndroidUseAssemblyStore=false APK contains only libassembly-store.so, because the CoreCLR host has no non-store fallback since dotnet/android#12033.
  • StoreReaderTests gains a CoreCLR-style v4 64-bit store with 32-bit hashes, plus corrupt-index cases (the 12-byte v2 layout and a non-divisible index size).

Example

Symbolicated stack trace from a .NET 11 app

image

Notes

  • Verified end to end with Sentry.Samples.Android (Release, net11.0-android37.0, arm64 emulator, API 37): the SDK reads the app assembly from the Zstandard-compressed v4 store, the captured event carries a pe_dotnet debug image with the PDB's debug ID, frames have addr_mode/function_id, and the matching PDB is uploaded by the build.
  • That only holds with the default trim mode. With AndroidLinkMode=full (which the Android sample sets) the trimmer rewrites app assemblies, and the Android SDK forces TrimmerRemoveSymbols=true in Release, so the packaged assemblies have no debug ID to report. That's independent of this PR and of .NET 11.
  • Removing the skips also re-enables these tests in the Android device test run, which reads the running app's own .NET 11 APK — that's the first on-device coverage of the whole v4 + Zstandard path.
  • The ELF _assembly_store symbol item was dropped from Port upstream AssemblyStore reader changes: v4/CoreCLR format, _assembly_store symbol, index-entry sizing (next major) #5454 as unnecessary — see this comment.

🤖 Generated with Claude Code

jamescrosswell and others added 4 commits September 14, 2026 16:51
The index entry layout was inferred from the ABI bitness (plus a compile-time
TFM check for the ignore flag). CoreCLR v4 stores use 32-bit CRC32 name
hashes on every ABI, so on 64-bit ABIs the reader read the index 4 bytes per
entry too far and failed in Prepare(). The entry size is now
index_size / index_entry_count, and anything other than the two v3/v4 layouts
is rejected as corrupt.

With this, .NET 11 APKs are readable, so the net11 APK tests are re-enabled.

Refs #5454

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.35294% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.82%. Comparing base (082cf3e) to head (66967da).

Files with missing lines Patch % Lines
...rc/Sentry.Android.AssemblyReader/V2/StoreReader.cs 81.81% 1 Missing and 1 partial ⚠️
src/Sentry/Internal/DebugStackTrace.cs 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           feat/assemblystore-zstd    #5577      +/-   ##
===========================================================
+ Coverage                    74.79%   74.82%   +0.03%     
===========================================================
  Files                          515      515              
  Lines                        18902    18913      +11     
  Branches                      3689     3693       +4     
===========================================================
+ Hits                         14138    14152      +14     
+ Misses                        3887     3885       -2     
+ Partials                       877      876       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jamescrosswell
jamescrosswell added this pull request to stack #5581 September 15, 2026 03:49
jamescrosswell and others added 2 commits September 15, 2026 16:52
On .NET 11 (CoreCLR) Android, assemblies loaded from the assembly store report
Module.FullyQualifiedName as <Unknown>, so DebugStackTrace bailed out before
calling the assembly reader and events had no debug images. When an assembly
reader is configured, fall back to Module.ScopeName, which is the file name
the store is indexed by.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…sizing

Also trims comments.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant