OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/logging/win/file_logger.h" | 5 #include "chrome/test/logging/win/file_logger.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <guiddef.h> | 8 #include <guiddef.h> |
9 #include <objbase.h> | 9 #include <objbase.h> |
10 | 10 |
11 #include <ios> | 11 #include <ios> |
12 | 12 |
13 #include "base/debug/trace_event_win.h" | 13 #include "base/debug/trace_event_win.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/file_path.h" | 15 #include "base/file_path.h" |
16 #include "base/logging_win.h" | 16 #include "base/logging_win.h" |
17 #include "base/string16.h" | 17 #include "base/string16.h" |
18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
19 #include "base/win/event_trace_consumer.h" | 19 #include "base/win/event_trace_consumer.h" |
20 #include "base/win/registry.h" | 20 #include "base/win/registry.h" |
21 #include "chrome/common/env_vars.h" | |
22 | 21 |
23 namespace logging_win { | 22 namespace logging_win { |
24 | 23 |
25 namespace { | 24 namespace { |
26 | 25 |
27 const wchar_t kChromeTestSession[] = L"chrome_tests"; | 26 const wchar_t kChromeTestSession[] = L"chrome_tests"; |
28 | 27 |
29 // From chrome_tab.cc: {0562BFC3-2550-45b4-BD8E-A310583D3A6F} | 28 // From chrome_tab.cc: {0562BFC3-2550-45b4-BD8E-A310583D3A6F} |
30 const GUID kChromeFrameProvider = | 29 const GUID kChromeFrameProvider = |
31 { 0x562bfc3, 0x2550, 0x45b4, | 30 { 0x562bfc3, 0x2550, 0x45b4, |
(...skipping 19 matching lines...) Expand all Loading... |
51 { &kChromeTraceProviderName, 255, 0 }, | 50 { &kChromeTraceProviderName, 255, 0 }, |
52 { &kChromeFrameProvider, 255, 0 }, | 51 { &kChromeFrameProvider, 255, 0 }, |
53 { &kChromeTestsProvider, 255, 0 }, | 52 { &kChromeTestsProvider, 255, 0 }, |
54 { &base::debug::kChromeTraceProviderName, 255, 0 } | 53 { &base::debug::kChromeTraceProviderName, 255, 0 } |
55 }; | 54 }; |
56 | 55 |
57 COMPILE_ASSERT((1 << arraysize(kProviders)) - 1 == | 56 COMPILE_ASSERT((1 << arraysize(kProviders)) - 1 == |
58 FileLogger::kAllEventProviders, | 57 FileLogger::kAllEventProviders, |
59 size_of_kProviders_is_inconsistent_with_kAllEventProviders); | 58 size_of_kProviders_is_inconsistent_with_kAllEventProviders); |
60 | 59 |
61 // The provider bits that require CHROME_ETW_LOGGING in the environment. | |
62 const uint32 kChromeLogProviders = | |
63 FileLogger::CHROME_LOG_PROVIDER | FileLogger::CHROME_FRAME_LOG_PROVIDER; | |
64 const HKEY kEnvironmentRoot = HKEY_LOCAL_MACHINE; | |
65 const wchar_t kEnvironmentKey[] = | |
66 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"; | |
67 const wchar_t kEnvironment[] = L"Environment"; | |
68 const unsigned int kBroadcastTimeoutMilliseconds = 2 * 1000; | |
69 | |
70 } // namespace | 60 } // namespace |
71 | 61 |
72 // FileLogger::ScopedSystemEnvironmentVariable implementation. | |
73 | |
74 FileLogger::ScopedSystemEnvironmentVariable::ScopedSystemEnvironmentVariable( | |
75 const string16& variable, | |
76 const string16& value) { | |
77 | |
78 // Set the value in this process and its children. | |
79 ::SetEnvironmentVariable(variable.c_str(), value.c_str()); | |
80 | |
81 // Set the value for the whole system and ask everyone to refresh. | |
82 base::win::RegKey environment; | |
83 LONG result = environment.Open(kEnvironmentRoot, kEnvironmentKey, | |
84 KEY_QUERY_VALUE | KEY_SET_VALUE); | |
85 if (result == ERROR_SUCCESS) { | |
86 string16 old_value; | |
87 // The actual value of the variable is insignificant in the eyes of Chrome. | |
88 if (environment.ReadValue(variable.c_str(), | |
89 &old_value) != ERROR_SUCCESS && | |
90 environment.WriteValue(variable.c_str(), | |
91 value.c_str()) == ERROR_SUCCESS) { | |
92 environment.Close(); | |
93 // Remember that this needs to be reversed in the dtor. | |
94 variable_ = variable; | |
95 NotifyOtherProcesses(); | |
96 } | |
97 } else { | |
98 SetLastError(result); | |
99 PLOG(ERROR) << "Failed to open HKLM to check/modify the system environment"; | |
100 } | |
101 } | |
102 | |
103 FileLogger::ScopedSystemEnvironmentVariable::~ScopedSystemEnvironmentVariable() | |
104 { | |
105 if (!variable_.empty()) { | |
106 base::win::RegKey environment; | |
107 if (environment.Open(kEnvironmentRoot, kEnvironmentKey, | |
108 KEY_SET_VALUE) == ERROR_SUCCESS) { | |
109 environment.DeleteValue(variable_.c_str()); | |
110 environment.Close(); | |
111 NotifyOtherProcesses(); | |
112 } | |
113 } | |
114 } | |
115 | |
116 // static | |
117 void FileLogger::ScopedSystemEnvironmentVariable::NotifyOtherProcesses() { | |
118 // Announce to the system that a change has been made so that the shell and | |
119 // other Windowsy bits pick it up; see | |
120 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682653.aspx. | |
121 SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, | |
122 reinterpret_cast<LPARAM>(kEnvironment), SMTO_ABORTIFHUNG, | |
123 kBroadcastTimeoutMilliseconds, NULL); | |
124 } | |
125 | |
126 bool FileLogger::is_initialized_ = false; | 62 bool FileLogger::is_initialized_ = false; |
127 | 63 |
128 FileLogger::FileLogger() | 64 FileLogger::FileLogger() |
129 : event_provider_mask_() { | 65 : event_provider_mask_() { |
130 } | 66 } |
131 | 67 |
132 FileLogger::~FileLogger() { | 68 FileLogger::~FileLogger() { |
133 if (is_logging()) { | 69 if (is_logging()) { |
134 LOG(ERROR) | 70 LOG(ERROR) |
135 << __FUNCTION__ << " don't forget to call FileLogger::StopLogging()"; | 71 << __FUNCTION__ << " don't forget to call FileLogger::StopLogging()"; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 logging::LogEventProvider::Uninitialize(); | 126 logging::LogEventProvider::Uninitialize(); |
191 } | 127 } |
192 | 128 |
193 void FileLogger::Initialize() { | 129 void FileLogger::Initialize() { |
194 Initialize(kAllEventProviders); | 130 Initialize(kAllEventProviders); |
195 } | 131 } |
196 | 132 |
197 void FileLogger::Initialize(uint32 event_provider_mask) { | 133 void FileLogger::Initialize(uint32 event_provider_mask) { |
198 CHECK(!is_initialized_); | 134 CHECK(!is_initialized_); |
199 | 135 |
200 // Set up CHROME_ETW_LOGGING in the environment if providers that require it | |
201 // are enabled. | |
202 if (event_provider_mask & kChromeLogProviders) { | |
203 etw_logging_configurator_.reset(new ScopedSystemEnvironmentVariable( | |
204 ASCIIToWide(env_vars::kEtwLogging), L"1")); | |
205 } | |
206 | |
207 // Stop a previous session that wasn't shut down properly. | 136 // Stop a previous session that wasn't shut down properly. |
208 base::win::EtwTraceProperties ignore; | 137 base::win::EtwTraceProperties ignore; |
209 HRESULT hr = base::win::EtwTraceController::Stop(kChromeTestSession, | 138 HRESULT hr = base::win::EtwTraceController::Stop(kChromeTestSession, |
210 &ignore); | 139 &ignore); |
211 LOG_IF(ERROR, FAILED(hr) && | 140 LOG_IF(ERROR, FAILED(hr) && |
212 hr != HRESULT_FROM_WIN32(ERROR_WMI_INSTANCE_NOT_FOUND)) | 141 hr != HRESULT_FROM_WIN32(ERROR_WMI_INSTANCE_NOT_FOUND)) |
213 << "Failed to stop a previous trace session; hr=" << std::hex << hr; | 142 << "Failed to stop a previous trace session; hr=" << std::hex << hr; |
214 | 143 |
215 event_provider_mask_ = event_provider_mask; | 144 event_provider_mask_ = event_provider_mask; |
216 | 145 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 178 |
250 hr = controller_.Flush(NULL); | 179 hr = controller_.Flush(NULL); |
251 LOG_IF(ERROR, FAILED(hr)) | 180 LOG_IF(ERROR, FAILED(hr)) |
252 << "Failed to flush events; hr=" << std::hex << hr; | 181 << "Failed to flush events; hr=" << std::hex << hr; |
253 hr = controller_.Stop(NULL); | 182 hr = controller_.Stop(NULL); |
254 LOG_IF(ERROR, FAILED(hr)) | 183 LOG_IF(ERROR, FAILED(hr)) |
255 << "Failed to stop ETW session; hr=" << std::hex << hr; | 184 << "Failed to stop ETW session; hr=" << std::hex << hr; |
256 } | 185 } |
257 | 186 |
258 } // namespace logging_win | 187 } // namespace logging_win |
OLD | NEW |