Skip to content

Commit 37253e0

Browse files
authored
[cdac] Implement ISOSDacInterface::GetUsefulGlobals (#105106)
Add the Exception, Object, Array of Object, and String method tables to the data descriptor and use them to implement ISOSDacInterface::GetUsefulGlobals in the cDAC. Contracts are unaffected - this is just exposing those globals via the DAC API.
1 parent d461cdb commit 37253e0

File tree

6 files changed

+78
-6
lines changed

6 files changed

+78
-6
lines changed

src/coreclr/debug/daccess/dacimpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,7 @@ class ClrDataAccess
12421242
HRESULT GetMethodTableNameImpl(CLRDATA_ADDRESS mt, unsigned int count, _Inout_updates_z_(count) WCHAR *mtName, unsigned int *pNeeded);
12431243
HRESULT GetObjectExceptionDataImpl(CLRDATA_ADDRESS objAddr, struct DacpExceptionObjectData *data);
12441244
HRESULT GetObjectStringDataImpl(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR *stringData, unsigned int *pNeeded);
1245+
HRESULT GetUsefulGlobalsImpl(struct DacpUsefulGlobalsData *globalsData);
12451246

12461247
BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
12471248
#ifndef TARGET_UNIX
@@ -2005,7 +2006,7 @@ class DacMethodTableSlotEnumerator : public DefaultCOMImpl<ISOSMethodEnum, IID_I
20052006
DacMethodTableSlotEnumerator() : mIteratorIndex(0)
20062007
{
20072008
}
2008-
2009+
20092010
virtual ~DacMethodTableSlotEnumerator() {}
20102011

20112012
HRESULT Init(PTR_MethodTable mTable);

src/coreclr/debug/daccess/request.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3460,13 +3460,47 @@ ClrDataAccess::GetHeapAnalyzeStaticData(struct DacpGcHeapAnalyzeData *analyzeDat
34603460
}
34613461

34623462
HRESULT
3463-
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
3463+
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData* globalsData)
34643464
{
34653465
if (globalsData == NULL)
34663466
return E_INVALIDARG;
34673467

34683468
SOSDacEnter();
34693469

3470+
if (m_cdacSos != NULL)
3471+
{
3472+
hr = m_cdacSos->GetUsefulGlobals(globalsData);
3473+
if (FAILED(hr))
3474+
{
3475+
hr = GetUsefulGlobals(globalsData);
3476+
}
3477+
#ifdef _DEBUG
3478+
else
3479+
{
3480+
// Assert that the data is the same as what we get from the DAC.
3481+
DacpUsefulGlobalsData globalsDataLocal;
3482+
HRESULT hrLocal = GetUsefulGlobalsImpl(&globalsDataLocal);
3483+
_ASSERTE(hr == hrLocal);
3484+
_ASSERTE(globalsData->ArrayMethodTable == globalsDataLocal.ArrayMethodTable);
3485+
_ASSERTE(globalsData->StringMethodTable == globalsDataLocal.StringMethodTable);
3486+
_ASSERTE(globalsData->ObjectMethodTable == globalsDataLocal.ObjectMethodTable);
3487+
_ASSERTE(globalsData->ExceptionMethodTable == globalsDataLocal.ExceptionMethodTable);
3488+
_ASSERTE(globalsData->FreeMethodTable == globalsDataLocal.FreeMethodTable);
3489+
}
3490+
#endif
3491+
}
3492+
else
3493+
{
3494+
hr = GetUsefulGlobals(globalsData);;
3495+
}
3496+
3497+
SOSDacLeave();
3498+
return hr;
3499+
}
3500+
3501+
HRESULT
3502+
ClrDataAccess::GetUsefulGlobalsImpl(struct DacpUsefulGlobalsData *globalsData)
3503+
{
34703504
TypeHandle objArray = g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT];
34713505
if (objArray != NULL)
34723506
globalsData->ArrayMethodTable = HOST_CDADDR(objArray.AsMethodTable());
@@ -3478,8 +3512,7 @@ ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
34783512
globalsData->ExceptionMethodTable = HOST_CDADDR(g_pExceptionClass);
34793513
globalsData->FreeMethodTable = HOST_CDADDR(g_pFreeObjectMethodTable);
34803514

