Skip to content

[release/11.0] Release ThreadStore lock before blocking for shutdown - #133181

Open
github-actions[bot] wants to merge 1 commit into
release/11.0from
backport/pr-133049-to-release/11.0
Open

[release/11.0] Release ThreadStore lock before blocking for shutdown#133181
github-actions[bot] wants to merge 1 commit into
release/11.0from
backport/pr-133049-to-release/11.0

Conversation

@github-actions

@github-actions github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Backport of #133049 to release/11.0

/cc @steveisok

Customer Impact

  • Customer reported
  • Found internally

[Select one or both of the boxes. Describe how this issue impacts customers, citing the expected and actual behaviors and scope of the issue. If customer-reported, provide the issue number.]

Regression

  • Yes
  • No

[If yes, specify when the regression was introduced. Provide the PR or commit if known.]

Testing

[How was the fix verified? How was the issue missed previously? What tests were added?]

Risk

[High/Medium/Low. Justify the indication by mentioning how risks were measured and addressed.]

IMPORTANT: If this backport is for a servicing release, please verify that:

  • For .NET 8 and .NET 9: The PR target branch is release/X.0-staging, not release/X.0.
  • For .NET 10+: The PR target branch is release/X.0 (no -staging suffix).

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

## Summary

Prevent a debugger shutdown hang by releasing the ThreadStore lock
before a non-special thread is permanently parked for shutdown.

Addresses #126096.

## Background

Paired debugger and target dumps showed this wait chain:

1. A non-special runtime thread begins sending a debugger class-load
event and acquires ThreadStore.
2. It attempts to acquire the debugger lock after shutdown mode has
begun.
3. The shutdown-aware debugger lock releases its own lock and parks the
thread permanently in `WaitForEndOfShutdown`.
4. The enclosing ThreadStore lock holder never unwinds, leaving
ThreadStore permanently held.
5. The debugger helper cannot acquire ThreadStore to process
`DB_IPCE_ASYNC_BREAK`, so `ICorDebugProcess::Stop` never receives
SyncComplete.

This is distinct from the previously fixed ReadyToRun/`PtrHashMap`
deadlock paths.

## Fix

`Debugger::DoNotCallDirectlyPrivateLock` knows when a shutdown-mode
debugger lock will reject and permanently park a non-special thread. If
that thread owns ThreadStore, release it immediately before entering the
shutdown wait.

Using `ThreadSuspend::UnlockThreadStore` preserves the ThreadStore
ownership and cant-stop bookkeeping rather than releasing the underlying
Crst directly. Finalizer, debugger-helper, shutdown, and GC threads
retain ThreadStore because they are allowed to continue during shutdown.

## Testing

- `.\build.cmd -subset clr`
- Built and ran `foreground-shutdown` five times successfully.

> [!NOTE]
> This pull request description was drafted with GitHub Copilot.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

@steveisok steveisok added the Servicing-approved Approved for servicing release label Sep 3, 2026
@steveisok
steveisok requested a review from a team September 3, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants