1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/logging_win.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,139 @@ 1.4 +// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/logging_win.h" 1.9 +#include "base/memory/singleton.h" 1.10 +#include <initguid.h> // NOLINT 1.11 + 1.12 +namespace logging { 1.13 + 1.14 +using base::win::EtwEventLevel; 1.15 +using base::win::EtwMofEvent; 1.16 + 1.17 +DEFINE_GUID(kLogEventId, 1.18 + 0x7fe69228, 0x633e, 0x4f06, 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7); 1.19 + 1.20 +LogEventProvider::LogEventProvider() : old_log_level_(LOG_NONE) { 1.21 +} 1.22 + 1.23 +LogEventProvider* LogEventProvider::GetInstance() { 1.24 + return Singleton<LogEventProvider, 1.25 + StaticMemorySingletonTraits<LogEventProvider> >::get(); 1.26 +} 1.27 + 1.28 +bool LogEventProvider::LogMessage(logging::LogSeverity severity, 1.29 + const char* file, int line, size_t message_start, 1.30 + const std::string& message) { 1.31 + EtwEventLevel level = TRACE_LEVEL_NONE; 1.32 + 1.33 + // Convert the log severity to the most appropriate ETW trace level. 1.34 + if (severity >= 0) { 1.35 + switch (severity) { 1.36 + case LOG_INFO: 1.37 + level = TRACE_LEVEL_INFORMATION; 1.38 + break; 1.39 + case LOG_WARNING: 1.40 + level = TRACE_LEVEL_WARNING; 1.41 + break; 1.42 + case LOG_ERROR: 1.43 + case LOG_ERROR_REPORT: 1.44 + level = TRACE_LEVEL_ERROR; 1.45 + break; 1.46 + case LOG_FATAL: 1.47 + level = TRACE_LEVEL_FATAL; 1.48 + break; 1.49 + } 1.50 + } else { // severity < 0 is VLOG verbosity levels. 1.51 + level = TRACE_LEVEL_INFORMATION - severity; 1.52 + } 1.53 + 1.54 + // Bail if we're not logging, not at that level, 1.55 + // or if we're post-atexit handling. 1.56 + LogEventProvider* provider = LogEventProvider::GetInstance(); 1.57 + if (provider == NULL || level > provider->enable_level()) 1.58 + return false; 1.59 + 1.60 + // And now log the event. 1.61 + if (provider->enable_flags() & ENABLE_LOG_MESSAGE_ONLY) { 1.62 + EtwMofEvent<1> event(kLogEventId, LOG_MESSAGE, level); 1.63 + event.SetField(0, message.length() + 1 - message_start, 1.64 + message.c_str() + message_start); 1.65 + 1.66 + provider->Log(event.get()); 1.67 + } else { 1.68 + const size_t kMaxBacktraceDepth = 32; 1.69 + void* backtrace[kMaxBacktraceDepth]; 1.70 + DWORD depth = 0; 1.71 + 1.72 + // Capture a stack trace if one is requested. 1.73 + // requested per our enable flags. 1.74 + if (provider->enable_flags() & ENABLE_STACK_TRACE_CAPTURE) 1.75 + depth = CaptureStackBackTrace(2, kMaxBacktraceDepth, backtrace, NULL); 1.76 + 1.77 + EtwMofEvent<5> event(kLogEventId, LOG_MESSAGE_FULL, level); 1.78 + if (file == NULL) 1.79 + file = ""; 1.80 + 1.81 + // Add the stack trace. 1.82 + event.SetField(0, sizeof(depth), &depth); 1.83 + event.SetField(1, sizeof(backtrace[0]) * depth, &backtrace); 1.84 + // The line. 1.85 + event.SetField(2, sizeof(line), &line); 1.86 + // The file. 1.87 + event.SetField(3, strlen(file) + 1, file); 1.88 + // And finally the message. 1.89 + event.SetField(4, message.length() + 1 - message_start, 1.90 + message.c_str() + message_start); 1.91 + 1.92 + provider->Log(event.get()); 1.93 + } 1.94 + 1.95 + // Don't increase verbosity in other log destinations. 1.96 + if (severity < provider->old_log_level_) 1.97 + return true; 1.98 + 1.99 + return false; 1.100 +} 1.101 + 1.102 +void LogEventProvider::Initialize(const GUID& provider_name) { 1.103 + LogEventProvider* provider = LogEventProvider::GetInstance(); 1.104 + 1.105 + provider->set_provider_name(provider_name); 1.106 + provider->Register(); 1.107 + 1.108 + // Register our message handler with logging. 1.109 + SetLogMessageHandler(LogMessage); 1.110 +} 1.111 + 1.112 +void LogEventProvider::Uninitialize() { 1.113 + LogEventProvider::GetInstance()->Unregister(); 1.114 +} 1.115 + 1.116 +void LogEventProvider::OnEventsEnabled() { 1.117 + // Grab the old log level so we can restore it later. 1.118 + old_log_level_ = GetMinLogLevel(); 1.119 + 1.120 + // Convert the new trace level to a logging severity 1.121 + // and enable logging at that level. 1.122 + EtwEventLevel level = enable_level(); 1.123 + if (level == TRACE_LEVEL_NONE || level == TRACE_LEVEL_FATAL) { 1.124 + SetMinLogLevel(LOG_FATAL); 1.125 + } else if (level == TRACE_LEVEL_ERROR) { 1.126 + SetMinLogLevel(LOG_ERROR); 1.127 + } else if (level == TRACE_LEVEL_WARNING) { 1.128 + SetMinLogLevel(LOG_WARNING); 1.129 + } else if (level == TRACE_LEVEL_INFORMATION) { 1.130 + SetMinLogLevel(LOG_INFO); 1.131 + } else if (level >= TRACE_LEVEL_VERBOSE) { 1.132 + // Above INFO, we enable verbose levels with negative severities. 1.133 + SetMinLogLevel(TRACE_LEVEL_INFORMATION - level); 1.134 + } 1.135 +} 1.136 + 1.137 +void LogEventProvider::OnEventsDisabled() { 1.138 + // Restore the old log level. 1.139 + SetMinLogLevel(old_log_level_); 1.140 +} 1.141 + 1.142 +} // namespace logging