Skip to content

Port upstream AssemblyStore reader changes: v4/CoreCLR format, _assembly_store symbol, index-entry sizing (next major) #5454

Description

@jamescrosswell

Tracking issue for upstream dotnet/android AssemblyStore reader changes that our vendored copy in src/Sentry.Android.AssemblyReader/ does not yet implement. Split out from #5451 (the watch-upstream alert for the file move). These are targeted at the next major release.

Compression (LZ4 → Zstandard) and decompressed-file caching are tracked separately in #5346 and are out of scope here.

Background

Our vendored parser is already ahead of the ATTRIBUTION.txt baseline: it tracks upstream through 64018e13 and hand-ports the v3 format (dotnet/android#10249). Comparing upstream from there to commit f1aecf9, the following logic is new upstream and missing from our copy.

Gaps to port

  • v4 / CoreCLR store format. Upstream StoreReader_V2.cs now accepts 0x_0000004 versions and reads a new content_id field in the header (present when format number >= 4). We accept only v2/v3, so a v4 store is rejected. This is the highest-value item — .NET Android's move to CoreCLR is what produces v4 stores.
  • Variable index-entry sizing. Upstream derives entry size from index_size / index_entry_count (GetIndexEntrySize()) and supports the V2 index-entry layouts, rather than branching on Is64Bit with fixed sizes. Ties into v4 and hardens against corrupt or future stores.

Nice-to-have robustness that came with the same commits: checked offset arithmetic, EndOfStreamException on short reads, and ArrayPool buffer reuse in ReadEntryImageData.

Housekeeping

  • Refresh src/Sentry.Android.AssemblyReader/V2/ATTRIBUTION.txt — it still cites baseline 5ebcb1dd, but the code has moved to 64018e13 + local v3.

Refs

Activity

  1. linear-code commented on Jul 28, 2026

    @linear-code
  2. added this to the 7.0.0 milestone on Jul 28, 2026
  3. jamescrosswell commented on Sep 1, 2026

    @jamescrosswell
    CollaboratorAuthor

    @/private/tmp/claude-501/-Users-jamescrosswell-code-sentry/2e6b94ee-bc64-4843-ac3f-eb524d3ba17e/scratchpad/issue-5454-comment.md

  4. jamescrosswell commented on Sep 1, 2026

    @jamescrosswell
    CollaboratorAuthor

    Confirming this from the .NET 11 preview 7 work in #5529 — the v4 gap is now actively biting.

    Observed: .NET 11 Android APKs carry store header 0x80030004 (64-bit | x64 | v4), and our reader rejects it:

    Store '...!lib/x86_64/libassembly-store.so' has unsupported version 0x80030004
    System.NotSupportedException : Format of assembly store '...' is unsupported
    

    The layout changed, not just the version number. I tested whether a constant bump would be enough: adding v4 to supportedVersions gets past IsSupported() and then fails with EndOfStreamException in StoreReader.Prepare(). That lines up with the content_id header field this issue already identifies as present when the format number is >= 4, so it does need the upstream port rather than a one-line change. I've reverted that experiment and left a comment in StoreReader.cs recording it, so nobody repeats it.

    The second bullet is implicated too. It isn't only assembly-store APKs — the APKs built with AndroidUseAssemblyStore=false fail as well, which points at the _assembly_store ELF dynamic-symbol payload discovery item.

    Impact: no Android symbolication on .NET 11. It degrades gracefully — AndroidHelpers.GetAndroidAssemblyReader catches, logs and returns null — so there's no crash, just missing debug images.

    Temporarily disabled tests. #5529 skips 20 tests in AndroidAssemblyReaderTests on net11.0 only, with this reason surfaced in the test output:

    Android assembly store v4 (.NET 11 / CoreCLR) is not supported yet - see #5454

    net10.0 still runs all 23. These need re-enabling when this issue is tackled — removing the StoreV4Unsupported guard in test/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.cs should be all that's required, and the test APKs for net11.0-android are already produced by the existing matrix.

    One related note for whoever picks this up: .NET 11 removed the Mono runtime for Android entirely (NETSDK1242), so RunAOTCompilation is rejected and Mono-AOT APKs can no longer be built. #5529 restricts the AOT variants of the test APK matrix to net10.0-android for that reason.

  5. jamescrosswell commented on Sep 14, 2026

    @jamescrosswell
    CollaboratorAuthor

    _assembly_store ELF symbol discovery isn't needed — removed from the checklist

    Checked this against a real net11.0-android APK (the TestAPKs built by Sentry.Android.AssemblyReader.Tests) before porting it. Our existing section-name lookup already finds .NET 11 stores, so the symbol lookup is redundant.

    Background

    dotnet/android#12033 changed how the CoreCLR host finds the assembly store inside libassembly-store.so. It used to parse the APK zip, mmap the .so and walk the ELF section headers for a non-loadable payload section. It now dlopens the library and calls dlsym("_assembly_store"). To support that, the payload became a loadable section with an exported symbol pointing at it.

    Offline readers can't call dlsym, so dotnet/android#12104 taught the upstream reader to emulate it: look for _assembly_store in .dynsym first, then fall back to the payload section (Utils.cs diff).

    Why we don't need it

    llvm-readelf -S --dyn-syms on the .NET 11 store:

    [ 6] payload   PROGBITS  Addr 0x4000  Off 0x004000  Flg A
    .dynsym:  _assembly_store  Value 0x4000  Size 0  Ndx 6
    
    • The section is still named payload. Upstream's generator keeps that name deliberately so section-name readers keep working.
    • The symbol points at the start of that section with size 0, so both lookups resolve to the same file offset (0x4000).

    With v4 header support from #5574, our reader parses the .NET 11 store header from the payload section correctly. The skip comment added in #5529 attributed the net11 failures partly to ELF payload discovery; that turned out to be wrong.

    What actually blocks .NET 11

    Temporarily unskipping the net11 APK tests shows two things, neither of them ELF discovery:

    1. Variable index-entry sizing (still on the checklist). The .NET 11 x86_64 store has 60 index entries in 540 bytes, so 9-byte entries on a 64-bit ABI. Our reader assumes 13 bytes whenever the store is 64-bit, and Prepare() fails with EndOfStreamException.
    2. Zstandard compression (Add support for Zstandard: dotnet/android tools/assembly-store-reader-mk2 @ 2e30614 #5346, now feat: Support Zstandard-compressed assemblies on Android (.NET 11) #5575). With index sizing hacked in locally and feat: Support Zstandard-compressed assemblies on Android (.NET 11) #5575 applied, every compressed net11 APK case reads assemblies. The only remaining failure is CreatesCorrectArchiveReader, whose expectation is out of date: on .NET 11 the AndroidUseAssemblyStore=false APK still contains an assembly store.

    If upstream ever renames the section or moves the symbol away from the section start, this becomes worth porting. That would show up as NoPayloadSection in the reader's debug log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    .NETPull requests that update .net codeNext MajorChanges scheduled for the next Major release.Taskupstream-watchUpstream vendored code has changed — review required

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions