xref: /aosp_15_r20/external/cronet/base/win/event_trace_controller.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2009 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker //
5*6777b538SAndroid Build Coastguard Worker // Implementation of a Windows event trace controller class.
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/win/event_trace_controller.h"
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/numerics/checked_math.h"
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker constexpr size_t kDefaultRealtimeBufferSizeKb = 16;
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker namespace base {
15*6777b538SAndroid Build Coastguard Worker namespace win {
16*6777b538SAndroid Build Coastguard Worker 
EtwTraceProperties()17*6777b538SAndroid Build Coastguard Worker EtwTraceProperties::EtwTraceProperties() {
18*6777b538SAndroid Build Coastguard Worker   memset(buffer_, 0, sizeof(buffer_));
19*6777b538SAndroid Build Coastguard Worker   EVENT_TRACE_PROPERTIES* prop = get();
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker   prop->Wnode.BufferSize = sizeof(buffer_);
22*6777b538SAndroid Build Coastguard Worker   prop->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
23*6777b538SAndroid Build Coastguard Worker   prop->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
24*6777b538SAndroid Build Coastguard Worker   prop->LogFileNameOffset =
25*6777b538SAndroid Build Coastguard Worker       sizeof(EVENT_TRACE_PROPERTIES) + sizeof(wchar_t) * kMaxStringLen;
26*6777b538SAndroid Build Coastguard Worker }
27*6777b538SAndroid Build Coastguard Worker 
SetLoggerName(const wchar_t * logger_name)28*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceProperties::SetLoggerName(const wchar_t* logger_name) {
29*6777b538SAndroid Build Coastguard Worker   size_t len = wcslen(logger_name) + 1;
30*6777b538SAndroid Build Coastguard Worker   if (kMaxStringLen < len)
31*6777b538SAndroid Build Coastguard Worker     return E_INVALIDARG;
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker   memcpy(buffer_ + get()->LoggerNameOffset, logger_name, sizeof(wchar_t) * len);
34*6777b538SAndroid Build Coastguard Worker   return S_OK;
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker 
SetLoggerFileName(const wchar_t * logger_file_name)37*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceProperties::SetLoggerFileName(const wchar_t* logger_file_name) {
38*6777b538SAndroid Build Coastguard Worker   size_t len = wcslen(logger_file_name) + 1;
39*6777b538SAndroid Build Coastguard Worker   if (kMaxStringLen < len)
40*6777b538SAndroid Build Coastguard Worker     return E_INVALIDARG;
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker   memcpy(buffer_ + get()->LogFileNameOffset, logger_file_name,
43*6777b538SAndroid Build Coastguard Worker          sizeof(wchar_t) * len);
44*6777b538SAndroid Build Coastguard Worker   return S_OK;
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker EtwTraceController::EtwTraceController() = default;
48*6777b538SAndroid Build Coastguard Worker 
~EtwTraceController()49*6777b538SAndroid Build Coastguard Worker EtwTraceController::~EtwTraceController() {
50*6777b538SAndroid Build Coastguard Worker   if (session_)
51*6777b538SAndroid Build Coastguard Worker     Stop(nullptr);
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker 
Start(const wchar_t * session_name,EtwTraceProperties * prop)54*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Start(const wchar_t* session_name,
55*6777b538SAndroid Build Coastguard Worker                                   EtwTraceProperties* prop) {
56*6777b538SAndroid Build Coastguard Worker   DCHECK(NULL == session_ && session_name_.empty());
57*6777b538SAndroid Build Coastguard Worker   EtwTraceProperties ignore;
58*6777b538SAndroid Build Coastguard Worker   if (prop == nullptr)
59*6777b538SAndroid Build Coastguard Worker     prop = &ignore;
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   HRESULT hr = Start(session_name, prop, &session_);
62*6777b538SAndroid Build Coastguard Worker   if (SUCCEEDED(hr))
63*6777b538SAndroid Build Coastguard Worker     session_name_ = session_name;
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   return hr;
66*6777b538SAndroid Build Coastguard Worker }
67*6777b538SAndroid Build Coastguard Worker 
StartFileSession(const wchar_t * session_name,const wchar_t * logfile_path,bool realtime)68*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::StartFileSession(const wchar_t* session_name,
69*6777b538SAndroid Build Coastguard Worker                                              const wchar_t* logfile_path,
70*6777b538SAndroid Build Coastguard Worker                                              bool realtime) {
71*6777b538SAndroid Build Coastguard Worker   DCHECK(NULL == session_ && session_name_.empty());
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   EtwTraceProperties prop;
74*6777b538SAndroid Build Coastguard Worker   prop.SetLoggerFileName(logfile_path);
75*6777b538SAndroid Build Coastguard Worker   EVENT_TRACE_PROPERTIES& p = *prop.get();
76*6777b538SAndroid Build Coastguard Worker   p.Wnode.ClientContext = 1;                         // QPC timer accuracy.
77*6777b538SAndroid Build Coastguard Worker   p.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;  // Sequential log.
78*6777b538SAndroid Build Coastguard Worker   if (realtime)
79*6777b538SAndroid Build Coastguard Worker     p.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   p.MaximumFileSize = 100;  // 100M file size.
82*6777b538SAndroid Build Coastguard Worker   p.FlushTimer = 30;        // 30 seconds flush lag.
83*6777b538SAndroid Build Coastguard Worker   return Start(session_name, &prop);
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker 
StartRealtimeSession(const wchar_t * session_name,size_t buffer_size)86*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::StartRealtimeSession(const wchar_t* session_name,
87*6777b538SAndroid Build Coastguard Worker                                                  size_t buffer_size) {
88*6777b538SAndroid Build Coastguard Worker   DCHECK(NULL == session_ && session_name_.empty());
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   EtwTraceProperties prop;
91*6777b538SAndroid Build Coastguard Worker   EVENT_TRACE_PROPERTIES& p = *prop.get();
92*6777b538SAndroid Build Coastguard Worker   p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY;
93*6777b538SAndroid Build Coastguard Worker   p.FlushTimer = 1;   // flush every second.
94*6777b538SAndroid Build Coastguard Worker   p.BufferSize = checked_cast<ULONG>(
95*6777b538SAndroid Build Coastguard Worker       buffer_size ? buffer_size : kDefaultRealtimeBufferSizeKb);
96*6777b538SAndroid Build Coastguard Worker   p.LogFileNameOffset = 0;
97*6777b538SAndroid Build Coastguard Worker   return Start(session_name, &prop);
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker 
EnableProvider(REFGUID provider,UCHAR level,ULONG flags)100*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::EnableProvider(REFGUID provider,
101*6777b538SAndroid Build Coastguard Worker                                            UCHAR level,
102*6777b538SAndroid Build Coastguard Worker                                            ULONG flags) {
103*6777b538SAndroid Build Coastguard Worker   ULONG error = ::EnableTrace(TRUE, flags, level, &provider, session_);
104*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(error);
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker 
DisableProvider(REFGUID provider)107*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::DisableProvider(REFGUID provider) {
108*6777b538SAndroid Build Coastguard Worker   ULONG error = ::EnableTrace(FALSE, 0, 0, &provider, session_);
109*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(error);
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker 
Stop(EtwTraceProperties * properties)112*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Stop(EtwTraceProperties* properties) {
113*6777b538SAndroid Build Coastguard Worker   EtwTraceProperties ignore;
114*6777b538SAndroid Build Coastguard Worker   if (properties == nullptr)
115*6777b538SAndroid Build Coastguard Worker     properties = &ignore;
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   ULONG error = ::ControlTrace(session_, nullptr, properties->get(),
118*6777b538SAndroid Build Coastguard Worker                                EVENT_TRACE_CONTROL_STOP);
119*6777b538SAndroid Build Coastguard Worker   if (ERROR_SUCCESS != error)
120*6777b538SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(error);
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   session_ = NULL;
123*6777b538SAndroid Build Coastguard Worker   session_name_.clear();
124*6777b538SAndroid Build Coastguard Worker   return S_OK;
125*6777b538SAndroid Build Coastguard Worker }
126*6777b538SAndroid Build Coastguard Worker 
Flush(EtwTraceProperties * properties)127*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Flush(EtwTraceProperties* properties) {
128*6777b538SAndroid Build Coastguard Worker   EtwTraceProperties ignore;
129*6777b538SAndroid Build Coastguard Worker   if (properties == nullptr)
130*6777b538SAndroid Build Coastguard Worker     properties = &ignore;
131*6777b538SAndroid Build Coastguard Worker 
132*6777b538SAndroid Build Coastguard Worker   ULONG error = ::ControlTrace(session_, nullptr, properties->get(),
133*6777b538SAndroid Build Coastguard Worker                                EVENT_TRACE_CONTROL_FLUSH);
134*6777b538SAndroid Build Coastguard Worker   if (ERROR_SUCCESS != error)
135*6777b538SAndroid Build Coastguard Worker     return HRESULT_FROM_WIN32(error);
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   return S_OK;
138*6777b538SAndroid Build Coastguard Worker }
139*6777b538SAndroid Build Coastguard Worker 
Start(const wchar_t * session_name,EtwTraceProperties * properties,TRACEHANDLE * session_handle)140*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Start(const wchar_t* session_name,
141*6777b538SAndroid Build Coastguard Worker                                   EtwTraceProperties* properties,
142*6777b538SAndroid Build Coastguard Worker                                   TRACEHANDLE* session_handle) {
143*6777b538SAndroid Build Coastguard Worker   DCHECK(properties != nullptr);
144*6777b538SAndroid Build Coastguard Worker   ULONG err = ::StartTrace(session_handle, session_name, properties->get());
145*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(err);
146*6777b538SAndroid Build Coastguard Worker }
147*6777b538SAndroid Build Coastguard Worker 
Query(const wchar_t * session_name,EtwTraceProperties * properties)148*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Query(const wchar_t* session_name,
149*6777b538SAndroid Build Coastguard Worker                                   EtwTraceProperties* properties) {
150*6777b538SAndroid Build Coastguard Worker   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
151*6777b538SAndroid Build Coastguard Worker                              EVENT_TRACE_CONTROL_QUERY);
152*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(err);
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker 
Update(const wchar_t * session_name,EtwTraceProperties * properties)155*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Update(const wchar_t* session_name,
156*6777b538SAndroid Build Coastguard Worker                                    EtwTraceProperties* properties) {
157*6777b538SAndroid Build Coastguard Worker   DCHECK(properties != nullptr);
158*6777b538SAndroid Build Coastguard Worker   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
159*6777b538SAndroid Build Coastguard Worker                              EVENT_TRACE_CONTROL_UPDATE);
160*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(err);
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker 
Stop(const wchar_t * session_name,EtwTraceProperties * properties)163*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Stop(const wchar_t* session_name,
164*6777b538SAndroid Build Coastguard Worker                                  EtwTraceProperties* properties) {
165*6777b538SAndroid Build Coastguard Worker   DCHECK(properties != nullptr);
166*6777b538SAndroid Build Coastguard Worker   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
167*6777b538SAndroid Build Coastguard Worker                              EVENT_TRACE_CONTROL_STOP);
168*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(err);
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker 
Flush(const wchar_t * session_name,EtwTraceProperties * properties)171*6777b538SAndroid Build Coastguard Worker HRESULT EtwTraceController::Flush(const wchar_t* session_name,
172*6777b538SAndroid Build Coastguard Worker                                   EtwTraceProperties* properties) {
173*6777b538SAndroid Build Coastguard Worker   DCHECK(properties != nullptr);
174*6777b538SAndroid Build Coastguard Worker   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
175*6777b538SAndroid Build Coastguard Worker                              EVENT_TRACE_CONTROL_FLUSH);
176*6777b538SAndroid Build Coastguard Worker   return HRESULT_FROM_WIN32(err);
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker }  // namespace win
180*6777b538SAndroid Build Coastguard Worker }  // namespace base
181