[cDAC] DacDbi code-version node APIs for ReJIT/SOS#126980
[cDAC] DacDbi code-version node APIs for ReJIT/SOS#126980
Conversation
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
There was a problem hiding this comment.
Pull request overview
Implements cDAC equivalents of legacy DAC DBI code-version node lookup APIs used by SOS/ICorDebug, mapping through existing CodeVersions and ReJIT contracts while preserving HRESULT-style behavior.
Changes:
- Implemented
GetActiveRejitILCodeVersionNodeby resolving(Module, mdMethodDef)→MethodDescand returning the explicit active ReJIT IL node (or 0). - Implemented
GetNativeCodeVersionNodeby matching(MethodDesc, codeStartAddress)against contract-enumerated native code versions and returning an explicit native node (or 0 for synthetic/absent). - Implemented
GetILCodeVersionNodeby mapping an explicit native node → explicit IL node (or 0 for default/synthetic), with DEBUG cross-validation against legacy DAC.
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/449a6821-0eb8-4352-815e-7c870d2edaa0 Co-authored-by: rcj1 <77995559+rcj1@users.noreply.github.com>
419ac0e to
bb2c01d
Compare
🤖 Copilot Code Review — PR #126980Note This review was AI/Copilot-generated. Multi-model review: Claude Opus 4.6 (primary) + Claude Sonnet 4.5 + GPT-5.3-Codex (sub-agents). Holistic AssessmentMotivation: Justified. These three DacDbi APIs ( Approach: Sound. The implementations correctly use the cDAC contracts ( Summary: ✅ LGTM. All three implementations faithfully reproduce the C++ DAC behavior. The code is correct, the debug validation is properly structured, and the edge cases align with the reference. Minor suggestions below are non-blocking. Detailed Findings✅ Correctness — Faithful C++ DAC translationI verified each method against the C++ reference implementations:
✅ Debug validation — Correct patternAll three
This matches the established pattern used throughout the file (e.g., 💡 Suggestion — Minor inconsistency in null-pointer check patternThe new methods check for null output pointers inside the try block and throw if (pVmILCodeVersionNode is null)
throw new ArgumentException("Output pointer cannot be null.", ...);
*pVmILCodeVersionNode = 0;Existing neighboring methods (e.g., *pMDStructuresVersion = 0; // before try, no null check
int hr = HResults.S_OK;
try { ... }The new approach is actually safer and matches the C++ DAC's explicit null check ( 💡 Suggestion — Long compound condition could benefit from a clarifying commentLine 1227 has a dense four-part condition. The C++ source at
Consider adding a similar comment to the cDAC implementation for maintainability.
|
| ICodeVersions codeVersions = _target.Contracts.CodeVersions; | ||
| bool foundMatch = false; | ||
|
|
||
| foreach (ILCodeVersionHandle ilCodeVersion in codeVersions.GetILCodeVersions(methodDesc)) |
There was a problem hiding this comment.
You could replace this double loop with codeVersions.GetNativeCodeVersionForIP(). Exposing GetSpecificNativeCodeVersion might perform a little better so you aren't re-finding the MethodDesc.
| MethodDescHandle md = rts.GetMethodDescHandle(methodDesc); | ||
|
|
||
| return GetSpecificNativeCodeVersion(rts, md, codeAddress); | ||
| } |
There was a problem hiding this comment.
I'd prefer to not expose this separate API. It breaks when a method desc is not versionable and duplicates the functionality of GetNativeCodeVersionForIP.
I see @noahfalk comment below about this, but calling GetNativeCodeVersionForIP should have little extra overhead as the MethodDesc and CodeBlockHandle are both cached and just dictionary lookups.
There was a problem hiding this comment.
Ok, I’m fine with it either way
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Description
Implements the cDAC
DacDbiImplAPIsGetActiveRejitILCodeVersionNode,GetNativeCodeVersionNode, andGetILCodeVersionNodeusing existingCodeVersionsandReJITcontracts.