Skip to content

Slim ThreadStressLogData and simplify GetStressMessages API#129673

Open
max-charlamb wants to merge 1 commit into
dotnet:mainfrom
max-charlamb:maxcharlamb/stresslog-slim-threaddata
Open

Slim ThreadStressLogData and simplify GetStressMessages API#129673
max-charlamb wants to merge 1 commit into
dotnet:mainfrom
max-charlamb:maxcharlamb/stresslog-slim-threaddata

Conversation

@max-charlamb

@max-charlamb max-charlamb commented Jun 21, 2026

Copy link
Copy Markdown
Member

Follow-up based on #129272 (comment)

Summary

Reduce the public surface of ThreadStressLogData and simplify the GetStressMessages API signature.

Changes

  • ThreadStressLogData: Trimmed from 8 fields to 3: {Address, ThreadId, WriteHasWrapped}. The removed fields (NextPointer, CurrentPointer, ChunkListHead, ChunkListTail, CurrentWriteChunk) are internal traversal state only needed by the contract implementation.

  • GetStressMessages: Changed from GetStressMessages(ThreadStressLogData threadLog) to GetStressMessages(TargetPointer threadStressLogAddress). The contract re-reads the ThreadStressLog data internally from the address.

  • SOSDacImpl.GetStressLogMessageEnumerator: Simplified -- no longer needs to re-enumerate all threads to find the matching one. Passes the address directly to the contract.

Motivation

Feedback from PR #129272 review (noahfalk): the public ThreadStressLogData record exposed internal data structure implementation details (chunk pointers, write positions) that consumers don't need. Only ThreadId, WriteHasWrapped, and Address are used externally.

Related

@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.

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 narrows the stress log contract surface by slimming ThreadStressLogData down to essential fields and by changing IStressLog.GetStressMessages to accept a TargetPointer address (instead of a ThreadStressLogData value), updating SOS and tooling call sites accordingly.

Changes:

  • Reduce ThreadStressLogData to { Address, ThreadId, WriteHasWrapped } in the cDAC abstractions/design docs and adjust contract construction.
  • Change GetStressMessages signature to GetStressMessages(TargetPointer threadStressLogAddress) and re-read ThreadStressLog internally in the contract implementation.
  • Update consumers (SOSDacImpl bridge, dump tests, StressLogAnalyzer) to pass the thread log address.

Reviewed changes

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

Show a summary per file
File Description
src/tools/StressLogAnalyzer/src/StressLogAnalyzer.cs Updates calls to GetStressMessages to pass log.Address.
src/native/managed/cdac/tests/DumpTests/StressLogDumpTests.cs Updates contract test to pass thread.Address into GetStressMessages.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/SOSDacImpl.cs Simplifies message enumerator creation by passing the thread log address directly to the contract.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs Refactors contract traversal to accept a thread log address and re-read ThreadStressLog data internally.
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IStressLog.cs Slims ThreadStressLogData and updates GetStressMessages signature in the abstraction contract.
docs/design/datacontracts/StressLog.md Updates design documentation to reflect slimmer thread data and the new GetStressMessages signature.

Comment on lines +7323 to 7325
TargetPointer address = threadStressLogAddress.ToTargetPointer(_target);
IEnumerable<Contracts.StressMsgData> messages = stressLogContract.GetStressMessages(address);
ppEnum.Interface = new SOSStressLogMsgEnum(_target, messages);
Comment on lines +126 to +135
public IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress)
{
uint stressMsgHeaderSize = target.GetTypeInfo(DataType.StressMsgHeader).Size!.Value;
uint pointerSize = (uint)target.PointerSize;

Data.ThreadStressLog threadLog = target.ProcessedData.GetOrAdd<Data.ThreadStressLog>(threadStressLogAddress);

Data.StressLogChunk currentChunkData = target.ProcessedData.GetOrAdd<Data.StressLogChunk>(threadLog.CurrentWriteChunk);
TargetPointer currentReadChunk = threadLog.CurrentWriteChunk;
TargetPointer readPointer = threadLog.CurrentPointer;
TargetPointer readPointer = threadLog.CurrentPtr;
Reduce ThreadStressLogData public record from 8 fields to 3:
{Address, ThreadId, WriteHasWrapped}. The removed fields
(NextPointer, CurrentPointer, ChunkListHead, ChunkListTail,
CurrentWriteChunk) are internal traversal state that only the
contract implementation needs.

Change GetStressMessages to take a TargetPointer (the thread stress
log address) instead of the full record. The contract re-reads the
ThreadStressLog data internally from that address.

This also simplifies GetStressLogMessageEnumerator in SOSDacImpl --
it no longer needs to re-enumerate all threads to find the matching
one; it passes the address directly to the contract.

Fix pre-existing StressLogAnalyzer crash: contract version was
specified as numeric 2 instead of string "c2" in the hardcoded
contract descriptor JSON.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@max-charlamb max-charlamb force-pushed the maxcharlamb/stresslog-slim-threaddata branch from 0c7050b to 210d5a8 Compare June 21, 2026 20:18
@max-charlamb max-charlamb marked this pull request as ready for review June 21, 2026 22:33
@max-charlamb max-charlamb requested review from Copilot and jkotas June 21, 2026 22:33

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

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

Comment on lines 7319 to +7323
Contracts.IStressLog stressLogContract = _target.Contracts.StressLog;
if (!stressLogContract.HasStressLog())
return HResults.S_FALSE;

Contracts.StressLogData logData = stressLogContract.GetStressLogData();

// Find the matching thread
Contracts.ThreadStressLogData? matchedThread = null;
foreach (var thread in stressLogContract.GetThreadStressLogs(logData.Logs))
{
if (thread.Address == threadStressLogAddress.ToTargetPointer(_target))
{
matchedThread = thread;
break;
}
}

if (matchedThread is null)
return HResults.E_INVALIDARG;

IEnumerable<Contracts.StressMsgData> messages = stressLogContract.GetStressMessages(matchedThread.Value);
TargetPointer address = threadStressLogAddress.ToTargetPointer(_target);
Comment on lines +126 to 134
public IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress)
{
uint stressMsgHeaderSize = target.GetTypeInfo(DataType.StressMsgHeader).Size!.Value;
uint pointerSize = (uint)target.PointerSize;

Data.ThreadStressLog threadLog = target.ProcessedData.GetOrAdd<Data.ThreadStressLog>(threadStressLogAddress);

Data.StressLogChunk currentChunkData = target.ProcessedData.GetOrAdd<Data.StressLogChunk>(threadLog.CurrentWriteChunk);
TargetPointer currentReadChunk = threadLog.CurrentWriteChunk;
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