3481-
SOSDacLeave();
3482-
return hr;
3515+
return S_OK;
34833516
}
34843517

34853518
HRESULT

src/coreclr/debug/runtimeinfo/datadescriptor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,10 @@ CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2)
282282
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1)
283283
#endif //TARGET_64BIT
284284
CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION)
285+
CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass)
285286
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
287+
CDAC_GLOBAL_POINTER(ObjectMethodTable, &::g_pObjectClass)
288+
CDAC_GLOBAL_POINTER(ObjectArrayMethodTable, &::g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT])
286289
CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass)
287290
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
288291
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)

src/native/managed/cdacreader/src/Constants.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ internal static class Globals
1717
internal const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask);
1818
internal const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion);
1919

20+
internal const string ExceptionMethodTable = nameof(ExceptionMethodTable);
2021
internal const string FreeObjectMethodTable = nameof(FreeObjectMethodTable);
22+
internal const string ObjectMethodTable = nameof(ObjectMethodTable);
23+
internal const string ObjectArrayMethodTable = nameof(ObjectArrayMethodTable);
2124
internal const string StringMethodTable = nameof(StringMethodTable);
2225

2326
internal const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress);

src/native/managed/cdacreader/src/Legacy/ISOSDacInterface.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ internal struct DacpMethodTableData
9191
public int bIsDynamic;
9292
public int bContainsGCPointers;
9393
}
94+
95+
internal struct DacpUsefulGlobalsData
96+
{
97+
public ulong ArrayMethodTable;
98+
public ulong StringMethodTable;
99+
public ulong ObjectMethodTable;
100+
public ulong ExceptionMethodTable;
101+
public ulong FreeMethodTable;
102+
}
94103
#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value
95104

96105
[GeneratedComInterface]
@@ -280,7 +289,7 @@ internal unsafe partial interface ISOSDacInterface
280289

281290
// Other
282291
[PreserveSig]
283-
int GetUsefulGlobals(/*struct DacpUsefulGlobalsData */ void* data);
292+
int GetUsefulGlobals(DacpUsefulGlobalsData* data);
284293
[PreserveSig]
285294
int GetClrWatsonBuckets(ulong thread, void* pGenericModeBlock);
286295
[PreserveSig]

src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,30 @@ public unsafe int GetThreadStoreData(DacpThreadStoreData* data)
403403
}
404404

405405
public unsafe int GetTLSIndex(uint* pIndex) => HResults.E_NOTIMPL;
406-
public unsafe int GetUsefulGlobals(void* data) => HResults.E_NOTIMPL;
406+
407+
public unsafe int GetUsefulGlobals(DacpUsefulGlobalsData* data)
408+
{
409+
try
410+
{
411+
data->ArrayMethodTable = _target.ReadPointer(
412+
_target.ReadGlobalPointer(Constants.Globals.ObjectArrayMethodTable));
413+
data->StringMethodTable = _target.ReadPointer(
414+
_target.ReadGlobalPointer(Constants.Globals.StringMethodTable));
415+
data->ObjectMethodTable = _target.ReadPointer(
416+
_target.ReadGlobalPointer(Constants.Globals.ObjectMethodTable));
417+
data->ExceptionMethodTable = _target.ReadPointer(
418+
_target.ReadGlobalPointer(Constants.Globals.ExceptionMethodTable));
419+
data->FreeMethodTable = _target.ReadPointer(
420+
_target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable));
421+
}
422+
catch (System.Exception ex)
423+
{
424+
return ex.HResult;
425+
}
426+
427+
return HResults.S_OK;
428+
}
429+
407430
public unsafe int GetWorkRequestData(ulong addrWorkRequest, void* data) => HResults.E_NOTIMPL;
408431
public unsafe int IsRCWDCOMProxy(ulong rcwAddress, int* inDCOMProxy) => HResults.E_NOTIMPL;
409432
public unsafe int TraverseEHInfo(ulong ip, void* pCallback, void* token) => HResults.E_NOTIMPL;

0 commit comments

Comments
 (0)