Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions docs/design/datacontracts/StressLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,8 @@ internal record struct StressLogData(

internal record struct ThreadStressLogData(
TargetPointer Address,
TargetPointer NextPointer,
ulong ThreadId,
bool WriteHasWrapped,
TargetPointer CurrentPointer,
TargetPointer ChunkListHead,
TargetPointer ChunkListTail,
TargetPointer CurrentWriteChunk);
bool WriteHasWrapped);

internal record struct StressMsgData(
uint Facility,
Expand All @@ -38,7 +33,7 @@ bool HasStressLog();
StressLogData GetStressLogData();
StressLogData GetStressLogData(TargetPointer stressLogPointer);
IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer logs);
IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog);
IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress);
bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer);
```

Expand Down Expand Up @@ -157,20 +152,15 @@ IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer logs)

yield return new ThreadStressLogData(
currentPointer,
threadStressLog.Next,
threadStressLog.ThreadId,
threadStressLog.WriteHasWrapped,
threadStressLog.CurrentPtr,
threadStressLog.ChunkListHead,
threadStressLog.ChunkListTail,
threadStressLog.CurrentWriteChunk);
threadStressLog.WriteHasWrapped);

currentPointer = threadStressLog.Next;
}
}

// Return messages going in reverse chronological order, newest first.
IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog)
IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress)
{
// 1. Get the current message pointer from the log and the info about the current chunk the runtime is writing into.
// Record our current read pointer as the current message pointer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,8 @@ public record struct StressLogData(

public record struct ThreadStressLogData(
TargetPointer Address,
TargetPointer NextPointer,
ulong ThreadId,
bool WriteHasWrapped,
TargetPointer CurrentPointer,
TargetPointer ChunkListHead,
TargetPointer ChunkListTail,
TargetPointer CurrentWriteChunk);
bool WriteHasWrapped);

public record struct StressMsgData(
uint Facility,
Expand All @@ -40,7 +35,7 @@ public interface IStressLog : IContract
StressLogData GetStressLogData() => throw new NotImplementedException();
StressLogData GetStressLogData(TargetPointer stressLog) => throw new NotImplementedException();
IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer Logs) => throw new NotImplementedException();
IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog) => throw new NotImplementedException();
IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress) => throw new NotImplementedException();
bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => throw new NotImplementedException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,8 @@ public IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer Logs)

yield return new ThreadStressLogData(
currentPointer,
threadStressLog.Next,
threadStressLog.ThreadId,
threadStressLog.WriteHasWrapped,
threadStressLog.CurrentPtr,
threadStressLog.ChunkListHead,
threadStressLog.ChunkListTail,
threadStressLog.CurrentWriteChunk);
threadStressLog.WriteHasWrapped);

currentPointer = threadStressLog.Next;
}
Expand Down Expand Up @@ -128,18 +123,20 @@ private TargetPointer GetFormatPointer(ulong formatOffset)
return TargetPointer.Null;
}

public IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog)
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;
Comment on lines +126 to 134
TargetPointer readPointer = threadLog.CurrentPointer;
TargetPointer readPointer = threadLog.CurrentPtr;
Comment on lines +126 to +135
bool readHasWrapped = false;
uint chunkSize = target.ReadGlobal<uint>(Constants.Globals.StressLogChunkSize);

TargetPointer currentPointer = threadLog.CurrentPointer;
TargetPointer currentPointer = threadLog.CurrentPtr;
// the last written log, if it wrapped around may have partially overwritten
// a previous record. Update currentPointer to reflect the last safe beginning of a record,
// but currentPointer shouldn't wrap around, otherwise it'll break our assumptions about stress
Expand Down Expand Up @@ -341,7 +338,7 @@ internal sealed class StressLog_1(Target target) : IStressLog
public StressLogData GetStressLogData() => traversal.GetStressLogData();
public StressLogData GetStressLogData(TargetPointer stressLog) => traversal.GetStressLogData(stressLog);
public IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer Logs) => traversal.GetThreadStressLogs(Logs);
public IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog) => traversal.GetStressMessages(threadLog);
public IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress) => traversal.GetStressMessages(threadStressLogAddress);
public bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => traversal.IsPointerInStressLog(stressLog, pointer);
}

Expand All @@ -354,6 +351,6 @@ internal sealed class StressLog_2(Target target) : IStressLog
public StressLogData GetStressLogData() => traversal.GetStressLogData();
public StressLogData GetStressLogData(TargetPointer stressLog) => traversal.GetStressLogData(stressLog);
public IEnumerable<ThreadStressLogData> GetThreadStressLogs(TargetPointer Logs) => traversal.GetThreadStressLogs(Logs);
public IEnumerable<StressMsgData> GetStressMessages(ThreadStressLogData threadLog) => traversal.GetStressMessages(threadLog);
public IEnumerable<StressMsgData> GetStressMessages(TargetPointer threadStressLogAddress) => traversal.GetStressMessages(threadStressLogAddress);
public bool IsPointerInStressLog(StressLogData stressLog, TargetPointer pointer) => traversal.IsPointerInStressLog(stressLog, pointer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7320,23 +7320,8 @@ int ISOSDacInterface17.GetStressLogMessageEnumerator(
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);
IEnumerable<Contracts.StressMsgData> messages = stressLogContract.GetStressMessages(address);
ppEnum.Interface = new SOSStressLogMsgEnum(_target, messages);
}
catch (System.Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void CanEnumerateThreadsAndMessages(TestConfiguration config)
bool foundMessages = false;
foreach (ThreadStressLogData thread in threads)
{
var messages = stressLog.GetStressMessages(thread).Take(10).ToList();
var messages = stressLog.GetStressMessages(thread.Address).Take(10).ToList();
if (messages.Count > 0)
{
foundMessages = true;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/StressLogAnalyzer/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ private static ContractDescriptorParser.ContractDescriptor GetDescriptor(string
"StressLogModuleTable": [[ 1 ], "pointer" ],
},
"contracts": {
"StressLog": 2,
"StressLog": "c2",
}
}
""""u8)!;
Expand Down
4 changes: 2 additions & 2 deletions src/tools/StressLogAnalyzer/src/StressLogAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal sealed class StressLogAnalyzer(
// The "end" timestamp is the timestamp of the most recent message.
timeTracker.SetEndTimestamp(
logs.Select(
log => outerLogContract.GetStressMessages(log).FirstOrDefault().Timestamp)
log => outerLogContract.GetStressMessages(log.Address).FirstOrDefault().Timestamp)
.Max());

if (!threadFilter.HasAnyGCThreadFilter)
Expand All @@ -58,7 +58,7 @@ await Parallel.ForEachAsync(logs, parallelOptions, (log, ct) =>
StressMsgData? earliestMessage = null;
List<StressMsgData> localMessages = [];
bool includeThreadMessages = true;
foreach (StressMsgData message in stressLogContract.Value!.GetStressMessages(log))
foreach (StressMsgData message in stressLogContract.Value!.GetStressMessages(log.Address))
{
numMessagesProcessed.Value++;
token.ThrowIfCancellationRequested();
Expand Down