Skip to content

[CrashReporter] Enable InProc CrashReporter for crashing GC threads - #131821

Open
mdh1418 wants to merge 1 commit into
dotnet:mainfrom
mdh1418:inproc-crash-report-gc-suspension
Open

[CrashReporter] Enable InProc CrashReporter for crashing GC threads#131821
mdh1418 wants to merge 1 commit into
dotnet:mainfrom
mdh1418:inproc-crash-report-gc-suspension

Conversation

@mdh1418

@mdh1418 mdh1418 commented Aug 4, 2026

Copy link
Copy Markdown
Member

Previously, the InProc CrashReporter skipped suspending and enumerating other managed threads during any GC scenario. However, in select GC scenarios, the thread running the reporter either owns the existing thread suspension or can safely establish its own suspension and walk managed call stacks.

This change tracks suspension ownership so the reporter can:

  • Reuse a completed suspension owned by the crashing thread.
  • Establish and later resume its own suspension when no GC suspension is active.
  • Continue avoiding thread enumeration when a suspension is incomplete or owned by another thread.

Reuse an existing suspension only when the crashing thread owns it, and allow workstation background GC to perform reporter-owned suspend and resume while preserving Server GC deadlock safeguards.

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

Copilot-Session: aa976a9e-b875-4524-82e1-1485d03d14fa
@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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates CoreCLR’s in-proc crash-report stack walker to allow managed thread enumeration in additional GC/suspension scenarios by tracking whether a runtime suspension is (a) unavailable, (b) already established and owned by the crashing thread, or (c) created by the crash reporter.

Changes:

  • Introduces CrashReportSuspensionOwnership to distinguish between an unusable suspension, a usable existing suspension, and a reporter-created suspension.
  • Reuses an existing completed suspension only when the crashing thread owns the ThreadStore lock; otherwise avoids enumerating other managed threads.
  • Resumes the runtime only when the crash reporter itself performed the suspension.

Comment on lines +492 to 496
// Do not wait for the ThreadStore lock while another suspension is starting or
// ending. In particular, a Server GC coordinator may hold the lock while waiting
// for a crashing parallel worker at a GC join. A fatal error already recorded on
// a GC thread also means the interrupted GC may never complete.
//
@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.

{
return crashThreadOwnsSuspension
? CrashReportSuspensionOwnership::Existing
: CrashReportSuspensionOwnership::Unavailable;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If I am reading this correctly, we will take CrashReportSuspensionOwnership::Unavailable; path when encounter a crash on a server GC thread. Is it the behavior we want?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The scenario I was imagining is in Server GC, there is a dedicated heap 0 thread that coordinates suspension, and the crash occurs in a Parallel Server GC worker. I was thinking that since the heap 0 thread controls SuspendEE/RestartEE that it wouldn't be safe to stackwalk other threads if the heap 0 thread can resume independently.

If the crashing thread is the one that owns Suspension, then we are able to walk suspended threads callstacks given it would be the one to RestartEE.

Does that sound right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants