Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/debug/daccess/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CLR_DIR}/debug/ee)
include_directories(${CLR_DIR}/gcdump)
include_directories(${CLR_DIR}/interop/inc)
include_directories(${CLR_DIR}/debug/datadescriptor-shared/inc)

if(CLR_CMAKE_HOST_UNIX)
include_directories(${GENERATED_INCLUDE_DIR})
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/debug/daccess/dacimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,7 @@ class ClrDataAccess
HRESULT EnumMemDumpAppDomainInfo(CLRDataEnumMemoryFlags flags);
HRESULT EnumMemDumpAllThreadsStack(CLRDataEnumMemoryFlags flags);
HRESULT EnumMemCLRMainModuleInfo();
HRESULT EnumMemDataDescriptors(CLRDataEnumMemoryFlags flags);

bool ReportMem(TADDR addr, TSIZE_T size, bool fExpectSuccess = true);
bool DacUpdateMemoryRegion(TADDR addr, TSIZE_T bufferSize, BYTE* buffer);
Expand Down
75 changes: 75 additions & 0 deletions src/coreclr/debug/daccess/enummem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#endif // FEATURE_COMWRAPPERS

#include "cdacplatformmetadata.hpp"
#include "contract-descriptor.h"

extern HRESULT GetDacTableAddress(ICorDebugDataTarget* dataTarget, ULONG64 baseAddress, PULONG64 dacTableAddress);

Expand Down Expand Up @@ -1631,6 +1632,77 @@ HRESULT ClrDataAccess::EnumMemCLRMainModuleInfo()
return status;
}

typedef DPTR(ContractDescriptor) PTR_ContractDescriptor;
extern "C" bool TryGetSymbol(ICorDebugDataTarget* dataTarget, uint64_t baseAddress, const char* symbolName, uint64_t* symbolAddress);

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Reports datadescriptor data for the cDAC
// that needs to be present in all minidumps.
// Hardcodes number of subdescriptors and does not recursively enumerate them.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT ClrDataAccess::EnumMemDataDescriptors(CLRDataEnumMemoryFlags flags)
Comment thread
max-charlamb marked this conversation as resolved.
{
SUPPORTS_DAC;

HRESULT status = S_OK;

uint64_t contractDescriptorAddr = 0;
if (!TryGetSymbol(m_pTarget, m_globalBase, "DotNetRuntimeContractDescriptor", &contractDescriptorAddr))
{
return E_FAIL;
}

PTR_ContractDescriptor pContractDescriptor = dac_cast<PTR_ContractDescriptor>((TADDR)contractDescriptorAddr);
// Enumerate the ContractDescriptor structure
ReportMem(dac_cast<TADDR>(pContractDescriptor), sizeof(ContractDescriptor));
// Report the pointer data array
ReportMem((TADDR)pContractDescriptor->pointer_data, pContractDescriptor->pointer_data_count * sizeof(void*));
// Report the JSON blob
ReportMem((TADDR)pContractDescriptor->descriptor, pContractDescriptor->descriptor_size);

// Assume that subdescriptors will be the n last pointers in the pointer_data array
// Must be updated if further subdescriptors are added
// This could be improved by iterating all of the pointer data recursively and identifying subdescriptors by
// the magic field in ContractDescriptor, but given it will eventually move to the cDAC, this is good enough for now.
Comment thread
max-charlamb marked this conversation as resolved.
Outdated
int cSubDescriptors = 1;
Comment thread
max-charlamb marked this conversation as resolved.
for (int i = 0; i < cSubDescriptors; i++)
{
int subDescriptorIndex = (pContractDescriptor->pointer_data_count - 1) - i;

TADDR pSubDescriptorAddr;
ULONG32 bytesRead;
if (FAILED(m_pTarget->ReadVirtual(
(TADDR)pContractDescriptor->pointer_data + subDescriptorIndex * sizeof(void*),
(PBYTE)&pSubDescriptorAddr, sizeof(TADDR), &bytesRead))
|| bytesRead != sizeof(TADDR)
|| pSubDescriptorAddr == NULL)
Comment thread
max-charlamb marked this conversation as resolved.
Outdated
{
continue;
}

TADDR subDescriptorAddr;
if (FAILED(m_pTarget->ReadVirtual(
pSubDescriptorAddr,
(PBYTE)&subDescriptorAddr, sizeof(TADDR), &bytesRead))
|| bytesRead != sizeof(TADDR)
|| subDescriptorAddr == NULL)
Comment thread
max-charlamb marked this conversation as resolved.
Outdated
{
continue;
}

PTR_ContractDescriptor pSubDescriptor = dac_cast<PTR_ContractDescriptor>(subDescriptorAddr);
Comment thread
max-charlamb marked this conversation as resolved.
Outdated
// Enumerate the ContractDescriptor structure
ReportMem(dac_cast<TADDR>(pSubDescriptor), sizeof(ContractDescriptor));
// Report the pointer data array
ReportMem((TADDR)pSubDescriptor->pointer_data, pSubDescriptor->pointer_data_count * sizeof(void*));
// Report the JSON blob
ReportMem((TADDR)pSubDescriptor->descriptor, pSubDescriptor->descriptor_size);
}

return status;
}

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
Expand Down Expand Up @@ -2059,6 +2131,9 @@ ClrDataAccess::EnumMemoryRegions(IN ICLRDataEnumMemoryRegionsCallback* callback,
}
}
#endif

EnumMemDataDescriptors(flags);

Flush();
}
EX_CATCH
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/datadescriptor/datadescriptor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,9 @@ CDAC_GLOBAL_POINTER(MethodDescSizeTable, &MethodDesc::s_ClassificationSizeTable)
CDAC_GLOBAL_POINTER(GCLowestAddress, &g_lowest_address)
CDAC_GLOBAL_POINTER(GCHighestAddress, &g_highest_address)


// It is important for the subdescriptor pointers to be the last pointers in the global structure
Comment thread
max-charlamb marked this conversation as resolved.
Outdated
// enummem.cpp relies on this order to find and enumerate the subdescriptors
CDAC_GLOBAL_SUB_DESCRIPTOR(GC, &(g_gc_dac_vars.gc_descriptor))
Comment thread
max-charlamb marked this conversation as resolved.

CDAC_GLOBAL_CONTRACT(CodeVersions, 1)
Expand Down
Loading