blob: 65f37375c33c34ba48b6414e0985300246d8b6fa (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include "common.h"
#include "genanalysis.h"
#include "eventpipeadapter.h"
GcGenAnalysisState gcGenAnalysisState = GcGenAnalysisState::Uninitialized;
EventPipeSession* gcGenAnalysisEventPipeSession = nullptr;
uint64_t gcGenAnalysisEventPipeSessionId = (uint64_t)-1;
GcGenAnalysisState gcGenAnalysisConfigured = GcGenAnalysisState::Uninitialized;
int64_t gcGenAnalysisGen = -1;
int64_t gcGenAnalysisBytes = 0;
int64_t gcGenAnalysisIndex = 0;
uint32_t gcGenAnalysisBufferMB = 0;
bool gcGenAnalysisTrace = true;
bool gcGenAnalysisDump = false;
/* static */ void GenAnalysis::Initialize()
{
#ifndef GEN_ANALYSIS_STRESS
if (gcGenAnalysisConfigured == GcGenAnalysisState::Uninitialized)
{
bool match = true;
CLRConfigStringHolder gcGenAnalysisCmd(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisCmd));
if (gcGenAnalysisCmd != nullptr)
{
// Get the managed command line.
LPCWSTR pCmdLine = GetCommandLineForDiagnostics();
match = wcsncmp(pCmdLine, gcGenAnalysisCmd, wcslen(gcGenAnalysisCmd)) == 0;
}
if (match && !CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisGen")))
{
match = false;
}
if (match && !CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisBytes")))
{
match = false;
}
if (match)
{
gcGenAnalysisBytes = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisBytes);
gcGenAnalysisGen = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisGen);
gcGenAnalysisIndex = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisIndex);
gcGenAnalysisBufferMB = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeCircularMB);
gcGenAnalysisTrace = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisTrace);
gcGenAnalysisDump = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisDump);
gcGenAnalysisConfigured = GcGenAnalysisState::Enabled;
}
else
{
gcGenAnalysisConfigured = GcGenAnalysisState::Disabled;
}
}
if ((gcGenAnalysisConfigured == GcGenAnalysisState::Enabled) && (gcGenAnalysisState == GcGenAnalysisState::Uninitialized))
#endif
{
if (gcGenAnalysisTrace)
{
EnableGenerationalAwareSession();
}
if (gcGenAnalysisDump)
{
gcGenAnalysisState = GcGenAnalysisState::Enabled;
}
}
}
/* static */ void GenAnalysis::EnableGenerationalAwareSession()
{
LPCWSTR outputPath = nullptr;
outputPath = GENAWARE_TRACE_FILE_NAME;
NewArrayHolder<COR_PRF_EVENTPIPE_PROVIDER_CONFIG> pProviders;
int providerCnt = 1;
pProviders = new COR_PRF_EVENTPIPE_PROVIDER_CONFIG[providerCnt];
const uint64_t GCHeapAndTypeNamesKeyword = 0x00001000000; // This keyword is necessary for the type names
const uint64_t GCHeapSurvivalAndMovementKeyword = 0x00000400000; // This keyword is necessary for the generation range data.
const uint64_t GCHeapDumpKeyword = 0x00000100000; // This keyword is necessary for enabling walking the heap
const uint64_t TypeKeyword = 0x00000080000; // This keyword is necessary for enabling BulkType events
const uint64_t keyword = GCHeapAndTypeNamesKeyword|GCHeapSurvivalAndMovementKeyword|GCHeapDumpKeyword|TypeKeyword;
pProviders[0].providerName = W("Microsoft-Windows-DotNETRuntime");
pProviders[0].keywords = keyword;
pProviders[0].loggingLevel = (uint32_t)EP_EVENT_LEVEL_VERBOSE;
pProviders[0].filterData = nullptr;
EventPipeProviderConfigurationAdapter configAdapter(pProviders, providerCnt);
gcGenAnalysisEventPipeSessionId = EventPipeAdapter::Enable(
outputPath,
gcGenAnalysisBufferMB,
configAdapter,
EP_SESSION_TYPE_FILE,
EP_SERIALIZATION_FORMAT_NETTRACE_V4,
false,
nullptr,
nullptr,
nullptr
);
if (gcGenAnalysisEventPipeSessionId > 0)
{
gcGenAnalysisEventPipeSession= EventPipeAdapter::GetSession(gcGenAnalysisEventPipeSessionId);
EventPipeAdapter::PauseSession(gcGenAnalysisEventPipeSession);
EventPipeAdapter::StartStreaming(gcGenAnalysisEventPipeSessionId);
gcGenAnalysisState = GcGenAnalysisState::Enabled;
}
}
|