Implement ISOSDacInterface::GetLoaderAllocatorHeapNames and GetLoaderAllocatorHeaps in cDAC SOSDacImpl#124818
Conversation
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs
Outdated
Show resolved
Hide resolved
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
|
@copilot, try again |
Implementation reworked in commits up to 0554c43. Changes: Feature-conditional heap names: GetLoaderAllocatorHeaps: Fully implemented in SOSDacImpl.cs, reading heap pointers through the Native data descriptors: Added Tests: 32 new test cases (8 test methods × 4 architectures) covering both methods. All 864 cDAC tests pass. |
max-charlamb
left a comment
There was a problem hiding this comment.
@copilot , address feedback
...tive/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs
Outdated
Show resolved
Hide resolved
max-charlamb
left a comment
There was a problem hiding this comment.
@copilot , address feedback
...native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs
Show resolved
Hide resolved
...native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs
Outdated
Show resolved
Hide resolved
...native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs
Outdated
Show resolved
Hide resolved
Addressed all three review comments in e0e9cd5 —
Addressed all three review comments in e0e9cd5 — |
|
@copilot , please fix build break |
Fixed in 3f63f2f. The issue was that Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
...tive/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs
Show resolved
Hide resolved
max-charlamb
left a comment
There was a problem hiding this comment.
@copilot , address feedback
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs
Show resolved
Hide resolved
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR implements ISOSDacInterface13.GetLoaderAllocatorHeapNames and ISOSDacInterface13.GetLoaderAllocatorHeaps in the managed cDAC, replacing legacy DAC delegation stubs. The implementation adds native data descriptors for loader allocator heaps and VirtualCallStubManager heaps, creates corresponding managed data classes, extends the ILoader contract, and includes comprehensive tests.
Changes:
- Added native data descriptors for LoaderAllocator heaps (StaticsHeap, ExecutableHeap, and feature-conditional heaps) and new VirtualCallStubManager type with heap fields
- Implemented
GetLoaderAllocatorHeapsin the ILoader contract returning a dictionary of heap names to pointers, with dynamic inclusion based on data descriptor field presence - Implemented SOSDacImpl methods to query heap names and addresses through the ILoader contract, with DEBUG validation against legacy DAC
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/loaderallocator.hpp | Added cdac_data fields for StaticsHeap, ExecutableHeap, and feature-conditional heap fields (FixupPrecodeHeap, NewStubPrecodeHeap, DynamicHelpersStubHeap, VirtualCallStubManager) |
| src/coreclr/vm/virtualcallstub.h | Created cdac_data specialization for VirtualCallStubManager with IndcellHeap and CacheEntryHeap fields |
| src/coreclr/vm/datadescriptor/datadescriptor.h | Added #include for virtualcallstub.h to expose VirtualCallStubManager data template |
| src/coreclr/vm/datadescriptor/datadescriptor.inc | Added LoaderAllocator heap fields and new VirtualCallStubManager type with matching feature guards |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs | Added VirtualCallStubManager enum value |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs | Added GetLoaderAllocatorHeaps method to ILoader interface |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/LoaderAllocator.cs | Added StaticsHeap, ExecutableHeap, and nullable feature-conditional heap properties, plus VirtualCallStubManager pointer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/VirtualCallStubManager.cs | Created new data class with IndcellHeap and nullable CacheEntryHeap properties |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs | Implemented GetLoaderAllocatorHeaps with dictionary building logic that conditionally includes heaps based on data descriptor field presence |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs | Implemented GetLoaderAllocatorHeapNames and GetLoaderAllocatorHeaps with lazy initialization, caching, and DEBUG validation |
| src/native/managed/cdac/tests/LoaderTests.cs | Added 8 test methods covering count queries, full retrieval, insufficient buffers, and null parameters for both APIs |
| docs/design/datacontracts/Loader.md | Documented new API, data descriptor fields, and pseudocode implementation |
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs
Outdated
Show resolved
Hide resolved
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
…dd missing using Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
…ps API Replace separate GetLoaderAllocatorHeapNames() and GetLoaderAllocatorHeaps(TargetPointer) with a single GetLoaderAllocatorHeaps(TargetPointer) returning IReadOnlyDictionary<string, TargetPointer>. SOSDacImpl.GetLoaderAllocatorHeapNames now queries the global loader allocator to get names from the dictionary. GetLoaderAllocatorHeaps iterates dictionary values. Tests updated to use dictionary-based mock and verify unordered name/address sets. Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
…tionary - Use nameof(Data.LoaderAllocator.X) instead of hardcoded strings for all dictionary keys in GetLoaderAllocatorHeaps - Make FixupPrecodeHeap and NewStubPrecodeHeap conditional on ContainsKey (exclude from dictionary when field absent from data descriptor) - Remove else branch that padded IndcellHeap/CacheEntryHeap with null when VirtualCallStubManager is null - only include them when VcsManager exists - All 864 cDAC tests pass Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
datadescriptor.h did not include virtualcallstub.h, so the cdac_data<VirtualCallStubManager> template specialization was not visible when datadescriptor.inc was compiled. This caused a build failure referencing cdac_data<VirtualCallStubManager>::IndcellHeap and cdac_data<VirtualCallStubManager>::CacheEntryHeap. Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
Add documentation for the new ILoader.GetLoaderAllocatorHeaps API, including: - New API in the contract API section - New data descriptor fields for LoaderAllocator (StaticsHeap, ExecutableHeap, FixupPrecodeHeap, NewStubPrecodeHeap, DynamicHelpersStubHeap, VirtualCallStubManager) and VirtualCallStubManager (IndcellHeap, CacheEntryHeap) in the data descriptors table - Pseudocode implementation showing feature-conditional dictionary building Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
…AllocatorHeaps Expand #if DEBUG validation blocks to compare actual name strings and heap pointer/kind values between cDAC and legacy DAC, following the pattern used by GetAssemblyList and GetMethodsWithProfilerModifiedIL. Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
… names[i] ↔ heaps[i] correspondence Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
e4980cc to
0adbea4
Compare
Description
Implements
ISOSDacInterface13.GetLoaderAllocatorHeapNamesandISOSDacInterface13.GetLoaderAllocatorHeapsin the managed cDACSOSDacImpl.cs, replacing the legacy DAC delegation stubs. Based onClrDataAccess::GetLoaderAllocatorHeapNamesandClrDataAccess::GetLoaderAllocatorHeapsinrequest.cpp.Native Data Descriptors
cdac_data<LoaderAllocator>inloaderallocator.hpp: StaticsHeap, ExecutableHeap, FixupPrecodeHeap (#ifdef HAS_FIXUP_PRECODE), NewStubPrecodeHeap (#ifndef FEATURE_PORTABLE_ENTRYPOINTS), DynamicHelpersStubHeap (FEATURE_READYTORUN && FEATURE_STUBPRECODE_DYNAMIC_HELPERS), VirtualCallStubManagercdac_data<VirtualCallStubManager>invirtualcallstub.h: IndcellHeap (unconditional), CacheEntryHeap (#ifdef FEATURE_VIRTUAL_STUB_DISPATCH)datadescriptor.incwith matching feature guardsVirtualCallStubManagertoDataTypeenum#include "virtualcallstub.h"todatadescriptor.hsocdac_data<VirtualCallStubManager>is visible whendatadescriptor.incis compiledManaged Data Classes
Data/LoaderAllocator.cswith optional heap fields (FixupPrecodeHeap, NewStubPrecodeHeap, DynamicHelpersStubHeap as nullable) and always-present fields (StaticsHeap, ExecutableHeap, VirtualCallStubManager)Data/VirtualCallStubManager.cswith IndcellHeap and optional CacheEntryHeapILoader Contract
GetLoaderAllocatorHeaps(TargetPointer)method toILoaderinterface returningIReadOnlyDictionary<string, TargetPointer>— dictionary keys are heap names, values are heap pointersLoader_1.cswith dynamic dictionary building based on data descriptor field presence viaContainsKeychecks, matching the native#ifdefconditional compilationnameof(Data.LoaderAllocator.X)andnameof(Data.VirtualCallStubManager.X)instead of hardcoded stringsSOSDacImpl
GetLoaderAllocatorHeapNames: Queries global loader allocator viaILoader.GetLoaderAllocatorHeapsto get heap names from dictionary keys. Lazily initializes ANSI string pointers viaMarshal.StringToHGlobalAnsi, cached on the instance along with the ordered name strings. Standard cDAC pattern with try/catch,S_FALSEwhen buffer is insufficientGetLoaderAllocatorHeaps: Uses the cached canonical name ordering fromGetLoaderAllocatorHeapNamesto look up heap pointers by key viaTryGetValue, defaulting to 0 for missing entries. This ensuresnames[i]always corresponds toheaps[i]regardless of dictionary enumeration order, matching the DAC's fixed-array ordering contract. FillsLoaderHeapKindNormalfor all heaps#if DEBUGvalidation blocks that compare cDAC results against legacy DAC output — heap name strings and heap pointer/kind values are validated to match, following the pattern used by other cDAC APIsContract Documentation
docs/design/datacontracts/Loader.mdwith:GetLoaderAllocatorHeapsAPI in the contract API sectionLoaderAllocator(StaticsHeap, ExecutableHeap, FixupPrecodeHeap, NewStubPrecodeHeap, DynamicHelpersStubHeap, VirtualCallStubManager) and newVirtualCallStubManagertype (IndcellHeap, CacheEntryHeap) in the data descriptors tableTests
LoaderTests.cs× 4 architectures = 32 new test casesGetLoaderAllocatorHeapNames: Count query, full name retrieval, insufficient buffer, null pNeededGetLoaderAllocatorHeaps: Count query, full heap retrieval, insufficient buffer, null addressnames[i]matches the expected heap address at indexi💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.