Skip to content

[cDAC] Implement GetNativeCodeSequencePointsAndVarInfo for cDAC#129267

Open
barosiak wants to merge 1 commit into
dotnet:mainfrom
barosiak:barosiak/GetNativeCodeSequencePointsAndVarInfo
Open

[cDAC] Implement GetNativeCodeSequencePointsAndVarInfo for cDAC#129267
barosiak wants to merge 1 commit into
dotnet:mainfrom
barosiak:barosiak/GetNativeCodeSequencePointsAndVarInfo

Conversation

@barosiak

Copy link
Copy Markdown
Member

Summary

Implement GetNativeCodeSequencePointsAndVarInfo in the cDAC DacDbiImpl. The interface is changed from output-pointer parameters (NativeVarData*, SequencePoints*) to a callback pattern (FP_NATIVEVARINFO_CALLBACK, FP_SEQUENCEPOINT_CALLBACK), since the managed cDAC cannot use the native forDbi allocator.

Changes

  • dacdbi.idl / dacdbiinterface.h / dacdbiimpl.h - Add callback typedefs, update method signature
  • dacdbiimpl.cpp - Rewrite method to use callbacks, remove GetNativeVarData/GetSequencePoints helpers
  • module.cpp - Rewrite LoadNativeInfo with callback struct and GrowAndAppend template helper
  • IDacDbiInterface.cs - Add VarLocType, VarLoc, NativeVarInfo, DbiOffsetMapping structs and update method signature
  • DacDbiImpl.cs - Implement GetNativeCodeSequencePointsAndVarInfo
  • DacDbiImpl.NativeCodeInfo.cs - conversion helpers and DEBUG validation
  • DacDbiImplTests.cs - unit tests for VarLoc type mapping, field-level conversion, and SourceTypes flag conversion

@barosiak barosiak self-assigned this Jun 11, 2026
Copilot AI review requested due to automatic review settings June 11, 2026 00:10
@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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the DAC↔DBI contract for GetNativeCodeSequencePointsAndVarInfo to use a callback-based enumeration model (instead of DBI-allocated output buffers), and wires up the managed cDAC (DacDbiImpl) implementation plus supporting interop structs and unit tests.

Changes:

  • Replaces out-pointer buffer parameters with callback delegates for native var info and sequence points (IDL + native headers + native implementation + DBI consumer).
  • Adds managed interop representations for native debug-info types and implements the cDAC-side method that enumerates var info and sequence points via callbacks.
  • Adds unit tests for var location kind mapping and SourceTypes flag conversion.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs Adds unit tests for VarLoc kind/field mapping and SourceTypes flag conversion.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs Adds managed interop structs/enums and updates method signature to callback-based pattern.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.NativeCodeInfo.cs Adds conversion helpers, fixed-arg counting helper, and DEBUG legacy validation.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs Implements callback-based GetNativeCodeSequencePointsAndVarInfo using cDAC contracts.
src/coreclr/inc/dacdbi.idl Updates the COM IDL to define callback typedefs and the new method signature.
src/coreclr/inc/cordebuginfo.h Documents that specific debug-info types are mirrored in managed code.
src/coreclr/debug/inc/dacdbiinterface.h Updates the native interface signature and adds callback typedefs.
src/coreclr/debug/di/module.cpp Updates CordbNativeCode::LoadNativeInfo to collect entries via callbacks and initialize its internal containers.
src/coreclr/debug/daccess/dacdbiimpl.h Updates the native DAC implementation signature to the new callback-based shape.
src/coreclr/debug/daccess/dacdbiimpl.cpp Rewrites the DAC implementation to enumerate var info / sequence points and invoke callbacks.

