Repository navigation
Port upstream AssemblyStore reader changes: v4/CoreCLR format, _assembly_store symbol, index-entry sizing (next major) #5454
Description
Activity
- addedupstream-watchUpstream vendored code has changed — review requiredUpstream vendored code has changed — review required
on Jul 28, 2026 - added.NETPull requests that update .net codePull requests that update .net code
on Jul 28, 2026 @/private/tmp/claude-501/-Users-jamescrosswell-code-sentry/2e6b94ee-bc64-4843-ac3f-eb524d3ba17e/scratchpad/issue-5454-comment.md
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 unsupportedThe layout changed, not just the version number. I tested whether a constant bump would be enough: adding v4 to
supportedVersionsgets pastIsSupported()and then fails withEndOfStreamExceptioninStoreReader.Prepare(). That lines up with thecontent_idheader 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 inStoreReader.csrecording it, so nobody repeats it.The second bullet is implicated too. It isn't only assembly-store APKs — the APKs built with
AndroidUseAssemblyStore=falsefail as well, which points at the_assembly_storeELF dynamic-symbol payload discovery item.Impact: no Android symbolication on .NET 11. It degrades gracefully —
AndroidHelpers.GetAndroidAssemblyReadercatches, logs and returnsnull— so there's no crash, just missing debug images.Temporarily disabled tests. #5529 skips 20 tests in
AndroidAssemblyReaderTestsonnet11.0only, with this reason surfaced in the test output:Android assembly store v4 (.NET 11 / CoreCLR) is not supported yet - see #5454
net10.0still runs all 23. These need re-enabling when this issue is tackled — removing theStoreV4Unsupportedguard intest/Sentry.Android.AssemblyReader.Tests/AndroidAssemblyReaderTests.csshould be all that's required, and the test APKs fornet11.0-androidare already produced by the existing matrix.One related note for whoever picks this up: .NET 11 removed the Mono runtime for Android entirely (
NETSDK1242), soRunAOTCompilationis rejected and Mono-AOT APKs can no longer be built. #5529 restricts the AOT variants of the test APK matrix tonet10.0-androidfor that reason.- addedNext MajorChanges scheduled for the next Major release.Changes scheduled for the next Major release.
on Sep 7, 2026 - added a commit that references this issue
on Sep 9, 2026 jamescrosswell commented
on Sep 14, 2026 CollaboratorAuthorMore actions_assembly_storeELF symbol discovery isn't needed — removed from the checklistChecked this against a real
net11.0-androidAPK (theTestAPKsbuilt bySentry.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,mmapthe.soand walk the ELF section headers for a non-loadablepayloadsection. It nowdlopens the library and callsdlsym("_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_storein.dynsymfirst, then fall back to thepayloadsection (Utils.csdiff).Why we don't need it
llvm-readelf -S --dyn-symson 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
payloadsection 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:
- 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 withEndOfStreamException. - 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 theAndroidUseAssemblyStore=falseAPK 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
NoPayloadSectionin the reader's debug log.- The section is still named
- added a commit that references this issue
on Sep 16, 2026 - added a commit that references this issue
on Oct 6, 2026 - linked a pull request that will close this issuefeat: Support reading .NET 11 Android assembly stores #5577
on Oct 6, 2026
Tracking issue for upstream
dotnet/androidAssemblyStore reader changes that our vendored copy insrc/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.txtbaseline: it tracks upstream through64018e13and hand-ports the v3 format (dotnet/android#10249). Comparing upstream from there to commitf1aecf9, the following logic is new upstream and missing from our copy.Gaps to port
StoreReader_V2.csnow accepts0x_0000004versions and reads a newcontent_idfield 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.index_size / index_entry_count(GetIndexEntrySize()) and supports the V2 index-entry layouts, rather than branching onIs64Bitwith fixed sizes. Ties into v4 and hardens against corrupt or future stores.Nice-to-have robustness that came with the same commits:
checkedoffset arithmetic,EndOfStreamExceptionon short reads, andArrayPoolbuffer reuse inReadEntryImageData.Housekeeping
src/Sentry.Android.AssemblyReader/V2/ATTRIBUTION.txt— it still cites baseline5ebcb1dd, but the code has moved to64018e13+ local v3.Refs