Add ISOSDacInterface18 for GCInfo inspection APIs#129761
Open
max-charlamb wants to merge 4 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new SOS-DAC COM interface (ISOSDacInterface18) intended to expose GCInfo inspection APIs (header, safe points, interruptible ranges, and slot lifetimes), alongside expanding the managed cDAC IGCInfo contract and decoder surface to project the same data.
Changes:
- Add
ISOSDacInterface18(IDL + prebuilt headers + C# GeneratedComInterface) and wire it up through DACQueryInterface. - Implement GCInfo inspection entrypoints in the native DAC (
ClrDataAccess) usingGcInfoDecoder/GcInfoDumper, and extend the managed GCInfo decoder/contracts with header/safe point/lifetime APIs. - Extend GCInfo platform traits to include PSP symbol encoding base across architectures; add placeholder (E_NOTIMPL) stubs in the managed legacy SOS DAC implementation.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs | Adds ISOSDacInterface18 exposure but currently returns E_NOTIMPL for all new methods. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/ISOSDacInterface.cs | Defines GCInfo structs and ISOSDacInterface18 managed COM declarations. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/X86/GCInfo.cs | Implements newly added IGCInfoDecoder members on x86 by throwing NotSupportedException. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/RISCV64GCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/LoongArch64GCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/InterpreterGCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/IGCInfoTraits.cs | Extends traits interface with PSP_SYM_STACK_SLOT_ENCBASE. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/ARMGCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/ARM64GCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/PlatformTraits/AMD64GCInfoTraits.cs | Adds PSP symbol stack-slot encoding base. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/IGCInfoDecoder.cs | Expands decoder interface to include header/safe points/lifetimes. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoDecoder.cs | Adds decoding/projection for header/safe points/lifetimes (includes a correctness issue in safe-point lookup and a potentially expensive lifetime algorithm). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfo_1.cs | Plumbs new IGCInfo contract methods to the decoder implementation. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IGCInfo.cs | Adds public contract types (header/lifetime records) and new IGCInfo methods. |
| src/coreclr/pal/prebuilt/inc/sospriv.h | Updates prebuilt SOS-DAC header with new interface and structs. |
| src/coreclr/pal/prebuilt/idl/sospriv_i.cpp | Adds GUID definitions for new SOS-DAC interfaces/enums. |
| src/coreclr/inc/sospriv.idl | Adds IDL definitions for GCInfo structs and ISOSDacInterface18. |
| src/coreclr/debug/daccess/request.cpp | Implements ClrDataAccess::GetGCInfo* methods and supporting helpers. |
| src/coreclr/debug/daccess/dacimpl.h | Extends ClrDataAccess inheritance and declares ISOSDacInterface17/18 methods. |
| src/coreclr/debug/daccess/daccess.cpp | Extends QueryInterface to support ISOSDacInterface17/18. |
646c0fb to
5310bc9
Compare
5310bc9 to
2f24300
Compare
2f24300 to
36cbff5
Compare
36cbff5 to
487271d
Compare
487271d to
f01e817
Compare
This was referenced Jun 24, 2026
This was referenced Jun 25, 2026
bbd22fa to
7d34213
Compare
7d34213 to
6be5694
Compare
c5743a4 to
930ed91
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoX86_1.cs:41
- GCInfoX86_1 doesn’t implement the new IGCInfo members (GetHeader/GetSafePoints/GetSlotLifetimes). Since these are default interface methods, calls will fall back to the interface default (throwing NotImplementedException) on x86, which will break GcScanner now that it calls GetHeader().
uint IGCInfo.GetCodeLength(IGCInfoHandle gcInfoHandle)
=> AssertCorrectHandle(gcInfoHandle).GetCodeLength();
uint IGCInfo.GetCalleePoppedArgumentsSize(IGCInfoHandle gcInfoHandle)
=> AssertCorrectHandle(gcInfoHandle).GetCalleePoppedArgumentsSize();
IReadOnlyList<InterruptibleRange> IGCInfo.GetInterruptibleRanges(IGCInfoHandle gcInfoHandle)
=> AssertCorrectHandle(gcInfoHandle).GetInterruptibleRanges();
IReadOnlyList<LiveSlot> IGCInfo.EnumerateLiveSlots(IGCInfoHandle gcInfoHandle, uint instructionOffset, GcSlotEnumerationOptions options)
=> AssertCorrectHandle(gcInfoHandle).EnumerateLiveSlots(instructionOffset, options);
4719686 to
2643859
Compare
2643859 to
ca43450
Compare
Add tracking for GcTransitionPointer PUSH/POP/KILL actions and StackDepthTransition in x86 GetSlotLifetimes. Pushed GC pointer arguments now emit SP-relative stack slot lifetimes from their push offset to their pop/kill offset. Also handle register PUSH/POP actions for stack depth tracking (non-pointer register pushes affect the depth but don't create GC slot lifetimes). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ca43450 to
b399f34
Compare
- Fix BaseRegister XML doc: describe as stack base kind (0/1/2), not a CPU register number - Use RegMaskToRegisterNumber helper in x86 GetHeader instead of hard-coded register numbers - Remove unused GetStackBaseRegister/GetSizeOfStackParameterArea public methods from GcInfoDecoder (callers use GetHeader) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jul 7, 2026
Open
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.
Note
This content was generated with AI assistance.
ISOSDacInterface18 for GCInfo inspection APIs
Add
ISOSDacInterface18with 4 COM methods exposing GC info data through the cDAC for the SOS!GCInfocommand:GetGCInfoHeader-- header fields (version, code size, prolog, stack base register, GS cookie, PSP sym, generics context)GetGCInfoInterruptibleRanges-- code regions where GC can interrupt executionGetGCInfoSafePoints-- specific offsets with point-in-time GC slot livenessGetGCInfoSlotLifetimes-- unified slot lifetime ranges (register + stack combined viaSOSGCSlotLifetimewithIsRegisterdiscriminator)IGCInfo contract changes
GetHeader,GetSafePoints,GetSlotLifetimestoIGCInfo/IGCInfoDecoderGetStackBaseRegisterandGetSizeOfStackParameterAreaintoGCInfoHeader(accessed viaGetHeader()). These fields require the same decode depth (DecodePoints.ReversePInvoke) as the rest of the header, so there's no performance benefit to keeping them separate.GetCodeLengthas a standalone method -- it only decodes toDecodePoints.CodeLength, which is significantly cheaper than the full header decode. Used on the hot path byEEJitManager/InterpreterJitManager/ReadyToRunJitManagerfor method size lookups.GetCalleePoppedArgumentsSizeas a standalone method -- it returns 0 via a default interface method on non-x86 platforms without any decoding. Only x86 reads theArgCountheader field.DecodeSafePoints, stored denormalized[safePointOffset, safePointOffset+1)per live slot per safe pointGetHeader/GetSafePoints/GetSlotLifetimes)GenericsContextKind.Noneas default enum valueGSCookieValidRange-- only set when GSCookie is presentE_NOINTERFACEforISOSDacInterface18(cDAC-only interface)Bug fix: ARM thumb bit in relative offset computation
EEJitManager.GetMethodInfoandInterpreterJitManager.GetMethodInfocomputedrelativeOffsetasjittedCodeAddress.Value - codeStart.Value. On ARM (Thumb-2),TargetCodePointer.Valueincludes the thumb bit (bit 0 = 1), butcodeStart(aTargetPointerfrom the nibble map) does not. This produced a relative offset that was off by 1, causingFindSafePointandEnumerateLiveSlotsto look up the wrong offset.Fixed by stripping the thumb bit via
CodePointerUtils.AddressFromCodePointerbefore computing the difference.ReadyToRunJitManagerwas already doing this correctly.Companion PR
!GCInfocommand updated to useISOSDacInterface18with legacy-compatible timeline output format