Skip to content

Look up TEB from OS thread ID instead of DacpThreadData.teb#5804

Merged
max-charlamb merged 3 commits intodotnet:mainfrom
max-charlamb:dev/maxcharlamb/remove-teb-from-getthread
Apr 16, 2026
Merged

Look up TEB from OS thread ID instead of DacpThreadData.teb#5804
max-charlamb merged 3 commits intodotnet:mainfrom
max-charlamb:dev/maxcharlamb/remove-teb-from-getthread

Conversation

@max-charlamb
Copy link
Copy Markdown
Member

Note

This PR was generated with the assistance of GitHub Copilot.

Summary

Stop reading the TEB from DacpThreadData.teb in the !Threads command and instead look it up via IDebuggerServices::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 !Threads command reads the COM apartment state (STA/MTA/NTA) by dereferencing TEB.ReservedForOle. Previously it used Thread.teb from DacpThreadData; now it calls GetDebuggerServices()->GetThreadTeb(Thread.osThreadId) to get the TEB address.

New test: ThreadApartment

Added a new SOS integration test that validates clrthreads properly displays COM apartment state:

  • Debuggee: Creates one STA thread (SetApartmentState(STA)) and one MTA thread before breaking
  • Script: Verifies the Apt column contains both STA and MTA values
  • Windows-only: Guarded in both the test method (OS.Kind != OSKind.Windows) and the script (IFDEF:WINDOWS)

Verification

Manually verified with cdb against a dump containing STA/MTA threads:

  • Original SOS: STA 1, MTA 4
  • New SOS: STA 1, MTA 4 (identical output)

Related PRs

max-charlamb and others added 2 commits April 14, 2026 13:36
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>
@max-charlamb max-charlamb requested review from hoyosjs and jkotas April 14, 2026 19:54
@max-charlamb max-charlamb marked this pull request as ready for review April 14, 2026 19:54
@max-charlamb max-charlamb requested a review from a team as a code owner April 14, 2026 19:54
Copilot AI review requested due to automatic review settings April 14, 2026 19:54
jkotas
jkotas previously approved these changes Apr 14, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@max-charlamb max-charlamb force-pushed the dev/maxcharlamb/remove-teb-from-getthread branch from be41b92 to 1f7f78f Compare April 14, 2026 23:07
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>
@max-charlamb max-charlamb force-pushed the dev/maxcharlamb/remove-teb-from-getthread branch 3 times, most recently from d29e165 to 547c912 Compare April 15, 2026 15:43
@max-charlamb max-charlamb force-pushed the dev/maxcharlamb/remove-teb-from-getthread branch from 547c912 to 2539add Compare April 15, 2026 15:54
@max-charlamb max-charlamb requested a review from jkotas April 15, 2026 19:35
@max-charlamb max-charlamb merged commit 9695c17 into dotnet:main Apr 16, 2026
19 checks passed
@max-charlamb max-charlamb deleted the dev/maxcharlamb/remove-teb-from-getthread branch April 16, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants