1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-10 01:50:53 +09:00

[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.
This commit is contained in:
Elinor Fung 2024-07-19 11:07:12 -07:00 committed by GitHub
parent d461cdb401
commit 37253e00c3
Signed by: github
GPG key ID: B5690EEEBB952194
6 changed files with 78 additions and 6 deletions

View file

@ -1242,6 +1242,7 @@ public:
HRESULT GetMethodTableNameImpl(CLRDATA_ADDRESS mt, unsigned int count, _Inout_updates_z_(count) WCHAR *mtName, unsigned int *pNeeded);
HRESULT GetObjectExceptionDataImpl(CLRDATA_ADDRESS objAddr, struct DacpExceptionObjectData *data);
HRESULT GetObjectStringDataImpl(CLRDATA_ADDRESS obj, unsigned int count, _Inout_updates_z_(count) WCHAR *stringData, unsigned int *pNeeded);
HRESULT GetUsefulGlobalsImpl(struct DacpUsefulGlobalsData *globalsData);
BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
#ifndef TARGET_UNIX

View file

@ -3460,13 +3460,47 @@ ClrDataAccess::GetHeapAnalyzeStaticData(struct DacpGcHeapAnalyzeData *analyzeDat
}
HRESULT
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData* globalsData)
{
if (globalsData == NULL)
return E_INVALIDARG;
SOSDacEnter();
if (m_cdacSos != NULL)
{
hr = m_cdacSos->GetUsefulGlobals(globalsData);
if (FAILED(hr))
{
hr = GetUsefulGlobals(globalsData);
}
#ifdef _DEBUG
else
{
// Assert that the data is the same as what we get from the DAC.
DacpUsefulGlobalsData globalsDataLocal;
HRESULT hrLocal = GetUsefulGlobalsImpl(&globalsDataLocal);
_ASSERTE(hr == hrLocal);
_ASSERTE(globalsData->ArrayMethodTable == globalsDataLocal.ArrayMethodTable);
_ASSERTE(globalsData->StringMethodTable == globalsDataLocal.StringMethodTable);
_ASSERTE(globalsData->ObjectMethodTable == globalsDataLocal.ObjectMethodTable);
_ASSERTE(globalsData->ExceptionMethodTable == globalsDataLocal.ExceptionMethodTable);
_ASSERTE(globalsData->FreeMethodTable == globalsDataLocal.FreeMethodTable);
}
#endif
}
else
{
hr = GetUsefulGlobals(globalsData);;
}
SOSDacLeave();
return hr;
}
HRESULT
ClrDataAccess::GetUsefulGlobalsImpl(struct DacpUsefulGlobalsData *globalsData)
{
TypeHandle objArray = g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT];
if (objArray != NULL)
globalsData->ArrayMethodTable = HOST_CDADDR(objArray.AsMethodTable());
@ -3478,8 +3512,7 @@ ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
globalsData->ExceptionMethodTable = HOST_CDADDR(g_pExceptionClass);
globalsData->FreeMethodTable = HOST_CDADDR(g_pFreeObjectMethodTable);
SOSDacLeave();
return hr;
return S_OK;
}
HRESULT

View file

@ -282,7 +282,10 @@ CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2)
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1)
#endif //TARGET_64BIT
CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION)
CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass)
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
CDAC_GLOBAL_POINTER(ObjectMethodTable, &::g_pObjectClass)
CDAC_GLOBAL_POINTER(ObjectArrayMethodTable, &::g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT])
CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass)
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)

View file

@ -17,7 +17,10 @@ internal static class Constants
internal const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask);
internal const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion);
internal const string ExceptionMethodTable = nameof(ExceptionMethodTable);
internal const string FreeObjectMethodTable = nameof(FreeObjectMethodTable);
internal const string ObjectMethodTable = nameof(ObjectMethodTable);
internal const string ObjectArrayMethodTable = nameof(ObjectArrayMethodTable);
internal const string StringMethodTable = nameof(StringMethodTable);
internal const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress);

View file

@ -91,6 +91,15 @@ internal struct DacpMethodTableData
public int bIsDynamic;
public int bContainsGCPointers;
}
internal struct DacpUsefulGlobalsData
{
public ulong ArrayMethodTable;
public ulong StringMethodTable;
public ulong ObjectMethodTable;
public ulong ExceptionMethodTable;
public ulong FreeMethodTable;
}
#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value
[GeneratedComInterface]
@ -280,7 +289,7 @@ internal unsafe partial interface ISOSDacInterface
// Other
[PreserveSig]
int GetUsefulGlobals(/*struct DacpUsefulGlobalsData */ void* data);
int GetUsefulGlobals(DacpUsefulGlobalsData* data);
[PreserveSig]
int GetClrWatsonBuckets(ulong thread, void* pGenericModeBlock);
[PreserveSig]

View file

@ -403,7 +403,30 @@ internal sealed partial class SOSDacImpl : ISOSDacInterface, ISOSDacInterface2,
}
public unsafe int GetTLSIndex(uint* pIndex) => HResults.E_NOTIMPL;
public unsafe int GetUsefulGlobals(void* data) => HResults.E_NOTIMPL;
public unsafe int GetUsefulGlobals(DacpUsefulGlobalsData* data)
{
try
{
data->ArrayMethodTable = _target.ReadPointer(
_target.ReadGlobalPointer(Constants.Globals.ObjectArrayMethodTable));
data->StringMethodTable = _target.ReadPointer(
_target.ReadGlobalPointer(Constants.Globals.StringMethodTable));
data->ObjectMethodTable = _target.ReadPointer(
_target.ReadGlobalPointer(Constants.Globals.ObjectMethodTable));
data->ExceptionMethodTable = _target.ReadPointer(
_target.ReadGlobalPointer(Constants.Globals.ExceptionMethodTable));
data->FreeMethodTable = _target.ReadPointer(
_target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable));
}
catch (System.Exception ex)
{
return ex.HResult;
}
return HResults.S_OK;
}
public unsafe int GetWorkRequestData(ulong addrWorkRequest, void* data) => HResults.E_NOTIMPL;
public unsafe int IsRCWDCOMProxy(ulong rcwAddress, int* inDCOMProxy) => HResults.E_NOTIMPL;
public unsafe int TraverseEHInfo(ulong ip, void* pCallback, void* token) => HResults.E_NOTIMPL;