Comment on lines +113 to +120
[StructLayout(LayoutKind.Sequential)]
public struct NativeVarInfo
{
public uint startOffset;
public uint endOffset;
public uint varNumber;
public VarLoc loc;
}
Comment on lines +64 to +72
[StructLayout(LayoutKind.Explicit)]
public struct VarLoc
{
[FieldOffset(0)]
public VarLocType vlType;

// vlReg
[FieldOffset(4)]
public uint vlrReg;
Comment on lines +44 to +51
internal static NativeVarInfo ConvertToNativeVarInfo(DebugVarInfo varInfo)
{
NativeVarInfo nvi = default;
nvi.startOffset = varInfo.StartOffset;
nvi.endOffset = varInfo.EndOffset;
nvi.varNumber = varInfo.VarNumber;
nvi.loc = ConvertToVarLoc(varInfo);
return nvi;
Comment on lines +191 to +198
Debug.Assert(c.startOffset == d.startOffset,
$"VarInfo[{i}] startOffset mismatch - cDAC: {c.startOffset}, DAC: {d.startOffset}");
Debug.Assert(c.endOffset == d.endOffset,
$"VarInfo[{i}] endOffset mismatch - cDAC: {c.endOffset}, DAC: {d.endOffset}");
Debug.Assert(c.varNumber == d.varNumber,
$"VarInfo[{i}] varNumber mismatch - cDAC: {c.varNumber}, DAC: {d.varNumber}");
Debug.Assert(c.loc.vlType == d.loc.vlType,
$"VarInfo[{i}] vlType mismatch - cDAC: {c.loc.vlType}, DAC: {d.loc.vlType}");
Comment on lines +1209 to +1214
int hr = HResults.S_OK;
try
{
Debug.Assert(vmMethodDesc != 0, $"vmMethodDesc is null");
Debug.Assert(fCodeAvailable != 0, $"fCodeAvailable is false");

Comment on lines +20 to +41
IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem;
MethodDescHandle mdh = rts.GetMethodDescHandle(new TargetPointer(vmMethodDesc));
uint token = rts.GetMethodToken(mdh);
TargetPointer mtAddr = rts.GetMethodTable(mdh);
TypeHandle typeHandle = rts.GetTypeHandle(mtAddr);
TargetPointer modulePtr = rts.GetModule(typeHandle);
ILoader loader = _target.Contracts.Loader;
Contracts.ModuleHandle moduleHandle = loader.GetModuleHandleFromModulePtr(modulePtr);
IEcmaMetadata ecmaMetadata = _target.Contracts.EcmaMetadata;
MetadataReader? mdReader = ecmaMetadata.GetMetadata(moduleHandle);
if (mdReader is null)
throw Marshal.GetExceptionForHR(HResults.E_FAIL)!;

MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)token);
MethodDefinition methodDef = mdReader.GetMethodDefinition(methodDefHandle);
BlobReader blobReader = mdReader.GetBlobReader(methodDef.Signature);
SignatureHeader sigHeader = blobReader.ReadSignatureHeader();
if (sigHeader.IsGeneric)
blobReader.ReadCompressedInteger(); // skip generic arity
uint paramCount = (uint)blobReader.ReadCompressedInteger();

return paramCount + (sigHeader.IsInstance ? 1u : 0u);
Comment on lines +4754 to +4760
ULONG32 newCapacity = (capacity == 0) ? 32 : capacity * 2;
T *pNew = new T[newCapacity];
if (count > 0)
memcpy(pNew, pArray.GetValue(), count * sizeof(T));
pArray = pNew;
capacity = newCapacity;
}
Comment on lines +914 to +919
public void ConvertToVarLoc_MapsVarLocTypeCorrectly(DebugVarLocKind kind, bool isByRef, VarLocType expected)
{
var varInfo = new DebugVarInfo { Kind = kind, IsByRef = isByRef };
VarLoc result = DacDbiImpl.ConvertToVarLoc(varInfo);
Assert.Equal(expected, result.vlType);
}
MethodDefinitionHandle methodDefHandle = MetadataTokens.MethodDefinitionHandle((int)token);
MethodDefinition methodDef = mdReader.GetMethodDefinition(methodDefHandle);
BlobReader blobReader = mdReader.GetBlobReader(methodDef.Signature);
SignatureHeader sigHeader = blobReader.ReadSignatureHeader();

@rcj1 rcj1 Jun 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have

private static void GetMethodSignatureInfo(MetadataReader mdReader, MethodDefinition methodDef, out SignatureHeader header, out uint numArgs)
and
private void GetMethodInfo(out MethodDescHandle mdh, out MetadataReader mdReader, out MethodDefinition methodDef, out Contracts.ModuleHandle moduleHandle, out uint token)
. We should probably extract the functionality of GetMethodInfo followed by GetMethodSignatureInfo - that is, getting from a method desc to signature info - into a common helper. See the various helper files in the Legacy folder.

} // CordbNativeCode::LookupOrCreateFromJITData

// Doubles the array capacity when full, then appends the item.
template<typename T>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have

CallbackAccumulator<DebuggerIPCE_ExpandedTypeData> acc;

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.

3 participants