Look up TEB from OS thread ID instead of DacpThreadData.teb#5804
Merged
max-charlamb merged 3 commits intodotnet:mainfrom Apr 16, 2026
Merged
Conversation
The !Threads command was reading the COM apartment state (STA/MTA/NTA) by using the TEB address from DacpThreadData.teb. This couples the SOS command to a runtime-internal field that is being removed from the DAC/cDAC Thread data contract. Instead, look up the TEB via the debugger services API (IDebuggerServices::GetThreadTeb) using the OS thread ID that is already available in DacpThreadData.osThreadId. This is the same mechanism SOS uses elsewhere for TEB access and does not depend on the DAC carrying the TEB pointer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a new SOS integration test that validates the !Threads (clrthreads) command properly displays COM apartment state (STA/MTA) in the Apt column. The test creates a debuggee with explicit STA and MTA threads using Thread.SetApartmentState before Thread.Start, then verifies clrthreads output contains both STA and MTA values. This test is Windows-only (guarded in both the test method and script) since COM apartment state is a Windows concept. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jkotas
previously approved these changes
Apr 14, 2026
be41b92 to
1f7f78f
Compare
max-charlamb
added a commit
to dotnet/runtime
that referenced
this pull request
Apr 15, 2026
> [!NOTE] > This PR was generated with the assistance of GitHub Copilot. ## Summary Remove the TEB (Thread Environment Block) pointer from the DAC/cDAC Thread data contract. Consumers should look up the TEB from the OS thread ID via the debugger's native API instead. ## Background The `Thread::m_pTEB` field was exposed through `DacpThreadData.teb` and through the cDAC `ThreadData.TEB` contract field. Analysis of all consumers shows: - **SOS** reads `DacpThreadData.teb` in one place (`strike.cpp:4460`) to display COM apartment state in `!Threads`. A companion PR in dotnet/diagnostics switches this to use `IDebuggerServices::GetThreadTeb(osThreadId)` instead. - **ClrMD** reads `DacpThreadData.Teb` to derive `StackBase`/`StackLimit`. A companion PR in microsoft/clrmd switches this to use `IThreadReader.GetThreadTeb(osThreadId)` instead. - **NativeAOT** already returns `TargetPointer.Null` for TEB. - **Non-Windows** platforms already return NULL for TEB. ## Changes - `request.cpp`: Always set `threadData->teb = NULL` (field retained for binary layout compatibility) - `datadescriptor.inc`: Remove TEB field from Thread type descriptor - `threads.h`: Remove TEB from `cdac_data<Thread>` - `Data/Thread.cs`: Remove TEB property and reading logic - `Thread_1.cs`: Remove TEB from ThreadData construction - `IThread.cs`: Remove TEB from ThreadData record - `SOSDacImpl.cs`: Set `data->teb = 0`, remove debug assertion - `Thread.md`: Remove TEB from data contract documentation - Test mocks: Remove TEB from mock thread descriptors ## Companion PRs - dotnet/diagnostics#5804 — SOS switches to `GetThreadTeb(osThreadId)` for apartment state display + new ThreadApartment regression test - microsoft/clrmd#1419 — `DacRuntime` switches to `IThreadReader.GetThreadTeb(osThreadId)` for stack bounds ## Validation - cDAC build: 0 warnings, 0 errors - cDAC tests: 1586/1586 passed - cdb verification: `!Threads` output identical between legacy DAC and cDAC (Release) - Manual cdb verification: STA/MTA apartment state displays correctly with both old and new SOS --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
d29e165 to
547c912
Compare
547c912 to
2539add
Compare
jkotas
approved these changes
Apr 16, 2026
noahfalk
approved these changes
Apr 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR was generated with the assistance of GitHub Copilot.
Summary
Stop reading the TEB from
DacpThreadData.tebin the!Threadscommand and instead look it up viaIDebuggerServices::GetThreadTeb(osThreadId). This decouples SOS from a runtime-internal field that is being removed from the DAC/cDAC Thread data contract.Changes
strike.cpp
The
!Threadscommand reads the COM apartment state (STA/MTA/NTA) by dereferencingTEB.ReservedForOle. Previously it usedThread.tebfromDacpThreadData; now it callsGetDebuggerServices()->GetThreadTeb(Thread.osThreadId)to get the TEB address.New test: ThreadApartment
Added a new SOS integration test that validates
clrthreadsproperly displays COM apartment state:SetApartmentState(STA)) and one MTA thread before breakingOS.Kind != OSKind.Windows) and the script (IFDEF:WINDOWS)Verification
Manually verified with cdb against a dump containing STA/MTA threads:
Related PRs