Skip to content

[cDAC] Implement EnumerateMonitorEventWaitList for cDAC#129054

Open
barosiak wants to merge 2 commits into
dotnet:mainfrom
barosiak:barosiak/EnumerateMonitorEventWaitList
Open

[cDAC] Implement EnumerateMonitorEventWaitList for cDAC#129054
barosiak wants to merge 2 commits into
dotnet:mainfrom
barosiak:barosiak/EnumerateMonitorEventWaitList

Conversation

@barosiak
Copy link
Copy Markdown
Member

@barosiak barosiak commented Jun 5, 2026

Summary

Implement DacDbiImpl.EnumerateMonitorEventWaitList in the cDAC to enumerate threads waiting on a monitor lock for a given object.

Changes

  • DacDbiImpl.cs - Implement EnumerateMonitorEventWaitList with #if DEBUG legacy validation
  • DacDbiImplTests.cs - Add 4 test methods (16 cases across architectures) covering no sync block, null callback, ConditionalWeakTable miss/empty list, and single/multiple/non-waiting thread scenarios

@barosiak barosiak self-assigned this Jun 5, 2026
Copilot AI review requested due to automatic review settings June 5, 2026 21:48
@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.

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.

Pull request overview

Implements DacDbiImpl.EnumerateMonitorEventWaitList in the cDAC managed DacDbiImpl to enumerate threads waiting on a monitor’s condition wait list for a given object, and adds unit tests exercising key scenarios across architectures.

Changes:

  • Added a cDAC implementation of EnumerateMonitorEventWaitList that reads the Monitor.s_conditionTable, resolves the object’s Condition via ConditionalWeakTable, maps per-thread waiter objects to threads, then walks the waiters linked list to invoke the callback.
  • Added #if DEBUG validation comparing cDAC results against legacy DAC results.
  • Added unit tests covering: no sync block, null callback, missing condition / empty waiters list, and single/multiple/non-waiting thread cases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs Adds the cDAC implementation of EnumerateMonitorEventWaitList plus DEBUG-only legacy cross-validation.
src/native/managed/cdac/tests/UnitTests/DacDbiImplTests.cs Adds helper infrastructure and new tests for EnumerateMonitorEventWaitList behavior across architectures.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 5, 2026 22:59
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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment on lines +3206 to +3219
// Build a map of Waiter objects to their owning Threads.
var waiterToThreadMap = new Dictionary<ulong, TargetPointer>();
Contracts.IThread threadContract = _target.Contracts.Thread;
Contracts.ThreadStoreData threadStore = threadContract.GetThreadStoreData();
TargetPointer currentThread = threadStore.FirstThread;
while (currentThread != TargetPointer.Null)
{
Contracts.ThreadData threadData = threadContract.GetThreadData(currentThread);

if (_target.Contracts.ManagedTypeSource.TryGetThreadStaticFieldAddress(
"System.Threading.Condition", "t_waiterForCurrentThread", currentThread, out TargetPointer waiterSlot))
{
TargetPointer waiterObj = _target.ReadPointer(waiterSlot);
if (waiterObj != TargetPointer.Null)
Comment on lines +1002 to +1009
var slotFragment = allocator.Allocate((ulong)ptrSize, $"WaiterSlot_{thread.Value:x}");
helpers.WritePointer(slotFragment.Data, waiterFragments[waiterIdx].Address);

TargetPointer outAddr = new(slotFragment.Address);
mockMts.Setup(m => m.TryGetThreadStaticFieldAddress(
"System.Threading.Condition", "t_waiterForCurrentThread", thread, out outAddr))
.Returns(true);
waiterIdx++;
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.

2 participants