Skip to content

[release/10.0] Release ThreadStore lock before blocking for shutdown - #133182

Merged
steveisok merged 1 commit into
release/10.0from
backport/pr-133049-to-release/10.0
Sep 4, 2026
Merged

[release/10.0] Release ThreadStore lock before blocking for shutdown#133182
steveisok merged 1 commit into
release/10.0from
backport/pr-133049-to-release/10.0

Conversation

@github-actions

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

Copy link
Copy Markdown
Contributor

Backport of #133049 to release/10.0

/cc @steveisok

Customer Impact

  • Customer reported
  • Found internally

Customers can experience an indefinite hang when using Stop Debugging or closing an application on .NET 10. This was reported in #126096 and confirmed internally with paired debugger and target process dumps. A non-special runtime class-load notification thread can retain the ThreadStore lock when parked during debugger shutdown, preventing debugger helper synchronization from completing.

Regression

  • Yes
  • No

This is a pre-existing race with no known regression point.

Testing

The CoreCLR build passed, and the foreground-shutdown test ran successfully five times. Targeted internal hosted-runtime A/B validation used identical inputs and layout except for the CoreCLR binaries: the unmodified release/10.0 parent build remained blocked until timeout, while the fixed build completed in approximately four seconds.

Risk

Low. The change is limited to debugger shutdown rejection, conditionally releases the ThreadStore lock through ThreadSuspend bookkeeping, and leaves special-thread behavior unchanged.

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 Servicing-consider Issue for next servicing release review Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Sep 3, 2026
@steveisok
steveisok requested a review from a team September 3, 2026 19:09
@steveisok
steveisok merged commit 4a596e3 into release/10.0 Sep 4, 2026
117 of 120 checks passed
@steveisok
steveisok deleted the backport/pr-133049-to-release/10.0 branch September 4, 2026 15:03
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