[ETW] Adds the EtwTokenizer
First part of adding etw trace processor.
This CL adds a new etw_module and adds to the default modules as well as
the tokenization logic itself. There's no path to this code in this CL.
In the upcoming CLs:
- Refactoring sched_event_tracker & thread_state_tracker
- Add Etw Praser to the trace processor
Change-Id: Id6c492112f65bf30593776561613bc1756b40bdf
diff --git a/Android.bp b/Android.bp
index dd2c861..50f69fc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2267,6 +2267,7 @@
":perfetto_src_trace_processor_importers_common_common",
":perfetto_src_trace_processor_importers_common_parser_types",
":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+ ":perfetto_src_trace_processor_importers_etw_full",
":perfetto_src_trace_processor_importers_ftrace_ftrace_descriptors",
":perfetto_src_trace_processor_importers_ftrace_full",
":perfetto_src_trace_processor_importers_ftrace_minimal",
@@ -11040,6 +11041,15 @@
],
}
+// GN: //src/trace_processor/importers/etw:full
+filegroup {
+ name: "perfetto_src_trace_processor_importers_etw_full",
+ srcs: [
+ "src/trace_processor/importers/etw/etw_module.cc",
+ "src/trace_processor/importers/etw/etw_tokenizer.cc",
+ ],
+}
+
// GN: //src/trace_processor/importers/ftrace:ftrace_descriptors
filegroup {
name: "perfetto_src_trace_processor_importers_ftrace_ftrace_descriptors",
@@ -13705,6 +13715,7 @@
":perfetto_src_trace_processor_importers_common_parser_types",
":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
":perfetto_src_trace_processor_importers_common_unittests",
+ ":perfetto_src_trace_processor_importers_etw_full",
":perfetto_src_trace_processor_importers_ftrace_ftrace_descriptors",
":perfetto_src_trace_processor_importers_ftrace_full",
":perfetto_src_trace_processor_importers_ftrace_minimal",
@@ -14417,6 +14428,7 @@
":perfetto_src_trace_processor_importers_common_common",
":perfetto_src_trace_processor_importers_common_parser_types",
":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+ ":perfetto_src_trace_processor_importers_etw_full",
":perfetto_src_trace_processor_importers_ftrace_ftrace_descriptors",
":perfetto_src_trace_processor_importers_ftrace_full",
":perfetto_src_trace_processor_importers_ftrace_minimal",
@@ -14650,6 +14662,7 @@
":perfetto_src_trace_processor_importers_common_common",
":perfetto_src_trace_processor_importers_common_parser_types",
":perfetto_src_trace_processor_importers_common_trace_parser_hdr",
+ ":perfetto_src_trace_processor_importers_etw_full",
":perfetto_src_trace_processor_importers_ftrace_ftrace_descriptors",
":perfetto_src_trace_processor_importers_ftrace_full",
":perfetto_src_trace_processor_importers_ftrace_minimal",
diff --git a/BUILD b/BUILD
index f8f66a2..9f7b69c 100644
--- a/BUILD
+++ b/BUILD
@@ -223,6 +223,7 @@
":src_trace_processor_importers_common_common",
":src_trace_processor_importers_common_parser_types",
":src_trace_processor_importers_common_trace_parser_hdr",
+ ":src_trace_processor_importers_etw_full",
":src_trace_processor_importers_ftrace_ftrace_descriptors",
":src_trace_processor_importers_ftrace_full",
":src_trace_processor_importers_ftrace_minimal",
@@ -1402,6 +1403,17 @@
],
)
+# GN target: //src/trace_processor/importers/etw:full
+perfetto_filegroup(
+ name = "src_trace_processor_importers_etw_full",
+ srcs = [
+ "src/trace_processor/importers/etw/etw_module.cc",
+ "src/trace_processor/importers/etw/etw_module.h",
+ "src/trace_processor/importers/etw/etw_tokenizer.cc",
+ "src/trace_processor/importers/etw/etw_tokenizer.h",
+ ],
+)
+
# GN target: //src/trace_processor/importers/ftrace:ftrace_descriptors
perfetto_filegroup(
name = "src_trace_processor_importers_ftrace_ftrace_descriptors",
@@ -5287,6 +5299,7 @@
":src_trace_processor_importers_common_common",
":src_trace_processor_importers_common_parser_types",
":src_trace_processor_importers_common_trace_parser_hdr",
+ ":src_trace_processor_importers_etw_full",
":src_trace_processor_importers_ftrace_ftrace_descriptors",
":src_trace_processor_importers_ftrace_full",
":src_trace_processor_importers_ftrace_minimal",
@@ -5451,6 +5464,7 @@
":src_trace_processor_importers_common_common",
":src_trace_processor_importers_common_parser_types",
":src_trace_processor_importers_common_trace_parser_hdr",
+ ":src_trace_processor_importers_etw_full",
":src_trace_processor_importers_ftrace_ftrace_descriptors",
":src_trace_processor_importers_ftrace_full",
":src_trace_processor_importers_ftrace_minimal",
@@ -5673,6 +5687,7 @@
":src_trace_processor_importers_common_common",
":src_trace_processor_importers_common_parser_types",
":src_trace_processor_importers_common_trace_parser_hdr",
+ ":src_trace_processor_importers_etw_full",
":src_trace_processor_importers_ftrace_ftrace_descriptors",
":src_trace_processor_importers_ftrace_full",
":src_trace_processor_importers_ftrace_minimal",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index c5be430..c20ba5e 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -158,6 +158,7 @@
"db",
"importers/android_bugreport",
"importers/common",
+ "importers/etw:full",
"importers/ftrace:full",
"importers/fuchsia:full",
"importers/gzip:full",
diff --git a/src/trace_processor/importers/etw/BUILD.gn b/src/trace_processor/importers/etw/BUILD.gn
new file mode 100644
index 0000000..d8985b1
--- /dev/null
+++ b/src/trace_processor/importers/etw/BUILD.gn
@@ -0,0 +1,40 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../gn/test.gni")
+
+source_set("full") {
+ sources = [
+ "etw_module.cc",
+ "etw_module.h",
+ "etw_tokenizer.cc",
+ "etw_tokenizer.h",
+ ]
+ deps = [
+ "../../../../gn:default_deps",
+ "../../../../protos/perfetto/common:zero",
+ "../../../../protos/perfetto/trace:zero",
+ "../../../../protos/perfetto/trace/etw:zero",
+ "../../../../protos/perfetto/trace/interned_data:zero",
+ "../../../protozero",
+ "../../sorter",
+ "../../storage",
+ "../../types",
+ "../common",
+ "../common:parser_types",
+ "../i2c:full",
+ "../proto:minimal",
+ "../syscalls:full",
+ ]
+}
diff --git a/src/trace_processor/importers/etw/etw_module.cc b/src/trace_processor/importers/etw/etw_module.cc
new file mode 100644
index 0000000..508d2ca
--- /dev/null
+++ b/src/trace_processor/importers/etw/etw_module.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/etw/etw_module.h"
+#include "perfetto/base/build_config.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/importers/etw/etw_tokenizer.h"
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using perfetto::protos::pbzero::TracePacket;
+
+EtwModule::EtwModule(TraceProcessorContext* context) : tokenizer_(context) {
+ RegisterForField(TracePacket::kEtwEventsFieldNumber, context);
+}
+
+ModuleResult EtwModule::TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t /*packet_timestamp*/,
+ PacketSequenceState* seq_state,
+ uint32_t field_id) {
+ switch (field_id) {
+ case TracePacket::kEtwEventsFieldNumber: {
+ auto etw_field = decoder.etw_events();
+ tokenizer_.TokenizeEtwBundle(
+ packet->slice(etw_field.data, etw_field.size), seq_state);
+ return ModuleResult::Handled();
+ }
+ }
+ return ModuleResult::Ignored();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/etw/etw_module.h b/src/trace_processor/importers/etw/etw_module.h
new file mode 100644
index 0000000..1624af1
--- /dev/null
+++ b/src/trace_processor/importers/etw/etw_module.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_MODULE_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_MODULE_H_
+
+#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#include "src/trace_processor/importers/common/parser_types.h"
+#include "src/trace_processor/importers/common/trace_parser.h"
+#include "src/trace_processor/importers/etw/etw_module.h"
+#include "src/trace_processor/importers/etw/etw_tokenizer.h"
+#include "src/trace_processor/importers/proto/proto_importer_module.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class EtwModule : public ProtoImporterModule {
+ public:
+ explicit EtwModule(TraceProcessorContext* context);
+
+ ModuleResult TokenizePacket(
+ const protos::pbzero::TracePacket::Decoder& decoder,
+ TraceBlobView* packet,
+ int64_t packet_timestamp,
+ PacketSequenceState* state,
+ uint32_t field_id) override;
+
+ private:
+ EtwTokenizer tokenizer_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_MODULE_H_
diff --git a/src/trace_processor/importers/etw/etw_tokenizer.cc b/src/trace_processor/importers/etw/etw_tokenizer.cc
new file mode 100644
index 0000000..f07d74c
--- /dev/null
+++ b/src/trace_processor/importers/etw/etw_tokenizer.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <optional>
+
+#include "src/trace_processor/importers/etw/etw_tokenizer.h"
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_or.h"
+#include "perfetto/protozero/proto_decoder.h"
+#include "perfetto/protozero/proto_utils.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state.h"
+#include "src/trace_processor/sorter/trace_sorter.h"
+#include "src/trace_processor/storage/trace_storage.h"
+
+#include "protos/perfetto/common/builtin_clock.pbzero.h"
+#include "protos/perfetto/trace/etw/etw_event.pbzero.h"
+#include "protos/perfetto/trace/etw/etw_event_bundle.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+using protozero::ProtoDecoder;
+using protozero::proto_utils::MakeTagVarInt;
+using protozero::proto_utils::ParseVarInt;
+
+using protos::pbzero::BuiltinClock;
+using protos::pbzero::EtwTraceEventBundle;
+
+PERFETTO_ALWAYS_INLINE
+base::Status EtwTokenizer::TokenizeEtwBundle(TraceBlobView bundle,
+ PacketSequenceState* state) {
+ protos::pbzero::EtwTraceEventBundle::Decoder decoder(bundle.data(),
+ bundle.length());
+ // Cpu id can either be in the etw bundle or inside the individual
+ // EtwTraceEvent. If present at this level, we pass it to the TokenizeEtwEvent
+ // in case the EtwTraceEvent does not contain the cpu.
+ std::optional<uint32_t> bundle_cpu =
+ decoder.has_cpu() ? std::make_optional(decoder.cpu()) : std::nullopt;
+ auto it = decoder.event();
+ return TokenizeEtwEvent(bundle_cpu, bundle.slice(it->data(), it->size()),
+ state);
+}
+
+PERFETTO_ALWAYS_INLINE
+base::Status EtwTokenizer::TokenizeEtwEvent(
+ std::optional<uint32_t> fallback_cpu,
+ TraceBlobView event,
+ PacketSequenceState* state) {
+ const uint8_t* data = event.data();
+ const size_t length = event.length();
+ ProtoDecoder decoder(data, length);
+
+ protos::pbzero::EtwTraceEvent::Decoder etw_decoder(data, length);
+ // Some ETW events lack CPU info; in that case, the bundle may
+ // provide it.
+ uint32_t cpu;
+ if (etw_decoder.has_cpu()) {
+ cpu = etw_decoder.cpu();
+ } else {
+ if (!fallback_cpu.has_value()) {
+ return base::ErrStatus(
+ "CPU field not found in EtwEvent and/or EtwEventBundle");
+ }
+ cpu = fallback_cpu.value();
+ }
+
+ static constexpr uint32_t kMaxCpuCount = 1024;
+ if (PERFETTO_UNLIKELY(cpu >= kMaxCpuCount)) {
+ return base::ErrStatus(
+ "CPU %u is greater than maximum allowed of %u. This is likely because "
+ "of trace corruption",
+ cpu, kMaxCpuCount);
+ }
+
+ uint64_t raw_timestamp = 0;
+ if (etw_decoder.has_timestamp()) {
+ raw_timestamp = etw_decoder.timestamp();
+ } else {
+ return base::ErrStatus("Timestamp field not found in EtwEvent");
+ }
+
+ base::StatusOr<int64_t> timestamp = static_cast<int64_t>(raw_timestamp);
+
+ // ClockTracker will increment some error stats if it failed to convert the
+ // timestamp so just return.
+ if (!timestamp.ok()) {
+ return timestamp.status();
+ }
+
+ context_->sorter->PushEtwEvent(cpu, *timestamp, std::move(event),
+ state->current_generation());
+
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/etw/etw_tokenizer.h b/src/trace_processor/importers/etw/etw_tokenizer.h
new file mode 100644
index 0000000..1d93a14
--- /dev/null
+++ b/src/trace_processor/importers/etw/etw_tokenizer.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_TOKENIZER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_TOKENIZER_H_
+
+#include <optional>
+
+#include "perfetto/base/status.h"
+#include "perfetto/trace_processor/trace_blob_view.h"
+#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+
+#include "protos/perfetto/trace/etw/etw_event_bundle.pbzero.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+class PacketSequenceState;
+
+class EtwTokenizer {
+ public:
+ explicit EtwTokenizer(TraceProcessorContext* context) : context_(context) {}
+
+ base::Status TokenizeEtwBundle(TraceBlobView bundle,
+ PacketSequenceState* state);
+
+ private:
+ base::Status TokenizeEtwEvent(std::optional<uint32_t> fallback_cpu,
+ TraceBlobView event,
+ PacketSequenceState* state);
+
+ TraceProcessorContext* context_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_ETW_ETW_TOKENIZER_H_
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index 7f8d3e0..a901ae1 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -75,6 +75,7 @@
"../../../../protos/perfetto/trace:zero",
"../../../../protos/perfetto/trace/android:zero",
"../../../../protos/perfetto/trace/chrome:zero",
+ "../../../../protos/perfetto/trace/etw:zero",
"../../../../protos/perfetto/trace/ftrace:zero",
"../../../../protos/perfetto/trace/interned_data:zero",
"../../../../protos/perfetto/trace/perfetto:zero",
@@ -181,6 +182,7 @@
"../../util:proto_to_args_parser",
"../common",
"../common:parser_types",
+ "../etw:full",
"../ftrace:full",
"../syscalls:full",
"winscope:full",
diff --git a/src/trace_processor/importers/proto/additional_modules.cc b/src/trace_processor/importers/proto/additional_modules.cc
index 341d6d7..6bd58ee 100644
--- a/src/trace_processor/importers/proto/additional_modules.cc
+++ b/src/trace_processor/importers/proto/additional_modules.cc
@@ -15,6 +15,7 @@
*/
#include "src/trace_processor/importers/proto/additional_modules.h"
+#include "src/trace_processor/importers/etw/etw_module.h"
#include "src/trace_processor/importers/ftrace/ftrace_module_impl.h"
#include "src/trace_processor/importers/proto/android_camera_event_module.h"
#include "src/trace_processor/importers/proto/android_probes_module.h"
@@ -43,6 +44,7 @@
context->modules.emplace_back(new MetadataModule(context));
context->modules.emplace_back(new V8Module(context));
context->modules.emplace_back(new WinscopeModule(context));
+ context->modules.emplace_back(new EtwModule(context));
// Ftrace module is special, because it has one extra method for parsing
// ftrace packets. So we need to store a pointer to it separately.
diff --git a/src/trace_processor/importers/proto/default_modules.cc b/src/trace_processor/importers/proto/default_modules.cc
index c24b0f0..ca18beb 100644
--- a/src/trace_processor/importers/proto/default_modules.cc
+++ b/src/trace_processor/importers/proto/default_modules.cc
@@ -32,6 +32,7 @@
// ftrace packets. So we need to store a pointer to it separately.
context->ftrace_module =
static_cast<FtraceModule*>(context->modules.back().get());
+
context->modules.emplace_back(new TrackEventModule(context));
context->track_module =
static_cast<TrackEventModule*>(context->modules.back().get());
diff --git a/src/trace_processor/sorter/trace_sorter.cc b/src/trace_processor/sorter/trace_sorter.cc
index 708def9..0a09224 100644
--- a/src/trace_processor/sorter/trace_sorter.cc
+++ b/src/trace_processor/sorter/trace_sorter.cc
@@ -204,6 +204,26 @@
case TimestampedEvent::Type::kInlineSchedSwitch:
case TimestampedEvent::Type::kInlineSchedWaking:
case TimestampedEvent::Type::kFtraceEvent:
+ case TimestampedEvent::Type::kEtwEvent:
+ PERFETTO_FATAL("Invalid event type");
+ }
+ PERFETTO_FATAL("For GCC");
+}
+
+void TraceSorter::ParseEtwPacket(uint32_t /*cpu*/,
+ const TimestampedEvent& event) {
+ switch (static_cast<TimestampedEvent::Type>(event.event_type)) {
+ case TimestampedEvent::Type::kEtwEvent:
+ return;
+ case TimestampedEvent::Type::kInlineSchedSwitch:
+ case TimestampedEvent::Type::kInlineSchedWaking:
+ case TimestampedEvent::Type::kFtraceEvent:
+ case TimestampedEvent::Type::kTrackEvent:
+ case TimestampedEvent::Type::kSystraceLine:
+ case TimestampedEvent::Type::kTracePacket:
+ case TimestampedEvent::Type::kTraceBlobView:
+ case TimestampedEvent::Type::kJsonValue:
+ case TimestampedEvent::Type::kFuchsiaRecord:
PERFETTO_FATAL("Invalid event type");
}
PERFETTO_FATAL("For GCC");
@@ -225,6 +245,7 @@
parser_->ParseFtraceEvent(cpu, event.ts,
token_buffer_.Extract<TracePacketData>(id));
return;
+ case TimestampedEvent::Type::kEtwEvent:
case TimestampedEvent::Type::kTrackEvent:
case TimestampedEvent::Type::kSystraceLine:
case TimestampedEvent::Type::kTracePacket:
@@ -267,6 +288,9 @@
case TimestampedEvent::Type::kFtraceEvent:
base::ignore_result(token_buffer_.Extract<TracePacketData>(id));
return;
+ case TimestampedEvent::Type::kEtwEvent:
+ base::ignore_result(token_buffer_.Extract<TracePacketData>(id));
+ return;
}
PERFETTO_FATAL("For GCC");
}
@@ -291,7 +315,13 @@
} else {
// Ftrace queues start at offset 1. So queues_[1] = cpu[0] and so on.
uint32_t cpu = static_cast<uint32_t>(queue_idx - 1);
- ParseFtracePacket(cpu, event);
+ auto event_type = static_cast<TimestampedEvent::Type>(event.event_type);
+
+ if (event_type == TimestampedEvent::Type::kEtwEvent) {
+ ParseEtwPacket(static_cast<uint32_t>(cpu), event);
+ } else {
+ ParseFtracePacket(cpu, event);
+ }
}
}
diff --git a/src/trace_processor/sorter/trace_sorter.h b/src/trace_processor/sorter/trace_sorter.h
index ef1ec92..fc4bac8 100644
--- a/src/trace_processor/sorter/trace_sorter.h
+++ b/src/trace_processor/sorter/trace_sorter.h
@@ -136,6 +136,17 @@
AppendNonFtraceEvent(timestamp, TimestampedEvent::Type::kTrackEvent, id);
}
+ inline void PushEtwEvent(uint32_t cpu,
+ int64_t timestamp,
+ TraceBlobView tbv,
+ RefPtr<PacketSequenceStateGeneration> state) {
+ TraceTokenBuffer::Id id =
+ token_buffer_.Append(TracePacketData{std::move(tbv), std::move(state)});
+ auto* queue = GetQueue(cpu + 1);
+ queue->Append(timestamp, TimestampedEvent::Type::kEtwEvent, id);
+ UpdateAppendMaxTs(queue);
+ }
+
inline void PushFtraceEvent(uint32_t cpu,
int64_t timestamp,
TraceBlobView tbv,
@@ -213,7 +224,8 @@
kFuchsiaRecord,
kTrackEvent,
kSystraceLine,
- kMax = kSystraceLine,
+ kEtwEvent,
+ kMax = kEtwEvent,
};
// Number of bits required to store the max element in |Type|.
@@ -327,6 +339,7 @@
void ParseTracePacket(const TimestampedEvent&);
void ParseFtracePacket(uint32_t cpu, const TimestampedEvent&);
+ void ParseEtwPacket(uint32_t cpu, const TimestampedEvent&);
void MaybeExtractEvent(size_t queue_idx, const TimestampedEvent&);
void ExtractAndDiscardTokenizedObject(const TimestampedEvent& event);
diff --git a/src/trace_processor/types/trace_processor_context.h b/src/trace_processor/types/trace_processor_context.h
index 8d770d0..25f129b 100644
--- a/src/trace_processor/types/trace_processor_context.h
+++ b/src/trace_processor/types/trace_processor_context.h
@@ -47,6 +47,7 @@
class ClockTracker;
class ClockConverter;
class DeobfuscationMappingTable;
+class EtwModule;
class EventTracker;
class ForwardingTraceParser;
class FtraceModule;
@@ -157,6 +158,7 @@
// all fields.
std::vector<ProtoImporterModule*> modules_for_all_fields;
FtraceModule* ftrace_module = nullptr;
+ EtwModule* etw_module = nullptr;
TrackEventModule* track_module = nullptr;
// Marks whether the uuid was read from the trace.