Skip to content

[cDAC][wasm] Expose the WebAssembly function identity of R2R frames - #135495

Closed
lewing wants to merge 4 commits into
dotnet:mainfrom
lewing:lewing-cdac-wasm-function-identity
Closed

lewing wants to merge 4 commits into
dotnet:mainfrom
lewing:lewing-cdac-wasm-function-identity

Conversation

@lewing

@lewing lewing commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Adds IStackWalk.GetWasmFunctionIdentity, which returns the owning module, image-relative RUNTIME_FUNCTION index, global function-table index and funclet flag of a wasm R2R frame. An out-of-process consumer such as a CDP debugger needs the image and image-relative index, because engine function indices are module-local.

The lookup maps the frame's virtual IP to its RUNTIME_FUNCTION through TryGetUnwindInfo (the funclet's own entry inside a funclet) and matches it against each image in FunctionTableIndexRangeList. So it doesn't depend on the tagged frame identity from #135440. For a composite image, Module is the module that loaded the image. The API throws off wasm and for frames that aren't frameless R2R frames. StackWalk.md documents it.

Replaces #135426, which was auto-closed when its base branch was deleted.

Note

This PR description was generated with GitHub Copilot.

lewing and others added 2 commits October 9, 2026 16:02
Add IStackWalk.GetWasmFunctionIdentity. For a ReadyToRun frameless frame it
returns the raw runtime-global function-table index from the frame record and,
when that index is in a registered range, the module that registered the image,
the image-relative RUNTIME_FUNCTION index, and whether the function is a
funclet.

A WebAssembly engine's function index is module-local, so an out-of-process
consumer (for example a debugger over the Chrome DevTools Protocol) needs the
module and image-relative index to find the engine function; the raw index alone
is not enough.

The API rejects non-ReadyToRun and non-frameless frames before reading the
stack, because interpreter frames and native markers can hold bytes that look
like an R2R frame record. WasmFunctionTableIndexLookup's funclet check now goes
through the same resolution.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.

Main's R2R frame record now stores a tagged identity rather than a raw
function-table index. Resolve the function from the IP through the
execution manager instead of parsing the frame record: the unwind info
selects the function's own RUNTIME_FUNCTION, which is then matched to its
registered image.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use GetReadyToRunInfo(section) like the other walkers and drop the ReadyToRunInfo null
guard. A function-table index range is registered by ReadyToRunInfo::RegisterVirtualIPRange,
which Module runs through GetReadyToRunInfo() during eager fixups, so the module's
ReadyToRunInfo is already set when the range is published. The only field assigned after
publication is MinVirtualIP, which the walkers that read it already check.

Drop the redundant NumRuntimeFunctions > 0 check, and shorten the helper summary; the
composite-image caveat stays on WasmFunctionIdentity.Module and in StackWalk.md.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing added a commit to lewing/runtime that referenced this pull request Oct 20, 2026
Decode WASM register locations (localIndex + WASM_LOCAL_REGNUM_BASE) into
DebugVarInfo.WasmLocal/WasmLocal2 and report them as the WasmLocal and
WasmLocalPair kinds. Resolve VLT_STK / VLT_STK2 against the logical frame
pointer in the stack-walk context. Engine-private locals report no native
locations, and an unreadable or null WASM VLT_STK_BYREF indirection keeps
its location but fails reads instead of reading linear address 0.

Frame context, funclet frame pointers and function identity are provided
by dotnet#135140 (merged), dotnet#135494 and dotnet#135495.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
byte[] GetContext(ThreadData threadData, ThreadContextSource contextSource, uint contextFlags) => throw new NotImplementedException();
TargetPointer GetFuncletRootId(IStackDataFrameHandle stackDataFrameHandle, out uint parentNativeOffset) => throw new NotImplementedException();
TargetPointer GetExactGenericArgsToken(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException();
WasmFunctionIdentity GetWasmFunctionIdentity(IStackDataFrameHandle stackDataFrameHandle) => throw new NotImplementedException();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the need for this new API?

We currently have APIs to access the Module, check if a code region is a funclet, and get the RUNTIME_FUNCTION address. If there is a reason we need the index, I believe that should be done in IExecutionManager.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, it isn't needed. The pieces already exist: GetCodeBlockHandle, IsFunclet, GetUnwindInfo / TryGetUnwindInfo for the RUNTIME_FUNCTION, and the module from the frame's MethodDesc. The CDP consumer that motivated this matches cDAC frames to engine frames by stack pointer and already decodes R2R RUNTIME_FUNCTION indices on its own, so it doesn't use this API either. Closing this PR. If an image-relative index turns out to be needed later, it will go in IExecutionManager as you suggest.

Note

This reply was generated with GitHub Copilot.

Auto-replied by the GitHub Copilot app

@lewing lewing closed this Oct 20, 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.

2 participants