From 6296fdf5b4a6350097be0d78440b3339c080a6aa Mon Sep 17 00:00:00 2001 From: rcj1 Date: Sun, 13 Jul 2025 10:55:37 -0700 Subject: [PATCH 1/4] adding GetTLSIndex cDAC implementation --- .../debug/runtimeinfo/datadescriptor.h | 2 + .../Constants.cs | 2 + .../Legacy/SOSDacImpl.cs | 37 ++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index 04d6070ac6098d..80b9572bc839e9 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -959,6 +959,7 @@ CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT) CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE) CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data::SyncBlockValue) CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST) +CDAC_GLOBAL(TlsOutOfIndexes, uint32, TLS_OUT_OF_INDEXES) CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data::ArrayBoundsZero) CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass) CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable) @@ -968,6 +969,7 @@ 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(TlsIndex, &::g_TlsIndex) #ifdef STRESS_LOG CDAC_GLOBAL(StressLogEnabled, uint8, 1) CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog) 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..90ec2241bf11a3 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,7 @@ public static class Globals public const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress); public const string MiniMetaDataBuffMaxSize = nameof(MiniMetaDataBuffMaxSize); + public const string TlsIndex = nameof(TlsIndex); public const string StressLogEnabled = nameof(StressLogEnabled); public const string StressLogHasModuleTable = nameof(StressLogHasModuleTable); @@ -51,6 +52,7 @@ public static class Globals public const string ExecutionManagerCodeRangeMapAddress = nameof(ExecutionManagerCodeRangeMapAddress); public const string StubCodeBlockLast = nameof(StubCodeBlockLast); + public const string TlsOutOfIndexes = nameof(TlsOutOfIndexes); public const string PlatformMetadata = nameof(PlatformMetadata); public const string ProfilerControlBlock = nameof(ProfilerControlBlock); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 4a07701f68daa1..95405561d046d4 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -1644,8 +1644,43 @@ 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 TlsOutOfIndexes = _target.ReadGlobal(Constants.Globals.TlsOutOfIndexes); + uint TlsIndex = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndex)); + if (TlsIndex == TlsOutOfIndexes) + { + *pIndex = 0; + hr = HResults.S_FALSE; + } + else + { + *pIndex = TlsIndex; + } + } + 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) From 0b58aabc0c028949723b778d4f39cf883186a538 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 15 Jul 2025 10:02:46 -0700 Subject: [PATCH 2/4] refactoring to use _tls_index and g_offsetOfCurrentThreadInfo for cDAC API --- src/coreclr/debug/runtimeinfo/datadescriptor.h | 3 ++- src/coreclr/inc/dacvars.h | 1 + src/coreclr/vm/threads.cpp | 6 +++--- src/coreclr/vm/vars.cpp | 1 + src/coreclr/vm/vars.hpp | 1 + .../Constants.cs | 3 ++- .../cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs | 8 +++++--- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index 80b9572bc839e9..9b7abc55c437ce 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -969,7 +969,8 @@ 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(TlsIndex, &::g_TlsIndex) +CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo) +CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index) #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 90ec2241bf11a3..f81c0b43100d50 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -27,7 +27,8 @@ public static class Globals public const string MiniMetaDataBuffAddress = nameof(MiniMetaDataBuffAddress); public const string MiniMetaDataBuffMaxSize = nameof(MiniMetaDataBuffMaxSize); - public const string TlsIndex = nameof(TlsIndex); + 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 95405561d046d4..9110e1eb54a305 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -1652,15 +1652,17 @@ int ISOSDacInterface.GetTLSIndex(uint* pIndex) try { uint TlsOutOfIndexes = _target.ReadGlobal(Constants.Globals.TlsOutOfIndexes); - uint TlsIndex = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndex)); - if (TlsIndex == TlsOutOfIndexes) + uint TlsIndexBase = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndexBase)); + uint OffsetOfCurrentThreadInfo = _target.Read(_target.ReadGlobalPointer(Constants.Globals.OffsetOfCurrentThreadInfo)); + uint CombinedTlsIndex = TlsIndexBase + (OffsetOfCurrentThreadInfo << 16) + 0x80000000; + if (CombinedTlsIndex == TlsOutOfIndexes) { *pIndex = 0; hr = HResults.S_FALSE; } else { - *pIndex = TlsIndex; + *pIndex = CombinedTlsIndex; } } catch (System.Exception ex) From ce38f4fad2abf0c63c8be90fec04bd64f0e3c7be Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 15 Jul 2025 10:30:01 -0700 Subject: [PATCH 3/4] refactoring to use _tls_index and g_offsetOfCurrentThreadInfo for cDAC API --- src/coreclr/debug/runtimeinfo/datadescriptor.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index 9b7abc55c437ce..e4f3ad714251f3 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -970,7 +970,9 @@ 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) From 779153fa1e6e9d2f22a12da7bf4c99daacdb733e Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 16 Jul 2025 18:32:43 -0700 Subject: [PATCH 4/4] removing TlsOutOfIndexes --- src/coreclr/debug/runtimeinfo/datadescriptor.h | 1 - .../Constants.cs | 1 - .../cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs | 11 +---------- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index e4f3ad714251f3..30e6ef8c105c8c 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -959,7 +959,6 @@ CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT) CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE) CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data::SyncBlockValue) CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST) -CDAC_GLOBAL(TlsOutOfIndexes, uint32, TLS_OUT_OF_INDEXES) CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data::ArrayBoundsZero) CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass) CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable) 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 f81c0b43100d50..b4e0011e1da0a4 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs @@ -53,7 +53,6 @@ public static class Globals public const string ExecutionManagerCodeRangeMapAddress = nameof(ExecutionManagerCodeRangeMapAddress); public const string StubCodeBlockLast = nameof(StubCodeBlockLast); - public const string TlsOutOfIndexes = nameof(TlsOutOfIndexes); public const string PlatformMetadata = nameof(PlatformMetadata); public const string ProfilerControlBlock = nameof(ProfilerControlBlock); diff --git a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs index 9110e1eb54a305..60fa4f07da95eb 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs @@ -1651,19 +1651,10 @@ int ISOSDacInterface.GetTLSIndex(uint* pIndex) int hr = HResults.S_OK; try { - uint TlsOutOfIndexes = _target.ReadGlobal(Constants.Globals.TlsOutOfIndexes); uint TlsIndexBase = _target.Read(_target.ReadGlobalPointer(Constants.Globals.TlsIndexBase)); uint OffsetOfCurrentThreadInfo = _target.Read(_target.ReadGlobalPointer(Constants.Globals.OffsetOfCurrentThreadInfo)); uint CombinedTlsIndex = TlsIndexBase + (OffsetOfCurrentThreadInfo << 16) + 0x80000000; - if (CombinedTlsIndex == TlsOutOfIndexes) - { - *pIndex = 0; - hr = HResults.S_FALSE; - } - else - { - *pIndex = CombinedTlsIndex; - } + *pIndex = CombinedTlsIndex; } catch (System.Exception ex) {