Skip to content

[cDAC] Return no debug info for ReadyToRun images without a DebugInfo section - #135059

Merged
lewing merged 1 commit into
dotnet:mainfrom
lewing:lewing-cdac-r2r-missing-debug-info
Oct 2, 2026
Merged

lewing merged 1 commit into
dotnet:mainfrom
lewing:lewing-cdac-r2r-missing-debug-info

Conversation

@lewing

@lewing lewing commented Oct 1, 2026

Copy link
Copy Markdown
Member

Native ReadyToRunInfo::GetDebugInfo (src/coreclr/vm/readytoruninfo.cpp) returns NULL immediately when m_pSectionDebugInfo == NULL. The cDAC mirror, ReadyToRunJitManager.GetDebugInfo, dereferenced ReadyToRunInfo.DebugInfoSection without that check and built a NativeArray from whatever was at address 0.

This now matters because #134690 makes Browser/WASI ReadyToRun publishes pass --strip-debug-info by default, including CoreLib and the framework. iOS, tvOS, and MacCatalyst already default to it. On wasm, linear address 0 is readable, so cDAC decoded garbage. A live run against a stripped browser image threw BadImageFormatException: offset out of bounds (NativeReader.DecodeUnsigned ← NativeArray..ctor ← ReadyToRunJitManager.GetDebugInfo ← DebugInfo_1.GetMethodVarInfo) instead of reporting that there was no debug info. On native targets, the same path fails with a read exception.

Changes

  • ReadyToRunJitManager.GetDebugInfo returns TargetPointer.Null (with hasFlagByte = false) when DebugInfoSection is null, matching native.
  • docs/design/datacontracts/ExecutionManager.md: the R2R GetDebugInfo description now includes the null-section early return.
  • No caller changes were needed. DebugInfo_1.HasDebugInfo, GetMethodNativeMap, GetMethodVarInfo, and GetAsyncSuspensionPoints already treat a null debug-info pointer as "no debug info". The two map/var methods still compute codeOffset.

Tests

New test ExecutionManagerTests.GetDebugInfo_R2R_NoDebugInfoSection_ReturnsNull runs as a [Theory] over StdArchAllVersions (4 arch cases). It builds an R2R module whose DebugInfoSection is null and makes the low 4 KB of the address space readable as zeros, the way wasm linear memory is, so the unfixed code decodes instead of hitting a read fault. It asserts that:

  • IExecutionManager.GetDebugInfo returns TargetPointer.Null and hasFlagByte == false
  • IDebugInfo.HasDebugInfo is false
  • GetMethodVarInfo and GetMethodNativeMap return empty sequences with codeOffset == 4

Results:

  • ./build.sh -s tools.cdactests -test: passed. UnitTests 3236/3236, DataGeneratorTests 46/46, UsageTests 4/4 (no stale generated docs).
  • ./.dotnet/dotnet test src/native/managed/cdac/tests/UnitTests --filter "FullyQualifiedName~GetDebugInfo_R2R_NoDebugInfoSection": passed, 4/4.
  • Mutation check: I removed the null check and reran the same filtered command. It failed 4/4 with System.BadImageFormatException : offset out of bounds at NativeReader.DecodeUnsigned ← NativeArray..ctor ← ReadyToRunJitManager.GetDebugInfo, the same failure as the live wasm run. With the fix restored, it passes 4/4.

This PR has a single concern. It leaves wasm stack-walk and variable-location work to #133890, #135044, and #135055.

Note

This PR description was generated with GitHub Copilot.

… section

Match native ReadyToRunInfo::GetDebugInfo, which returns NULL when
m_pSectionDebugInfo is null. Images published with --strip-debug-info
(now the default for Browser/WASI R2R) have no DebugInfo section; cDAC
dereferenced the null ImageDataDirectory and, on wasm where address 0 is
readable, decoded garbage and threw BadImageFormatException.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

@lewing
lewing requested a review from rcj1 October 1, 2026 21:53
@lewing
lewing enabled auto-merge (squash) October 1, 2026 21:57
@lewing

lewing commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

/ba-g failures are known

@lewing
lewing merged commit 8b05605 into dotnet:main Oct 2, 2026
77 of 85 checks passed
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants