Skip to content

Commit 8a94463

Browse files
Copilotbrianrob
andcommitted
Fix last sample dropped in cdbstack and set sample metric
Co-authored-by: brianrob <[email protected]>
1 parent 5f8c844 commit 8a94463

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using Diagnostics.Tracing.StackSources;
2+
using Microsoft.Diagnostics.Tracing.Stacks;
3+
using System.IO;
4+
using Xunit;
5+
6+
namespace PerfViewTests
7+
{
8+
public class DebuggerStackSourceTests
9+
{
10+
[Fact]
11+
public void TestLastSampleIsNotDropped()
12+
{
13+
// Create a sample cdbstack file with two samples
14+
var cdbStackContent = @"Call Site
15+
coreclr!JIT_MonEnterWorker_Portable
16+
System_Windows_ni!MS.Internal.ManagedPeerTable.TryGetManagedPeer(IntPtr, Boolean, System.Object ByRef)
17+
Call Site
18+
kernel32!BaseThreadInitThunk
19+
ntdll!RtlUserThreadStart";
20+
21+
DebuggerStackSource stackSource;
22+
using (var reader = new StringReader(cdbStackContent))
23+
{
24+
stackSource = new DebuggerStackSource(reader);
25+
}
26+
27+
// Count the samples
28+
int sampleCount = 0;
29+
stackSource.ForEach(sample => sampleCount++);
30+
31+
// We should have 2 samples, but the bug causes only 1 to be added
32+
Assert.Equal(2, sampleCount);
33+
}
34+
35+
[Fact]
36+
public void TestSingleSampleIsAdded()
37+
{
38+
// Create a sample cdbstack file with a single sample (no subsequent "Call Site")
39+
var cdbStackContent = @"Call Site
40+
coreclr!JIT_MonEnterWorker_Portable
41+
System_Windows_ni!MS.Internal.ManagedPeerTable.TryGetManagedPeer(IntPtr, Boolean, System.Object ByRef)";
42+
43+
DebuggerStackSource stackSource;
44+
using (var reader = new StringReader(cdbStackContent))
45+
{
46+
stackSource = new DebuggerStackSource(reader);
47+
}
48+
49+
// Count the samples
50+
int sampleCount = 0;
51+
stackSource.ForEach(sample => sampleCount++);
52+
53+
// We should have 1 sample
54+
Assert.Equal(1, sampleCount);
55+
}
56+
57+
[Fact]
58+
public void TestSampleMetricIsSet()
59+
{
60+
// Create a sample cdbstack file with one sample
61+
var cdbStackContent = @"Call Site
62+
coreclr!JIT_MonEnterWorker_Portable
63+
System_Windows_ni!MS.Internal.ManagedPeerTable.TryGetManagedPeer(IntPtr, Boolean, System.Object ByRef)";
64+
65+
DebuggerStackSource stackSource;
66+
using (var reader = new StringReader(cdbStackContent))
67+
{
68+
stackSource = new DebuggerStackSource(reader);
69+
}
70+
71+
// Check that metric is set to 1 for each sample
72+
stackSource.ForEach(sample =>
73+
{
74+
Assert.Equal(1, sample.Metric);
75+
});
76+
}
77+
}
78+
}

src/PerfView/OtherSources/DebuggerStackSource.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ private void Read(TextReader reader)
102102

103103
stack.Clear();
104104

105+
sample.Metric = 1;
105106
sample.StackIndex = parent;
106107
sample.TimeRelativeMSec = time;
107108
time++;
@@ -112,6 +113,25 @@ private void Read(TextReader reader)
112113
}
113114
}
114115
}
116+
117+
// Handle the last sample if there are any remaining frames
118+
if (stack.Count != 0)
119+
{
120+
StackSourceCallStackIndex parent = StackSourceCallStackIndex.Invalid;
121+
for (int i = stack.Count - 1; i >= 0; --i)
122+
{
123+
parent = Interner.CallStackIntern(stack[i].frame, parent);
124+
}
125+
126+
stack.Clear();
127+
128+
sample.Metric = 1;
129+
sample.StackIndex = parent;
130+
sample.TimeRelativeMSec = time;
131+
time++;
132+
AddSample(sample);
133+
}
134+
115135
Interner.DoneInterning();
116136
}
117137
#endregion

0 commit comments

Comments
 (0)