1
+ // Licensed to the .NET Foundation under one or more agreements.
2
+ // The .NET Foundation licenses this file to you under the MIT license.
3
+ // See the LICENSE file in the project root for more information.
4
+
5
+ using System ;
6
+ using System . Diagnostics . Tracing ;
7
+ using System . IO ;
8
+ using System . Linq ;
9
+ using System . Threading ;
10
+ using System . Threading . Tasks ;
11
+ using System . Collections . Generic ;
12
+ using Microsoft . Diagnostics . NETCore . Client ;
13
+ using Microsoft . Diagnostics . Tools . RuntimeClient ;
14
+ using Microsoft . Diagnostics . Tracing ;
15
+ using Microsoft . Diagnostics . Tracing . Parsers ;
16
+ using Tracing . Tests . Common ;
17
+ using Microsoft . Diagnostics . Tracing . Parsers . Clr ;
18
+
19
+ namespace Tracing . Tests . EventSourceError
20
+ {
21
+ // Regression test for https://github.com/dotnet/runtime/issues/38639
22
+ public class GCDumpTest
23
+ {
24
+ private static int _bulkTypeCount = 0 ;
25
+ private static int _bulkNodeCount = 0 ;
26
+ private static int _bulkEdgeCount = 0 ;
27
+ private static int _bulkRootEdgeCount = 0 ;
28
+ private static int _bulkRootStaticVarCount = 0 ;
29
+
30
+ private static readonly ulong GC_HeapDump_Keyword = 0x100000UL ;
31
+
32
+ public static int Main ( string [ ] args )
33
+ {
34
+ // This test validates that if an EventSource generates an error
35
+ // during construction it gets emitted over EventPipe
36
+
37
+ List < Provider > providers = new List < Provider >
38
+ {
39
+ new Provider ( "Microsoft-Windows-DotNETRuntime" , eventLevel : EventLevel . Verbose , keywords : ( ulong ) ClrTraceEventParser . Keywords . GCHeapSnapshot )
40
+ } ;
41
+
42
+ var configuration = new SessionConfiguration ( circularBufferSizeMB : 1024 , format : EventPipeSerializationFormat . NetTrace , providers : providers ) ;
43
+ return IpcTraceTest . RunAndValidateEventCounts ( _expectedEventCounts , _eventGeneratingAction , configuration , _DoesRundownContainMethodEvents ) ;
44
+ }
45
+
46
+ private static Dictionary < string , ExpectedEventCount > _expectedEventCounts = new Dictionary < string , ExpectedEventCount > ( )
47
+ {
48
+ // This space intentionally left blank
49
+ } ;
50
+
51
+ private static Action _eventGeneratingAction = ( ) =>
52
+ {
53
+ // This space intentionally left blank
54
+ } ;
55
+
56
+ private static Func < EventPipeEventSource , Func < int > > _DoesRundownContainMethodEvents = ( source ) =>
57
+ {
58
+ source . Clr . TypeBulkType += ( GCBulkTypeTraceData data ) =>
59
+ {
60
+ _bulkTypeCount += data . Count ;
61
+ } ;
62
+
63
+ source . Clr . GCBulkNode += delegate ( GCBulkNodeTraceData data )
64
+ {
65
+ _bulkNodeCount += data . Count ;
66
+ } ;
67
+
68
+ source . Clr . GCBulkEdge += ( GCBulkEdgeTraceData data ) =>
69
+ {
70
+ _bulkEdgeCount += data . Count ;
71
+ } ;
72
+
73
+ source . Clr . GCBulkRootEdge += ( GCBulkRootEdgeTraceData data ) =>
74
+ {
75
+ _bulkRootEdgeCount += data . Count ;
76
+ } ;
77
+
78
+ source . Clr . GCBulkRootStaticVar += ( GCBulkRootStaticVarTraceData data ) =>
79
+ {
80
+ _bulkRootStaticVarCount += data . Count ;
81
+ } ;
82
+
83
+ return ( ) =>
84
+ {
85
+ // These values are ~80% (rounded to nice whole numbers) of the values
86
+ // I saw when writing the test. The idea is that I want to catch
87
+ // any real deviation in the number of types, but don't want to have
88
+ // to maintain this test as the number of types varies. (And they will vary due to
89
+ // framework code changes). If this test needs any sort of ongoing maintenance
90
+ // just change all these values to a low number like 10 and move on.
91
+ if ( _bulkTypeCount > 125
92
+ && _bulkNodeCount > 600
93
+ && _bulkEdgeCount > 850
94
+ && _bulkRootEdgeCount > 250
95
+ && _bulkRootStaticVarCount > 70 )
96
+ {
97
+ return 100 ;
98
+ }
99
+
100
+
101
+ Console . WriteLine ( $ "Test failed due to missing GC heap events.") ;
102
+ Console . WriteLine ( $ "_bulkTypeCount = { _bulkTypeCount } ") ;
103
+ Console . WriteLine ( $ "_bulkNodeCount = { _bulkNodeCount } ") ;
104
+ Console . WriteLine ( $ "_bulkEdgeCount = { _bulkEdgeCount } ") ;
105
+ Console . WriteLine ( $ "_bulkRootEdgeCount = { _bulkRootEdgeCount } ") ;
106
+ Console . WriteLine ( $ "_bulkRootStaticVarCount = { _bulkRootStaticVarCount } ") ;
107
+ return - 1 ;
108
+ } ;
109
+ } ;
110
+ }
111
+ }
0 commit comments