Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/9.0-staging] [Profiler] Avoid Recursive ThreadStoreLock in Profiling Thread Enumerator #110665

Merged

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Dec 12, 2024

Backport of #110548 to release/9.0-staging

/cc @mdh1418

Customer Impact

  • Customer reported
  • Found internally

#110062
Profiler users invoking EnumThreads within a RuntimeSuspendFinished callback will cause an infinite wait because the EnumThreads will recursively acquire/release the ThreadStore lock.

Regression

  • Yes
  • No

This did not occur in .NET 8.0. The recursive ThreadStoreLock acquire/release was always there, but the condition that previously prevented this case causing an infinite wait was removed in #101782

Testing

The issue was reproduced locally and the fix was confirmed locally.
The issue was missed previously because there were no profiler tests covering this edge-case scenario. It is hard to cover all the ways our customers will use Profiler APIs.
A runtime test was added for this particular scenario, invoking the EnumThreads API within a RuntimeSuspendFinished callback.

Risk

Low. The changes only affect Profiler users that specifically invoke EnumThreads within a RuntimeSuspendFinished callback and trigger a GC.

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

  • The PR target branch is release/X.0-staging, not release/X.0.

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.

Profiling Enumerators look to acquire the ThreadStoreLock.
In release config, re-acquiring the ThreadStoreLock and
releasing it in ProfilerThreadEnum::Init will cause
problems if the callback invoking EnumThread has logic
that depends on the ThreadStoreLock being held.
To avoid recursively acquiring the ThreadStoreLock,
expand the condition when the profiling thread enumerator
shouldn't acquire the ThreadStoreLock.
There was a potential race condition when setting the flag
before suspending and resetting the flag after restarting.
For example, if the thread restarting runtime is preempted
right after resuming runtime, the flag could remain unset
by the time another thread looks to suspend runtime, which
would see that the flag as set.
Copy link
Contributor

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

@mdh1418 mdh1418 requested review from VSadov and tommcdon December 12, 2024 20:17
@mdh1418 mdh1418 added this to the 9.0.x milestone Dec 18, 2024
@tommcdon tommcdon added the Servicing-approved Approved for servicing release label Dec 18, 2024
@mdh1418
Copy link
Member

mdh1418 commented Dec 19, 2024

Approved via email.

@mdh1418 mdh1418 merged commit 7eb5ef2 into release/9.0-staging Dec 19, 2024
97 of 101 checks passed
@jkotas jkotas deleted the backport/pr-110548-to-release/9.0-staging branch December 29, 2024 15:49
@github-actions github-actions bot locked and limited conversation to collaborators Jan 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants