|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/trace_event/trace_event_win.h" | 
|  |  | 
|  | #include "base/logging.h" | 
|  | #include "base/memory/singleton.h" | 
|  | #include <initguid.h>  // NOLINT | 
|  |  | 
|  | namespace base { | 
|  | namespace trace_event { | 
|  |  | 
|  | using base::win::EtwEventType; | 
|  | using base::win::EtwMofEvent; | 
|  |  | 
|  | // {3DADA31D-19EF-4dc1-B345-037927193422} | 
|  | const GUID kChromeTraceProviderName = { | 
|  | 0x3dada31d, | 
|  | 0x19ef, | 
|  | 0x4dc1, | 
|  | {0xb3, 0x45, 0x3, 0x79, 0x27, 0x19, 0x34, 0x22}}; | 
|  |  | 
|  | // {B967AE67-BB22-49d7-9406-55D91EE1D560} | 
|  | const GUID kTraceEventClass32 = { | 
|  | 0xb967ae67, | 
|  | 0xbb22, | 
|  | 0x49d7, | 
|  | {0x94, 0x6, 0x55, 0xd9, 0x1e, 0xe1, 0xd5, 0x60}}; | 
|  |  | 
|  | // {97BE602D-2930-4ac3-8046-B6763B631DFE} | 
|  | const GUID kTraceEventClass64 = { | 
|  | 0x97be602d, | 
|  | 0x2930, | 
|  | 0x4ac3, | 
|  | {0x80, 0x46, 0xb6, 0x76, 0x3b, 0x63, 0x1d, 0xfe}}; | 
|  |  | 
|  | TraceEventETWProvider::TraceEventETWProvider() : | 
|  | EtwTraceProvider(kChromeTraceProviderName) { | 
|  | Register(); | 
|  | } | 
|  |  | 
|  | TraceEventETWProvider* TraceEventETWProvider::GetInstance() { | 
|  | return Singleton<TraceEventETWProvider, | 
|  | StaticMemorySingletonTraits<TraceEventETWProvider> >::get(); | 
|  | } | 
|  |  | 
|  | bool TraceEventETWProvider::StartTracing() { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | void TraceEventETWProvider::TraceEvent(const char* name, | 
|  | size_t name_len, | 
|  | char type, | 
|  | const void* id, | 
|  | const char* extra, | 
|  | size_t extra_len) { | 
|  | // Make sure we don't touch NULL. | 
|  | if (name == NULL) | 
|  | name = ""; | 
|  | if (extra == NULL) | 
|  | extra = ""; | 
|  |  | 
|  | EtwEventType etw_type = 0; | 
|  | switch (type) { | 
|  | case TRACE_EVENT_PHASE_BEGIN: | 
|  | etw_type = kTraceEventTypeBegin; | 
|  | break; | 
|  | case TRACE_EVENT_PHASE_END: | 
|  | etw_type = kTraceEventTypeEnd; | 
|  | break; | 
|  |  | 
|  | case TRACE_EVENT_PHASE_INSTANT: | 
|  | etw_type = kTraceEventTypeInstant; | 
|  | break; | 
|  |  | 
|  | default: | 
|  | NOTREACHED() << "Unknown event type"; | 
|  | etw_type = kTraceEventTypeInstant; | 
|  | break; | 
|  | } | 
|  |  | 
|  | EtwMofEvent<5> event(kTraceEventClass32, | 
|  | etw_type, | 
|  | TRACE_LEVEL_INFORMATION); | 
|  | event.SetField(0, name_len + 1, name); | 
|  | event.SetField(1, sizeof(id), &id); | 
|  | event.SetField(2, extra_len + 1, extra); | 
|  |  | 
|  | // These variables are declared here so that they are not out of scope when | 
|  | // the event is logged. | 
|  | DWORD depth; | 
|  | void* backtrace[32]; | 
|  |  | 
|  | // See whether we're to capture a backtrace. | 
|  | if (enable_flags() & CAPTURE_STACK_TRACE) { | 
|  | depth = CaptureStackBackTrace(0, | 
|  | arraysize(backtrace), | 
|  | backtrace, | 
|  | NULL); | 
|  | event.SetField(3, sizeof(depth), &depth); | 
|  | event.SetField(4, sizeof(backtrace[0]) * depth, backtrace); | 
|  | } | 
|  |  | 
|  | // Trace the event. | 
|  | Log(event.get()); | 
|  | } | 
|  |  | 
|  | void TraceEventETWProvider::Trace(const char* name, | 
|  | size_t name_len, | 
|  | char type, | 
|  | const void* id, | 
|  | const char* extra, | 
|  | size_t extra_len) { | 
|  | TraceEventETWProvider* provider = TraceEventETWProvider::GetInstance(); | 
|  | if (provider && provider->IsTracing()) { | 
|  | // Compute the name & extra lengths if not supplied already. | 
|  | if (name_len == kUseStrlen) | 
|  | name_len = (name == NULL) ? 0 : strlen(name); | 
|  | if (extra_len == kUseStrlen) | 
|  | extra_len = (extra == NULL) ? 0 : strlen(extra); | 
|  |  | 
|  | provider->TraceEvent(name, name_len, type, id, extra, extra_len); | 
|  | } | 
|  | } | 
|  |  | 
|  | void TraceEventETWProvider::Resurrect() { | 
|  | StaticMemorySingletonTraits<TraceEventETWProvider>::Resurrect(); | 
|  | } | 
|  |  | 
|  | }  // namespace trace_event | 
|  | }  // namespace base |