mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-10 10:00:57 +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:
parent
d461cdb401
commit
37253e00c3
6 changed files with 78 additions and 6 deletions
|
@ -1242,6 +1242,7 @@ public:
|
||||||
HRESULT GetMethodTableNameImpl(CLRDATA_ADDRESS mt, unsigned int count, _Inout_updates_z_(count) WCHAR *mtName, unsigned int *pNeeded);
|
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 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 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);
|
BOOL IsExceptionFromManagedCode(EXCEPTION_RECORD * pExceptionRecord);
|
||||||
#ifndef TARGET_UNIX
|
#ifndef TARGET_UNIX
|
||||||
|
|
|
@ -3460,13 +3460,47 @@ ClrDataAccess::GetHeapAnalyzeStaticData(struct DacpGcHeapAnalyzeData *analyzeDat
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
|
ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData* globalsData)
|
||||||
{
|
{
|
||||||
if (globalsData == NULL)
|
if (globalsData == NULL)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
SOSDacEnter();
|
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];
|
TypeHandle objArray = g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT];
|
||||||
if (objArray != NULL)
|
if (objArray != NULL)
|
||||||
globalsData->ArrayMethodTable = HOST_CDADDR(objArray.AsMethodTable());
|
globalsData->ArrayMethodTable = HOST_CDADDR(objArray.AsMethodTable());
|
||||||
|
@ -3478,8 +3512,7 @@ ClrDataAccess::GetUsefulGlobals(struct DacpUsefulGlobalsData *globalsData)
|
||||||
globalsData->ExceptionMethodTable = HOST_CDADDR(g_pExceptionClass);
|
globalsData->ExceptionMethodTable = HOST_CDADDR(g_pExceptionClass);
|
||||||
globalsData->FreeMethodTable = HOST_CDADDR(g_pFreeObjectMethodTable);
|
globalsData->FreeMethodTable = HOST_CDADDR(g_pFreeObjectMethodTable);
|
||||||
|
|
||||||
SOSDacLeave();
|
return S_OK;
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
|
|
|
@ -282,7 +282,10 @@ CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1 | 1 << 2)
|
||||||
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1)
|
CDAC_GLOBAL(ObjectToMethodTableUnmask, uint8, 1 | 1 << 1)
|
||||||
#endif //TARGET_64BIT
|
#endif //TARGET_64BIT
|
||||||
CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION)
|
CDAC_GLOBAL(SOSBreakingChangeVersion, uint8, SOS_BREAKING_CHANGE_VERSION)
|
||||||
|
CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass)
|
||||||
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
|
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(StringMethodTable, &::g_pStringClass)
|
||||||
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
|
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
|
||||||
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
|
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
|
||||||
|
|
|
@ -17,7 +17,10 @@ internal static class Constants
|
||||||
internal const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask);
|
internal const string ObjectToMethodTableUnmask = nameof(ObjectToMethodTableUnmask);
|
||||||
internal const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion);
|
internal const string SOSBreakingChangeVersion = nameof(SOSBreakingChangeVersion);
|
||||||
|
|
||||||
|
internal const string ExceptionMethodTable = nameof(ExceptionMethodTable);
|
||||||
internal const string FreeObjectMethodTable = nameof(FreeObjectMethodTable);
|
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 StringMethodTable = nameof(StringMethodTable);
|
||||||
|
|
||||||
internal const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress);
|
internal const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress);
|
||||||
|
|
|
@ -91,6 +91,15 @@ internal struct DacpMethodTableData
|
||||||
public int bIsDynamic;
|
public int bIsDynamic;
|
||||||
public int bContainsGCPointers;
|
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
|
#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value
|
||||||
|
|
||||||
[GeneratedComInterface]
|
[GeneratedComInterface]
|
||||||
|
@ -280,7 +289,7 @@ internal unsafe partial interface ISOSDacInterface
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int GetUsefulGlobals(/*struct DacpUsefulGlobalsData */ void* data);
|
int GetUsefulGlobals(DacpUsefulGlobalsData* data);
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
int GetClrWatsonBuckets(ulong thread, void* pGenericModeBlock);
|
int GetClrWatsonBuckets(ulong thread, void* pGenericModeBlock);
|
||||||
[PreserveSig]
|
[PreserveSig]
|
||||||
|
|
|
@ -403,7 +403,30 @@ internal sealed partial class SOSDacImpl : ISOSDacInterface, ISOSDacInterface2,
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe int GetTLSIndex(uint* pIndex) => HResults.E_NOTIMPL;
|
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 GetWorkRequestData(ulong addrWorkRequest, void* data) => HResults.E_NOTIMPL;
|
||||||
public unsafe int IsRCWDCOMProxy(ulong rcwAddress, int* inDCOMProxy) => 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;
|
public unsafe int TraverseEHInfo(ulong ip, void* pCallback, void* token) => HResults.E_NOTIMPL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue