diff --git a/docs/design/datacontracts/Thread.md b/docs/design/datacontracts/Thread.md index f1345105acb6aa..c245c25e4e8eeb 100644 --- a/docs/design/datacontracts/Thread.md +++ b/docs/design/datacontracts/Thread.md @@ -36,7 +36,6 @@ record struct ThreadData ( TargetPointer AllocContextLimit; TargetPointer Frame; TargetPointer FirstNestedException; - TargetPointer TEB; TargetPointer LastThrownObjectHandle; TargetPointer NextThread; ); @@ -97,7 +96,6 @@ The contract additionally depends on these data descriptors | `Thread` | `Frame` | Pointer to current frame | | `Thread` | `CachedStackBase` | Pointer to the base of the stack | | `Thread` | `CachedStackLimit` | Pointer to the limit of the stack | -| `Thread` | `TEB` | Thread Environment Block pointer | | `Thread` | `LastThrownObject` | Handle to last thrown exception object | | `Thread` | `LinkNext` | Pointer to get next thread | | `Thread` | `ExceptionTracker` | Pointer to exception tracking information | @@ -184,7 +182,6 @@ ThreadData GetThreadData(TargetPointer address) AllocContextPointer: allocContextPointer, AllocContextLimit: allocContextLimit, Frame: target.ReadPointer(address + /* Thread::Frame offset */), - TEB : /* Has Thread::TEB offset */ ? target.ReadPointer(address + /* Thread::TEB offset */) : TargetPointer.Null, LastThrownObjectHandle : target.ReadPointer(address + /* Thread::LastThrownObject offset */), FirstNestedException : firstNestedException, NextThread: target.ReadPointer(address + /* Thread::LinkNext offset */) - threadLinkOffset; diff --git a/src/coreclr/debug/daccess/enummem.cpp b/src/coreclr/debug/daccess/enummem.cpp index f39f576993f027..a329019ae051dc 100644 --- a/src/coreclr/debug/daccess/enummem.cpp +++ b/src/coreclr/debug/daccess/enummem.cpp @@ -1227,10 +1227,6 @@ HRESULT ClrDataAccess::EnumMemDumpAllThreadsStack(CLRDataEnumMemoryFlags flags) // Write out the Thread instance DacEnumHostDPtrMem(pThread); - // @TODO - // write TEB pointed by the thread - // DacEnumHostDPtrMem(pThread->GetTEB()); - // @TODO // If CLR is hosted, we want to write out fiber data diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 6f322bf5413e5f..cf7110ea284094 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -885,11 +885,9 @@ HRESULT ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThre threadData->context = PTR_CDADDR(AppDomain::GetCurrentDomain()); threadData->domain = PTR_CDADDR(AppDomain::GetCurrentDomain()); threadData->lockCount = (DWORD)-1; -#ifndef TARGET_UNIX - threadData->teb = TO_CDADDR(thread->m_pTEB); -#else + // TEB is no longer provided by the runtime. Consumers should look up the TEB + // from the OS thread ID via the debugger's native API (e.g., IDebuggerServices::GetThreadTeb). threadData->teb = (CLRDATA_ADDRESS)NULL; -#endif threadData->lastThrownObjectHandle = TO_CDADDR(thread->m_LastThrownObjectHandle); threadData->nextThread = diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index 0ee65734c32da2..427b7c8341a775 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -53,7 +53,6 @@ CDAC_TYPE_FIELD(Thread, TYPE(GCHandle), LastThrownObject, cdac_data::Las CDAC_TYPE_FIELD(Thread, T_POINTER, LinkNext, cdac_data::Link) CDAC_TYPE_FIELD(Thread, T_POINTER, ThreadLocalDataPtr, cdac_data::ThreadLocalDataPtr) #ifndef TARGET_UNIX -CDAC_TYPE_FIELD(Thread, T_POINTER, TEB, cdac_data::TEB) CDAC_TYPE_FIELD(Thread, T_POINTER, UEWatsonBucketTrackerBuckets, cdac_data::UEWatsonBucketTrackerBuckets) #endif CDAC_TYPE_END(Thread) diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 8d554cbca625b7..ac6744c92ecb4d 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -1513,8 +1513,6 @@ void Thread::InitThread() #ifndef TARGET_UNIX (void) _controlfp_s( NULL, _RC_NEAR, _RC_CHOP|_RC_UP|_RC_DOWN|_RC_NEAR ); - m_pTEB = (struct _NT_TIB*)NtCurrentTeb(); - #endif // !TARGET_UNIX if (m_CacheStackBase == 0) diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index e120e0b3bdddc2..7e400bbc3a6ba3 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -912,20 +912,6 @@ class Thread InterpThreadContext* GetOrCreateInterpThreadContext(); #endif // FEATURE_INTERPRETER -#ifndef TARGET_UNIX -private: - _NT_TIB *m_pTEB; -public: - _NT_TIB *GetTEB() { - LIMITED_METHOD_CONTRACT; - return m_pTEB; - } - PEXCEPTION_REGISTRATION_RECORD *GetExceptionListPtr() { - WRAPPER_NO_CONTRACT; - return &GetTEB()->ExceptionList; - } -#endif // !TARGET_UNIX - inline void SetTHAllocContextObj(TypeHandle th) {LIMITED_METHOD_CONTRACT; m_thAllocContextObj = th; } inline TypeHandle GetTHAllocContextObj() {LIMITED_METHOD_CONTRACT; return m_thAllocContextObj; } @@ -3786,7 +3772,6 @@ struct cdac_data static constexpr size_t ProfilerFilterContext = offsetof(Thread, m_pProfilerFilterContext); #endif // PROFILING_SUPPORTED #ifndef TARGET_UNIX - static constexpr size_t TEB = offsetof(Thread, m_pTEB); static constexpr size_t UEWatsonBucketTrackerBuckets = offsetof(Thread, m_ExceptionState) + offsetof(ThreadExceptionState, m_UEWatsonBucketTracker) + offsetof(EHWatsonBucketTracker, m_WatsonUnhandledInfo.m_pUnhandledBuckets); #endif diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index 3e235ddcafcdd5..f265094ce9876a 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -2893,12 +2893,8 @@ BOOL Thread::RedirectThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt) #ifdef _DEBUG // In some rare cases the stack pointer may be outside the stack limits. // SetThreadContext would fail assuming that we are trying to bypass CFG. - // - // NB: the check here is slightly more strict than what OS requires, - // but it is simple and uses only documented parts of TEB - auto pTeb = this->GetTEB(); void* stackPointer = (void*)GetSP(pCtx); - if ((stackPointer < pTeb->StackLimit) || (stackPointer > pTeb->StackBase)) + if ((stackPointer < this->GetCachedStackLimit()) || (stackPointer > this->GetCachedStackBase())) { return (FALSE); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs index 98d33c30a9254a..f699c639cdc86c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs @@ -38,7 +38,6 @@ public record struct ThreadData( TargetPointer AllocContextLimit, TargetPointer Frame, TargetPointer FirstNestedException, - TargetPointer TEB, TargetPointer LastThrownObjectHandle, TargetPointer NextThread); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs index fe2aa710303490..c0b5cfc619e441 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs @@ -98,7 +98,6 @@ ThreadData IThread.GetThreadData(TargetPointer threadPointer) thread.RuntimeThreadLocals?.AllocContext.GCAllocationContext.Limit ?? TargetPointer.Null, thread.Frame, firstNestedException, - thread.TEB, thread.LastThrownObject.Handle, GetThreadFromLink(thread.LinkNext)); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs index 8cb0fe073b957d..83579602848ab9 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs @@ -23,8 +23,6 @@ public Thread(Target target, TargetPointer address) CachedStackBase = target.ReadPointerField(address, type, nameof(CachedStackBase)); CachedStackLimit = target.ReadPointerField(address, type, nameof(CachedStackLimit)); - // TEB does not exist on certain platforms - TEB = target.ReadPointerFieldOrNull(address, type, nameof(TEB)); LastThrownObject = target.ProcessedData.GetOrAdd( target.ReadPointerField(address, type, nameof(LastThrownObject))); LinkNext = target.ReadPointerField(address, type, nameof(LinkNext)); @@ -46,7 +44,6 @@ public Thread(Target target, TargetPointer address) public TargetPointer Frame { get; init; } public TargetPointer CachedStackBase { get; init; } public TargetPointer CachedStackLimit { get; init; } - public TargetPointer TEB { get; init; } public ObjectHandle LastThrownObject { get; init; } public TargetPointer LinkNext { get; init; } public TargetPointer ExceptionTracker { get; init; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs index b7379397373f7f..f69ca8d475f590 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs @@ -4266,7 +4266,7 @@ int ISOSDacInterface.GetThreadData(ClrDataAddress thread, DacpThreadData* data) data->lockCount = -1; // Always set to -1 - lock count was .NET Framework and no longer needed data->pFrame = threadData.Frame.ToClrDataAddress(_target); data->firstNestedException = threadData.FirstNestedException.ToClrDataAddress(_target); - data->teb = threadData.TEB.ToClrDataAddress(_target); + data->teb = 0; // TEB is no longer provided by the DAC - consumers should look it up from the OS thread ID data->lastThrownObjectHandle = threadData.LastThrownObjectHandle.ToClrDataAddress(_target); data->nextThread = threadData.NextThread.ToClrDataAddress(_target); } @@ -4295,7 +4295,6 @@ int ISOSDacInterface.GetThreadData(ClrDataAddress thread, DacpThreadData* data) Debug.Assert(data->lockCount == dataLocal.lockCount, $"cDAC: {data->lockCount}, DAC: {dataLocal.lockCount}"); Debug.Assert(data->pFrame == dataLocal.pFrame, $"cDAC: {data->pFrame:x}, DAC: {dataLocal.pFrame:x}"); Debug.Assert(data->firstNestedException == dataLocal.firstNestedException, $"cDAC: {data->firstNestedException:x}, DAC: {dataLocal.firstNestedException:x}"); - Debug.Assert(data->teb == dataLocal.teb, $"cDAC: {data->teb:x}, DAC: {dataLocal.teb:x}"); Debug.Assert(data->lastThrownObjectHandle == dataLocal.lastThrownObjectHandle, $"cDAC: {data->lastThrownObjectHandle:x}, DAC: {dataLocal.lastThrownObjectHandle:x}"); Debug.Assert(data->nextThread == dataLocal.nextThread, $"cDAC: {data->nextThread:x}, DAC: {dataLocal.nextThread:x}"); } diff --git a/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs b/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs index 2bb87b3288c8e2..363604cc885609 100644 --- a/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs +++ b/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs @@ -85,7 +85,6 @@ private static (TestPlaceholderTarget Target, IXCLRDataTask Task) CreateTargetWi AllocContextLimit: TargetPointer.Null, Frame: TargetPointer.Null, FirstNestedException: firstNestedException, - TEB: TargetPointer.Null, LastThrownObjectHandle: lastThrownObjectHandle, NextThread: TargetPointer.Null)); @@ -464,7 +463,6 @@ private static (IXCLRDataTask Task, string ExpectedMessage) CreateTargetWithLast AllocContextLimit: TargetPointer.Null, Frame: TargetPointer.Null, FirstNestedException: firstNestedException, - TEB: TargetPointer.Null, LastThrownObjectHandle: lastThrownObjectHandle, NextThread: TargetPointer.Null)); diff --git a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.Thread.cs b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.Thread.cs index 939f0674ec8c76..e152354c22577c 100644 --- a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.Thread.cs +++ b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.Thread.cs @@ -178,7 +178,6 @@ internal sealed class MockThread : TypedView private const string FrameFieldName = "Frame"; private const string CachedStackBaseFieldName = "CachedStackBase"; private const string CachedStackLimitFieldName = "CachedStackLimit"; - private const string TEBFieldName = "TEB"; private const string LastThrownObjectFieldName = "LastThrownObject"; private const string LinkNextFieldName = "LinkNext"; private const string ExceptionTrackerFieldName = "ExceptionTracker"; @@ -198,7 +197,6 @@ public static Layout CreateLayout(MockTarget.Architecture architectu .AddPointerField(FrameFieldName) .AddPointerField(CachedStackBaseFieldName) .AddPointerField(CachedStackLimitFieldName) - .AddPointerField(TEBFieldName) .AddPointerField(LastThrownObjectFieldName) .AddPointerField(LinkNextFieldName) .AddPointerField(ExceptionTrackerFieldName)