[wasm] Fix R2R stackwalk for inline P/Invoke frames and composite-image RVA base#131243
Merged
Conversation
…ge RVA base Two wasm-only stackwalk correctness fixes, needed once R2R-compiled managed code participates in a stackwalk (exception unwind, GetCallersAssembly, Assembly.Load): 1. Inline-P/Invoke sentinel resolution (stackwalk.cpp, frames.h, helpers.cpp): An R2R inline P/Invoke frame carries the sentinel return address INLINED_PINVOKE_FROM_R2R (== 1) instead of a real native address; the real caller virtual IP is derived from m_pCallSiteSP. StackFrameIterator::NextRaw fed that sentinel straight to ProcessIp, which cannot recognize it as managed code, so the same active frame repeated forever. Resolve the sentinel to the caller virtual IP via GetWasmVirtualIPFromStackPointer before ProcessIp, failing the walk (SWA_FAILED) if the lookup returns null. The sentinel constant is moved from a helpers.cpp #define into frames.h so the stack walker can reference it. 2. Composite R2R image RVA base (codeman.inl): JitTokenToModuleRVABase resolved wasm virtual-IP ranges against the IL module base (GetModuleBaseAddress()), which is wrong for a composite R2R (WbIL) image. Use the R2R image base (ReadyToRunInfo()->GetImage()->GetBase()) so unwind-frame RVAs decode against the correct composite base. Verified: WASI CoreCLR build (clr -os wasi -c Release) 0W/0E; validated end-to-end against minimal Assembly.Load / GetExecutingAssembly R2R repros that previously looped forever in StackFrameIterator. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2902374a-f352-4c46-bcec-8a35c97733ae
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @agocke |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR makes two WebAssembly-only correctness fixes for ReadyToRun (R2R) stack walking: (1) properly handling the sentinel “return address” used by inline P/Invoke frames in R2R, and (2) using the correct image base when mapping unwind RVAs for composite R2R images.
Changes:
- Resolve the wasm R2R inline-P/Invoke sentinel return address to a real virtual IP before calling
ProcessIpduring stack walking. - Move the sentinel constant to a typed
static constexprinframes.hso it’s accessible to stack-walk code. - Fix wasm
JitTokenToModuleRVABaseto use the R2R image base (not the IL module base) forRANGE_SECTION_VIRTUALIPsections.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/vm/wasm/helpers.cpp | Removes the local macro sentinel definition; continues using the sentinel for active inline P/Invoke frames. |
| src/coreclr/vm/stackwalk.cpp | Adds wasm-specific handling to translate the inline P/Invoke sentinel to a virtual IP prior to ProcessIp. |
| src/coreclr/vm/frames.h | Introduces a typed sentinel constant and declares GetWasmVirtualIPFromStackPointer for wasm. |
| src/coreclr/vm/codeman.inl | Updates wasm virtual-IP RVA base resolution to use the R2R image base address. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
lewing
marked this pull request as ready for review
July 23, 2026 01:13
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
davidwrighton
approved these changes
Jul 23, 2026
lewing
enabled auto-merge (squash)
July 23, 2026 17:31
Member
Author
|
/ba-g native-aot infra failures are not related |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two wasm-only R2R stackwalk correctness fixes, needed once R2R-compiled managed code participates in a stackwalk (exception unwind,
GetCallersAssembly,Assembly.Load,GetExecutingAssembly, …).1. Inline P/Invoke sentinel resolution (
stackwalk.cpp,frames.h,helpers.cpp)An R2R inline P/Invoke
InlinedCallFramecarries the sentinel return addressINLINED_PINVOKE_FROM_R2R(== 1) instead of a real native address; the real caller virtual IP is derived fromm_pCallSiteSP(this infrastructure — the sentinel assignment andInlinedCallFrame::UpdateRegDisplay_Impl— already exists onmain). ButStackFrameIterator::NextRawfed that sentinel straight toProcessIp, which cannot recognize it as managed code, so the same active frame repeated forever — an infinite loop in any stackwalk that crosses an R2R inline-P/Invoke frame.Resolve the sentinel to the caller virtual IP via
GetWasmVirtualIPFromStackPointerbeforeProcessIp, failing the walk (SWA_FAILED) if the lookup returns null. The sentinel constant moves from ahelpers.cpp#defineto a typedstatic constexprinframes.hso the stack walker can reference it (existinghelpers.cppuses are unchanged semantically).2. Composite R2R image RVA base (
codeman.inl)JitTokenToModuleRVABaseresolved wasm virtual-IP ranges against the IL module base (GetModuleBaseAddress()), which is wrong for a composite R2R (WbIL) image — unwind-frame RVAs decoded against the wrong base. Use the R2R image base (ReadyToRunInfo()->GetImage()->GetBase()), correct for both composite and standalone R2R.Validation
clr -os wasi -c Release): 0W/0E;stackwalk.cpp/helpers.cppobjects recompile clean.Assembly.Load/GetExecutingAssemblyR2R repros that previously looped forever inStackFrameIterator.Note
This PR was authored with the assistance of GitHub Copilot.