Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3210)

Unified Diff: base/debug/trace_event_win.cc

Issue 23934003: Have all trace points emit to ETW. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/debug/trace_event_win.h ('k') | base/win/event_trace_provider.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/trace_event_win.cc
diff --git a/base/debug/trace_event_win.cc b/base/debug/trace_event_win.cc
index 686ade344c889a25c4d52df1ae61dcf969b7bde3..5dd094cd0f09a82b993f03ef3568ec52298c85a4 100644
--- a/base/debug/trace_event_win.cc
+++ b/base/debug/trace_event_win.cc
@@ -7,6 +7,136 @@
#include "base/memory/singleton.h"
#include <initguid.h> // NOLINT
+namespace {
+// Returns the ETW event type ("opcode") associated with an event. The ETW
+// event type depends on:
+// - |internal_type|: Internal type of the event.
+// - |num_args|: Number of arguments included with the event.
+// - |with_stack|: Presence of a stack trace with the event.
+// The bits in the returned event type mean:
+// - 0-3 LSB: Number of arguments associated with the event.
+// - 4: Indicates whether a stack trace is included with the event.
+// - 5-8 MSB: Code associated with an internal event type.
+base::win::EtwEventType GetEtwEventType(char internal_type,
+ int num_args,
+ bool with_stack) {
+ const base::win::EtwEventType kEtwBeginType = 1;
+ const base::win::EtwEventType kEtwEndType = 2;
+ const base::win::EtwEventType kEtwCompleteType = 3;
+ const base::win::EtwEventType kEtwInstantType = 4;
+ const base::win::EtwEventType kEtwAsyncBeginType = 5;
+ const base::win::EtwEventType kEtwAsyncStepIntoType = 6;
+ const base::win::EtwEventType kEtwAsyncStepPastType = 7;
+ const base::win::EtwEventType kEtwAsyncEndType = 8;
+ const base::win::EtwEventType kEtwFlowBeginType = 9;
+ const base::win::EtwEventType kEtwFlowStepType = 10;
+ const base::win::EtwEventType kEtwFlowEndType = 11;
+ const base::win::EtwEventType kEtwMetadataType = 12;
+ const base::win::EtwEventType kEtwCounterType = 13;
+ const base::win::EtwEventType kEtwSampleType = 14;
+ const base::win::EtwEventType kEtwCreateObjectType = 15;
+ const base::win::EtwEventType kEtwSnapshotObjectType = 16;
+ const base::win::EtwEventType kEtwDeleteObjectType = 17;
+
+ const base::win::EtwEventType kEtwInternalTypeShiftLeft = 3;
+ const base::win::EtwEventType kEtwStackMask = 0x04;
+ const base::win::EtwEventType kEtwNumArgsMask = 0x03;
+
+ // This type is used by third party libraries. It's defined here so that
+ // events from these libraries can be handled correctly.
+ const char kTraceEventPhaseInstantOld = 'I';
+
+ base::win::EtwEventType etw_type;
+ switch (internal_type) {
+ case TRACE_EVENT_PHASE_BEGIN:
+ etw_type = kEtwBeginType;
+ break;
+
+ case TRACE_EVENT_PHASE_END:
+ etw_type = kEtwEndType;
+ break;
+
+ case TRACE_EVENT_PHASE_COMPLETE:
+ etw_type = kEtwCompleteType;
+ break;
+
+ case TRACE_EVENT_PHASE_INSTANT:
+ case kTraceEventPhaseInstantOld:
+ etw_type = kEtwInstantType;
+ break;
+
+ case TRACE_EVENT_PHASE_ASYNC_BEGIN:
+ etw_type = kEtwAsyncBeginType;
+ break;
+
+ case TRACE_EVENT_PHASE_ASYNC_STEP_INTO:
+ etw_type = kEtwAsyncStepIntoType;
+ break;
+
+ case TRACE_EVENT_PHASE_ASYNC_STEP_PAST:
+ etw_type = kEtwAsyncStepPastType;
+ break;
+ case TRACE_EVENT_PHASE_ASYNC_END:
+ etw_type = kEtwAsyncEndType;
+ break;
+
+ case TRACE_EVENT_PHASE_FLOW_BEGIN:
+ etw_type = kEtwFlowBeginType;
+ break;
+
+ case TRACE_EVENT_PHASE_FLOW_STEP:
+ etw_type = kEtwFlowStepType;
+ break;
+
+ case TRACE_EVENT_PHASE_FLOW_END:
+ etw_type = kEtwFlowEndType;
+ break;
+
+ case TRACE_EVENT_PHASE_METADATA:
+ etw_type = kEtwMetadataType;
+ break;
+
+ case TRACE_EVENT_PHASE_COUNTER:
+ etw_type = kEtwCounterType;
+ break;
+
+ case TRACE_EVENT_PHASE_SAMPLE:
+ etw_type = kEtwSampleType;
+ break;
+
+ case TRACE_EVENT_PHASE_CREATE_OBJECT:
+ etw_type = kEtwCreateObjectType;
+ break;
+
+ case TRACE_EVENT_PHASE_SNAPSHOT_OBJECT:
+ etw_type = kEtwSnapshotObjectType;
+ break;
+
+ case TRACE_EVENT_PHASE_DELETE_OBJECT:
+ etw_type = kEtwAsyncEndType;
+ break;
+
+ default:
+ NOTREACHED() << "Unknown event type";
+ etw_type = kEtwInstantType;
+ break;
+ }
+
+ etw_type = etw_type << kEtwInternalTypeShiftLeft;
+ DCHECK(num_args <= kEtwNumArgsMask);
+ etw_type += static_cast<base::win::EtwEventType>(num_args) & kEtwNumArgsMask;
+ if (with_stack)
+ etw_type |= kEtwStackMask;
+
+ return etw_type;
+}
+
+// Maximum number of MOF fields for traced events.
+// See the comment above the declaration of
+// TraceEventETWProvider::TraceEventWithArgs() for the list of fields.
+const int kTraceNumFields = 5 + 2 * base::debug::kTraceMaxNumArgs;
+} // namespace
+
namespace base {
namespace debug {
@@ -21,10 +151,9 @@ const GUID kChromeTraceProviderName = {
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};
-
+// {d2d578d9-2936-45b6-a09f-30e32715f41d}
+const GUID kTraceEventClass = {
+ 0xd2d578d9, 0x2936, 0x45b6, 0xa0, 0x9f, 0x30, 0xe3, 0x27, 0x15, 0xf4, 0x1d};
TraceEventETWProvider::TraceEventETWProvider() :
EtwTraceProvider(kChromeTraceProviderName) {
@@ -97,6 +226,87 @@ void TraceEventETWProvider::TraceEvent(const char* name,
Log(event.get());
}
+void TraceEventETWProvider::TraceEventWithArgs(
+ const char* category_group,
+ const char* name,
+ char type,
+ unsigned long long id,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ const scoped_refptr<ConvertableToTraceFormat>* convertable_values) {
+ // Make sure we don't touch NULL.
+ if (name == NULL)
+ name = "";
+ if (category_group == NULL)
+ category_group = "";
+
+ EtwMofEvent<kTraceNumFields> event(kTraceEventClass,
+ TRACE_LEVEL_INFORMATION);
+
+ int field_index = 0;
+ event.SetField(field_index++, strlen(name) + 1, name);
+ event.SetField(field_index++, sizeof(id), &id);
+ event.SetField(field_index++, strlen(category_group) + 1, category_group);
+
+ // Real number of arguments for the event. Might end up being less than
+ // |num_args| when some arguments types are deactivated by flags.
+ unsigned int real_num_args = 0;
+
+ // Traced arguments values converted to strings.
+ std::string arg_str_values[kTraceMaxNumArgs];
+
+ if (enable_flags() & CAPTURE_SIMPLE_ARGUMENTS ||
+ enable_flags() & CAPTURE_ALL_ARGUMENTS) {
+ if (num_args > kTraceMaxNumArgs) {
+ NOTREACHED() << "Maximum number of custom fields exceeded in ETW event. "
+ "Extra custom fields will be ignored.";
+ num_args = kTraceMaxNumArgs;
+ }
+
+ for (int i = 0; i < num_args; ++i) {
+ if (arg_types[i] != TRACE_VALUE_TYPE_CONVERTABLE) {
+ base::debug::TraceEvent::TraceValue value;
+ value.as_uint = arg_values[i];
+ base::debug::TraceEvent::AppendValueAsJSON(arg_types[i],
+ value,
+ &arg_str_values[i]);
+ } else if (enable_flags() & CAPTURE_ALL_ARGUMENTS) {
+ convertable_values[i]->AppendAsTraceFormat(&arg_str_values[i]);
+ } else {
+ continue;
+ }
+
+ ++real_num_args;
+ event.SetField(field_index++, strlen(arg_names[i]) + 1, arg_names[i]);
+ event.SetField(field_index++,
+ arg_str_values[i].size() + 1,
+ arg_str_values[i].c_str());
+ }
+ }
+ bool capture_stack_trace = enable_flags() & CAPTURE_STACK_TRACE;
+ event.SetType(GetEtwEventType(type, real_num_args, capture_stack_trace));
+
+ // See whether we're to capture a backtrace.
+ DWORD depth;
+ void* backtrace[32];
+ if (capture_stack_trace) {
+ DWORD hash = 0;
+ depth = CaptureStackBackTrace(0,
+ arraysize(backtrace),
+ backtrace,
+ NULL);
+ event.SetField(field_index++, sizeof(depth), &depth);
+ event.SetField(field_index++, sizeof(backtrace[0]) * depth, backtrace);
+ }
+ DCHECK(field_index <= kTraceNumFields)
+ << "Maxium number of fields exceeded in ETW event.";
+
+ // Trace the event.
+ Log(event.get());
+}
+
void TraceEventETWProvider::Trace(const char* name,
size_t name_len,
char type,
@@ -115,6 +325,24 @@ void TraceEventETWProvider::Trace(const char* name,
}
}
+void TraceEventETWProvider::TraceWithArgs(
+ const char* category_group,
+ const char* name,
+ char type,
+ unsigned long long id,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values,
+ const scoped_refptr<ConvertableToTraceFormat>* convertable_values) {
+ TraceEventETWProvider* provider = TraceEventETWProvider::GetInstance();
+ if (provider && provider->IsTracing()) {
+ provider->TraceEventWithArgs(category_group, name, type, id,
+ num_args, arg_names, arg_types, arg_values,
+ convertable_values);
+ }
+}
+
void TraceEventETWProvider::Resurrect() {
StaticMemorySingletonTraits<TraceEventETWProvider>::Resurrect();
}
« no previous file with comments | « base/debug/trace_event_win.h ('k') | base/win/event_trace_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698