diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index 04d6070ac6098d..30e6ef8c105c8c 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -968,6 +968,10 @@ CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass) CDAC_GLOBAL_POINTER(SyncTableEntries, &::g_pSyncTable) CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress) CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize) +CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo) +#ifdef TARGET_WINDOWS +CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index) +#endif // TARGET_WINDOWS #ifdef STRESS_LOG CDAC_GLOBAL(StressLogEnabled, uint8, 1) CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog) diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h index 9f4af048edcee9..73090f2c96b278 100644 --- a/src/coreclr/inc/dacvars.h +++ b/src/coreclr/inc/dacvars.h @@ -115,6 +115,7 @@ DEFINE_DACVAR(PTR_SystemDomain, SystemDomain__m_pSystemDomain, SystemDomain::m_p DEFINE_DACVAR(DWORD, dac__g_debuggerWordTLSIndex, g_debuggerWordTLSIndex) #endif DEFINE_DACVAR(DWORD, dac__g_TlsIndex, g_TlsIndex) +DEFINE_DACVAR(DWORD, dac__g_offsetOfCurrentThreadInfo, g_offsetOfCurrentThreadInfo) #ifdef FEATURE_EH_FUNCLETS DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pEHClass, ::g_pEHClass) diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 1469ffe0e64453..6234251a0b2204 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -1142,13 +1142,13 @@ void InitThreadManager() #ifndef TARGET_UNIX _ASSERTE(GetThreadNULLOk() == NULL); - size_t offsetOfCurrentThreadInfo = Thread::GetOffsetOfThreadStatic(&t_CurrentThreadInfo); + g_offsetOfCurrentThreadInfo = (DWORD)Thread::GetOffsetOfThreadStatic(&t_CurrentThreadInfo); - _ASSERTE(offsetOfCurrentThreadInfo < 0x8000); + _ASSERTE(g_offsetOfCurrentThreadInfo < 0x8000); _ASSERTE(_tls_index < 0x10000); // Save t_CurrentThreadInfo location for debugger - SetIlsIndex((DWORD)(_tls_index + (offsetOfCurrentThreadInfo << 16) + 0x80000000)); + SetIlsIndex((DWORD)(_tls_index + (g_offsetOfCurrentThreadInfo << 16) + 0x80000000)); _ASSERTE(g_TrapReturningThreads == 0); #endif // !TARGET_UNIX diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp index 7b527e70c29ff3..31fc88e6005bf0 100644 --- a/src/coreclr/vm/vars.cpp +++ b/src/coreclr/vm/vars.cpp @@ -93,6 +93,7 @@ GPTR_IMPL(RCWCleanupList,g_pRCWCleanupList); GVAL_IMPL_INIT(DWORD, g_debuggerWordTLSIndex, TLS_OUT_OF_INDEXES); #endif GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES); +GVAL_IMPL_INIT(DWORD, g_offsetOfCurrentThreadInfo, 0); MethodTable* g_pCastHelpers; #ifdef FEATURE_EH_FUNCLETS diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index b846b25bdb20a1..9e98fbb87cb999 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -356,6 +356,7 @@ GPTR_DECL(MethodDesc, g_pObjectFinalizerMD); GVAL_DECL(DWORD, g_debuggerWordTLSIndex); #endif GVAL_DECL(DWORD, g_TlsIndex); +GVAL_DECL(DWORD, g_offsetOfCurrentThreadInfo); #ifdef FEATURE_EH_FUNCLETS GPTR_DECL(MethodTable, g_pEHClass); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs index ab45f4a9bbe290..b4e0011e1da0a4 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -27,6 +27,8 @@ public static class Globals public const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress); public const string MiniMetaDataBuffMaxSize = nameof(MiniMetaDataBuffMaxSize); + public const string OffsetOfCurrentThreadInfo = nameof(OffsetOfCurrentThreadInfo); + public const string TlsIndexBase = nameof(TlsIndexBase); public const string StressLogEnabled = nameof(StressLogEnabled); public const string StressLogHasModuleTable = nameof(StressLogHasModuleTable); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 4a07701f68daa1..60fa4f07da95eb 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -1644,8 +1644,36 @@ int ISOSDacInterface.GetThreadStoreData(DacpThreadStoreData* data) } int ISOSDacInterface.GetTLSIndex(uint* pIndex) - => _legacyImpl is not null ? _legacyImpl.GetTLSIndex(pIndex) : HResults.E_NOTIMPL; + { + if (pIndex == null) + return HResults.E_INVALIDARG; + int hr = HResults.S_OK; + try + { + uint TlsIndexBase = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndexBase)); + uint OffsetOfCurrentThreadInfo = _target.Read(_target.ReadGlobalPointer(Constants.Globals.OffsetOfCurrentThreadInfo)); + uint CombinedTlsIndex = TlsIndexBase + (OffsetOfCurrentThreadInfo << 16) + 0x80000000; + *pIndex = CombinedTlsIndex; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacyImpl is not null) + { + uint indexLocal; + int hrLocal = _legacyImpl.GetTLSIndex(&indexLocal); + Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}"); + if (hr == HResults.S_OK || hr == HResults.S_FALSE) + { + Debug.Assert(*pIndex == indexLocal); + } + } +#endif + return hr; + } int ISOSDacInterface.GetUsefulGlobals(DacpUsefulGlobalsData* data) { if (data == null)