Merge "tp: fix generating table headers in G3"
diff --git a/Android.bp b/Android.bp
index 603f6ca..8a41156 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8222,6 +8222,7 @@
filegroup {
name: "perfetto_src_base_threading_threading",
srcs: [
+ "src/base/threading/spawn.cc",
"src/base/threading/stream_combinators.cc",
"src/base/threading/thread_pool.cc",
],
@@ -8233,6 +8234,7 @@
srcs: [
"src/base/threading/channel_unittest.cc",
"src/base/threading/future_unittest.cc",
+ "src/base/threading/spawn_unittest.cc",
"src/base/threading/stream_unittest.cc",
"src/base/threading/thread_pool_unittest.cc",
"src/base/threading/util_unittest.cc",
@@ -9295,6 +9297,7 @@
"src/trace_processor/importers/common/event_tracker.cc",
"src/trace_processor/importers/common/flow_tracker.cc",
"src/trace_processor/importers/common/global_args_tracker.cc",
+ "src/trace_processor/importers/common/metadata_tracker.cc",
"src/trace_processor/importers/common/process_tracker.cc",
"src/trace_processor/importers/common/slice_tracker.cc",
"src/trace_processor/importers/common/slice_translation_table.cc",
@@ -9585,7 +9588,6 @@
"src/trace_processor/importers/proto/memory_tracker_snapshot_module.cc",
"src/trace_processor/importers/proto/memory_tracker_snapshot_parser.cc",
"src/trace_processor/importers/proto/metadata_minimal_module.cc",
- "src/trace_processor/importers/proto/metadata_tracker.cc",
"src/trace_processor/importers/proto/network_trace_module.cc",
"src/trace_processor/importers/proto/packet_analyzer.cc",
"src/trace_processor/importers/proto/packet_sequence_state_generation.cc",
diff --git a/BUILD b/BUILD
index 080ae05..a79e0f2 100644
--- a/BUILD
+++ b/BUILD
@@ -1121,6 +1121,8 @@
"src/trace_processor/importers/common/flow_tracker.h",
"src/trace_processor/importers/common/global_args_tracker.cc",
"src/trace_processor/importers/common/global_args_tracker.h",
+ "src/trace_processor/importers/common/metadata_tracker.cc",
+ "src/trace_processor/importers/common/metadata_tracker.h",
"src/trace_processor/importers/common/process_tracker.cc",
"src/trace_processor/importers/common/process_tracker.h",
"src/trace_processor/importers/common/slice_tracker.cc",
@@ -1412,8 +1414,6 @@
"src/trace_processor/importers/proto/memory_tracker_snapshot_parser.h",
"src/trace_processor/importers/proto/metadata_minimal_module.cc",
"src/trace_processor/importers/proto/metadata_minimal_module.h",
- "src/trace_processor/importers/proto/metadata_tracker.cc",
- "src/trace_processor/importers/proto/metadata_tracker.h",
"src/trace_processor/importers/proto/network_trace_module.cc",
"src/trace_processor/importers/proto/network_trace_module.h",
"src/trace_processor/importers/proto/packet_analyzer.cc",
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 0750e3c..2ac2948 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -1210,6 +1210,10 @@
public_configs = [ ":zlib_config" ]
deps = [ "//gn:default_deps" ]
+ if (is_win) {
+ defines = [ "X86_WINDOWS" ]
+ }
+
# TODO(primiano): look into ADLER32_SIMD_SSSE3 and other SIMD optimizations
# (from chromium's third_party/zlib/BUILD.gn).
}
diff --git a/include/perfetto/ext/base/threading/BUILD.gn b/include/perfetto/ext/base/threading/BUILD.gn
index 9e557ec..d3a7b85 100644
--- a/include/perfetto/ext/base/threading/BUILD.gn
+++ b/include/perfetto/ext/base/threading/BUILD.gn
@@ -20,6 +20,7 @@
"future.h",
"future_combinators.h",
"poll.h",
+ "spawn.h",
"stream.h",
"stream_combinators.h",
"thread_pool.h",
diff --git a/include/perfetto/ext/base/threading/spawn.h b/include/perfetto/ext/base/threading/spawn.h
new file mode 100644
index 0000000..bf73fb9
--- /dev/null
+++ b/include/perfetto/ext/base/threading/spawn.h
@@ -0,0 +1,144 @@
+/*
+ * 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 INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
+
+#include <atomic>
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/flat_set.h"
+#include "perfetto/base/platform_handle.h"
+#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/thread_checker.h"
+#include "perfetto/ext/base/threading/channel.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/stream.h"
+#include "perfetto/ext/base/threading/stream_combinators.h"
+#include "perfetto/ext/base/threading/util.h"
+#include "perfetto/ext/base/uuid.h"
+#include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+namespace base {
+
+class PolledFuture;
+
+// A RAII object which tracks the polling of a Future.
+//
+// When this object is dropped, the backing Future will be cancelled as
+// soon as possible. In practice, the cancellation happens on the TaskRunner
+// thread so there can be some delay.
+class SpawnHandle {
+ public:
+ SpawnHandle(TaskRunner* task_runner, std::function<Future<FVoid>()> fn);
+ ~SpawnHandle();
+
+ private:
+ SpawnHandle(const SpawnHandle&) = delete;
+ SpawnHandle& operator=(const SpawnHandle&) = delete;
+
+ TaskRunner* task_runner_ = nullptr;
+ std::shared_ptr<std::unique_ptr<PolledFuture>> polled_future_;
+};
+
+// Specialization of SpawnHandle used by Futures/Streams which return T.
+//
+// Values of T are returned through a Channel<T> which allows reading these
+// values on a different thread to where the polling happens.
+template <typename T>
+class ResultSpawnHandle {
+ public:
+ ResultSpawnHandle(TaskRunner* task_runner,
+ std::shared_ptr<Channel<T>> channel,
+ std::function<Future<FVoid>()> fn)
+ : handle_(task_runner, std::move(fn)), channel_(std::move(channel)) {}
+
+ Channel<T>* channel() const { return channel_.get(); }
+
+ private:
+ SpawnHandle handle_;
+ std::shared_ptr<Channel<T>> channel_;
+};
+
+// "Spawns" a Future<FVoid> on the given TaskRunner and returns an RAII
+// SpawnHandle which can be used to cancel the spawn.
+//
+// Spawning a Future means to poll it to completion. In Perfetto, this is done
+// by using a TaskRunner object to track FD readiness and polling the Future
+// when progress can be made.
+//
+// The returned SpawnHandle should be stashed as it is responsible for the
+// lifetime of the pollling. If the SpawnHandle is dropped, the Future is
+// cancelled and dropped ASAP (this happens on the TaskRunner thread so there
+// can be some delay).
+PERFETTO_WARN_UNUSED_RESULT inline SpawnHandle SpawnFuture(
+ TaskRunner* task_runner,
+ std::function<Future<FVoid>()> fn) {
+ return SpawnHandle(task_runner, std::move(fn));
+}
+
+// Variant of |SpawnFuture| for a Stream<T> allowing returning items of T.
+//
+// See ResultSpawnHandle for how elements from the stream can be consumed.
+template <typename T>
+PERFETTO_WARN_UNUSED_RESULT inline ResultSpawnHandle<T> SpawnResultStream(
+ TaskRunner* task_runner,
+ std::function<Stream<T>()> fn) {
+ class AllVoidCollector : public Collector<FVoid, FVoid> {
+ public:
+ Optional<FVoid> OnNext(FVoid) override { return nullopt; }
+ FVoid OnDone() override { return FVoid(); }
+ };
+ auto channel = std::make_shared<Channel<T>>(4);
+ return ResultSpawnHandle<T>(
+ task_runner, channel, [c = channel, fn = std::move(fn)]() {
+ return fn()
+ .MapFuture([c](T value) {
+ return WriteChannelFuture(c.get(), std::move(value));
+ })
+ .Concat(OnDestroyStream<FVoid>([c]() { c->Close(); }))
+ .Collect(std::unique_ptr<Collector<FVoid, FVoid>>(
+ new AllVoidCollector()));
+ });
+}
+
+// Variant of |SpawnFuture| for a Future<T> allowing returning items of T.
+//
+// See ResultSpawnHandle for how elements from the future can be consumed.
+template <typename T>
+PERFETTO_WARN_UNUSED_RESULT inline ResultSpawnHandle<T> SpawnResultFuture(
+ TaskRunner* task_runner,
+ std::function<Future<T>()> fn) {
+ return SpawnResultStream<T>(task_runner, [fn = std::move(fn)]() {
+ return StreamFromFuture(std::move(fn()));
+ });
+}
+
+} // namespace base
+} // namespace perfetto
+
+#endif // INCLUDE_PERFETTO_EXT_BASE_THREADING_SPAWN_H_
diff --git a/src/android_stats/perfetto_atoms.h b/src/android_stats/perfetto_atoms.h
index 5a5eef0..e9ef08e 100644
--- a/src/android_stats/perfetto_atoms.h
+++ b/src/android_stats/perfetto_atoms.h
@@ -70,6 +70,7 @@
kTracedStartTracingInvalidSessionState = 36,
kTracedEnableTracingInvalidFilter = 47,
kTracedEnableTracingOobTargetBuffer = 48,
+ kTracedEnableTracingInvalidTriggerMode = 52,
// Checkpoints inside perfetto_cmd after tracing has finished.
kOnTracingDisabled = 4,
diff --git a/src/base/threading/BUILD.gn b/src/base/threading/BUILD.gn
index 3a31723..23343bc 100644
--- a/src/base/threading/BUILD.gn
+++ b/src/base/threading/BUILD.gn
@@ -15,9 +15,13 @@
import("../../../gn/test.gni")
source_set("threading") {
- deps = [ "../../../gn:default_deps" ]
+ deps = [
+ "..:base",
+ "../../../gn:default_deps",
+ ]
public_deps = [ "../../../include/perfetto/ext/base/threading" ]
sources = [
+ "spawn.cc",
"stream_combinators.cc",
"thread_pool.cc",
]
@@ -28,12 +32,14 @@
deps = [
":threading",
"..:base",
+ "..:test_support",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
]
sources = [
"channel_unittest.cc",
"future_unittest.cc",
+ "spawn_unittest.cc",
"stream_unittest.cc",
"thread_pool_unittest.cc",
"util_unittest.cc",
diff --git a/src/base/threading/spawn.cc b/src/base/threading/spawn.cc
new file mode 100644
index 0000000..4fd246a
--- /dev/null
+++ b/src/base/threading/spawn.cc
@@ -0,0 +1,124 @@
+/*
+ * 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 "perfetto/ext/base/threading/spawn.h"
+
+#include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/thread_checker.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/stream.h"
+
+namespace perfetto {
+namespace base {
+
+// Represents a future which is being polled to completion. Owned by
+// SpawnHandle.
+class PolledFuture {
+ public:
+ explicit PolledFuture(TaskRunner* task_runner, Future<FVoid> future)
+ : task_runner_(task_runner), future_(std::move(future)) {
+ PERFETTO_DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ PollUntilFinish();
+ }
+
+ ~PolledFuture() {
+ PERFETTO_DCHECK_THREAD(thread_checker);
+ ClearFutureAndWatches(interested_);
+ }
+
+ private:
+ PolledFuture(PolledFuture&&) = delete;
+ PolledFuture& operator=(PolledFuture&&) = delete;
+
+ void PollUntilFinish() {
+ PERFETTO_DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+ auto pre_poll_interested = std::move(interested_);
+ interested_.clear();
+
+ FuturePollResult<FVoid> res = future_->Poll(&context_);
+ if (!res.IsPending()) {
+ ClearFutureAndWatches(pre_poll_interested);
+ return;
+ }
+
+ for (PlatformHandle fd : SetDifference(pre_poll_interested, interested_)) {
+ task_runner_->RemoveFileDescriptorWatch(fd);
+ }
+
+ auto weak_this = weak_ptr_factory_.GetWeakPtr();
+ for (PlatformHandle fd : SetDifference(interested_, pre_poll_interested)) {
+ task_runner_->AddFileDescriptorWatch(fd, [weak_this, fd]() {
+ if (!weak_this) {
+ return;
+ }
+ weak_this->ready_ = {fd};
+ weak_this->PollUntilFinish();
+ });
+ }
+ }
+
+ void ClearFutureAndWatches(FlatSet<PlatformHandle> interested) {
+ future_ = nullopt;
+ for (PlatformHandle fd : interested) {
+ task_runner_->RemoveFileDescriptorWatch(fd);
+ }
+ interested_.clear();
+ ready_.clear();
+ }
+
+ static std::vector<PlatformHandle> SetDifference(
+ const FlatSet<PlatformHandle>& f,
+ const FlatSet<PlatformHandle>& s) {
+ std::vector<PlatformHandle> out(f.size());
+ auto it = std::set_difference(f.begin(), f.end(), s.begin(), s.end(),
+ out.begin());
+ out.resize(static_cast<size_t>(std::distance(out.begin(), it)));
+ return out;
+ }
+
+ TaskRunner* const task_runner_ = nullptr;
+
+ Optional<Future<FVoid>> future_;
+ FlatSet<PlatformHandle> interested_;
+ FlatSet<PlatformHandle> ready_;
+ PollContext context_{&interested_, &ready_};
+
+ PERFETTO_THREAD_CHECKER(thread_checker)
+
+ // Keep this last.
+ WeakPtrFactory<PolledFuture> weak_ptr_factory_{this};
+};
+
+SpawnHandle::SpawnHandle(TaskRunner* task_runner,
+ std::function<Future<FVoid>()> fn)
+ : task_runner_(task_runner),
+ polled_future_(std::make_shared<std::unique_ptr<PolledFuture>>()) {
+ task_runner->PostTask(
+ [t = task_runner, fn = std::move(fn), p = polled_future_]() mutable {
+ p->reset(new PolledFuture(t, fn()));
+ });
+}
+
+SpawnHandle::~SpawnHandle() {
+ task_runner_->PostTask(
+ [f = std::move(polled_future_)]() mutable { f.reset(); });
+}
+
+} // namespace base
+} // namespace perfetto
diff --git a/src/base/threading/spawn_unittest.cc b/src/base/threading/spawn_unittest.cc
new file mode 100644
index 0000000..1324b18
--- /dev/null
+++ b/src/base/threading/spawn_unittest.cc
@@ -0,0 +1,133 @@
+/*
+ * 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 "perfetto/ext/base/threading/spawn.h"
+
+#include "perfetto/ext/base/event_fd.h"
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/thread_task_runner.h"
+#include "perfetto/ext/base/threading/future.h"
+#include "perfetto/ext/base/threading/poll.h"
+#include "perfetto/ext/base/threading/util.h"
+#include "perfetto/ext/base/unix_task_runner.h"
+#include "src/base/test/test_task_runner.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+using ::testing::_;
+using ::testing::Return;
+
+template <typename T>
+class MockFuturePollable : public FuturePollable<T> {
+ public:
+ MOCK_METHOD1(Poll, FuturePollResult<T>(PollContext*));
+};
+
+template <typename T>
+class MockStreamPollable : public StreamPollable<T> {
+ public:
+ MOCK_METHOD1(PollNext, StreamPollResult<T>(PollContext*));
+};
+
+TEST(SpawnUnittest, SpawnFuture) {
+ base::TestTaskRunner task_runner;
+
+ base::EventFd fd;
+ auto pollable = std::make_unique<MockFuturePollable<int>>();
+ EXPECT_CALL(*pollable, Poll(_))
+ .WillOnce([&fd](PollContext* ctx) {
+ fd.Clear();
+ ctx->RegisterInterested(fd.fd());
+ return PendingPollResult();
+ })
+ .WillOnce(Return(FuturePollResult<int>(1024)));
+ auto res = SpawnResultFuture<int>(
+ &task_runner,
+ [pollable = std::make_shared<std::unique_ptr<MockFuturePollable<int>>>(
+ std::move(pollable))]() mutable {
+ return base::Future<int>(std::move(*pollable));
+ });
+
+ task_runner.RunUntilIdle();
+ ASSERT_EQ(res.channel()->ReadNonBlocking().item, base::nullopt);
+
+ task_runner.RunUntilIdle();
+ ASSERT_EQ(res.channel()->ReadNonBlocking().item, base::nullopt);
+
+ fd.Notify();
+ task_runner.RunUntilIdle();
+
+ auto read = res.channel()->ReadNonBlocking();
+ ASSERT_EQ(read.item, 1024);
+ ASSERT_TRUE(read.is_closed);
+
+ read = res.channel()->ReadNonBlocking();
+ ASSERT_TRUE(read.is_closed);
+}
+
+TEST(SpawnUnittest, SpawnStream) {
+ base::TestTaskRunner task_runner;
+
+ base::EventFd fd;
+ auto pollable = std::make_unique<MockStreamPollable<int>>();
+ EXPECT_CALL(*pollable, PollNext(_))
+ .WillOnce([&fd](PollContext* ctx) {
+ fd.Clear();
+ ctx->RegisterInterested(fd.fd());
+ return PendingPollResult();
+ })
+ .WillOnce(Return(StreamPollResult<int>(1024)))
+ .WillOnce([&fd](PollContext* ctx) {
+ fd.Clear();
+ ctx->RegisterInterested(fd.fd());
+ return PendingPollResult();
+ })
+ .WillOnce(Return(StreamPollResult<int>(2048)))
+ .WillOnce(Return(DonePollResult()));
+ auto res = SpawnResultStream<int>(
+ &task_runner,
+ [pollable = std::make_shared<std::unique_ptr<MockStreamPollable<int>>>(
+ std::move(pollable))]() mutable {
+ return base::Stream<int>(std::move(*pollable));
+ });
+
+ task_runner.RunUntilIdle();
+ ASSERT_EQ(res.channel()->ReadNonBlocking().item, base::nullopt);
+
+ fd.Notify();
+ task_runner.RunUntilIdle();
+
+ auto read = res.channel()->ReadNonBlocking();
+ ASSERT_EQ(read.item, 1024);
+ ASSERT_FALSE(read.is_closed);
+
+ task_runner.RunUntilIdle();
+ ASSERT_EQ(res.channel()->ReadNonBlocking().item, base::nullopt);
+
+ fd.Notify();
+ task_runner.RunUntilIdle();
+
+ read = res.channel()->ReadNonBlocking();
+ ASSERT_EQ(read.item, 2048);
+ ASSERT_TRUE(read.is_closed);
+}
+
+} // namespace
+} // namespace base
+} // namespace perfetto
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index 07722a0..823bc17 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -28,9 +28,9 @@
#include "perfetto/ext/base/temp_file.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/track_event_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
diff --git a/src/trace_processor/importers/common/BUILD.gn b/src/trace_processor/importers/common/BUILD.gn
index 22a1154..7795398 100644
--- a/src/trace_processor/importers/common/BUILD.gn
+++ b/src/trace_processor/importers/common/BUILD.gn
@@ -33,6 +33,8 @@
"flow_tracker.h",
"global_args_tracker.cc",
"global_args_tracker.h",
+ "metadata_tracker.cc",
+ "metadata_tracker.h",
"process_tracker.cc",
"process_tracker.h",
"slice_tracker.cc",
diff --git a/src/trace_processor/importers/common/clock_tracker.cc b/src/trace_processor/importers/common/clock_tracker.cc
index a2feea9..987739c 100644
--- a/src/trace_processor/importers/common/clock_tracker.cc
+++ b/src/trace_processor/importers/common/clock_tracker.cc
@@ -36,8 +36,8 @@
using Clock = protos::pbzero::ClockSnapshot::Clock;
-ClockTracker::ClockTracker(TraceStorage* storage)
- : storage_(storage),
+ClockTracker::ClockTracker(TraceProcessorContext* context)
+ : context_(context),
trace_time_clock_id_(protos::pbzero::BUILTIN_CLOCK_BOOTTIME) {}
ClockTracker::~ClockTracker() = default;
@@ -67,7 +67,7 @@
" cannot use incremental encoding; this is only "
"supported for sequence-scoped clocks.",
clock_id);
- storage_->IncrementStats(stats::invalid_clock_snapshots);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
return snapshot_id;
}
domain.unit_multiplier_ns = clock_ts.clock.unit_multiplier_ns;
@@ -83,7 +83,7 @@
clock_id, clock_ts.clock.unit_multiplier_ns,
clock_ts.clock.is_incremental, domain.unit_multiplier_ns,
domain.is_incremental);
- storage_->IncrementStats(stats::invalid_clock_snapshots);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
return snapshot_id;
}
const int64_t timestamp_ns = clock_ts.timestamp * domain.unit_multiplier_ns;
@@ -95,7 +95,7 @@
PERFETTO_ELOG("Clock sync error: duplicate clock domain with id=%" PRIu64
" at snapshot %" PRIu32 ".",
clock_id, snapshot_id);
- storage_->IncrementStats(stats::invalid_clock_snapshots);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
return snapshot_id;
}
@@ -119,7 +119,7 @@
" not >= %" PRId64 ".",
clock_id, snapshot_id, timestamp_ns,
vect.timestamps_ns.back());
- storage_->IncrementStats(stats::invalid_clock_snapshots);
+ context_->storage->IncrementStats(stats::invalid_clock_snapshots);
return snapshot_id;
}
@@ -220,12 +220,12 @@
PERFETTO_DCHECK(!IsSequenceClock(src_clock_id));
PERFETTO_DCHECK(!IsSequenceClock(target_clock_id));
- storage_->IncrementStats(stats::clock_sync_cache_miss);
+ context_->storage->IncrementStats(stats::clock_sync_cache_miss);
ClockPath path = FindPath(src_clock_id, target_clock_id);
if (!path.valid()) {
// Too many logs maybe emitted when path is invalid.
- storage_->IncrementStats(stats::clock_sync_failure);
+ context_->storage->IncrementStats(stats::clock_sync_failure);
return base::ErrStatus("No path from clock %" PRIu64 " to %" PRIu64
" at timestamp %" PRId64,
src_clock_id, target_clock_id, src_timestamp);
diff --git a/src/trace_processor/importers/common/clock_tracker.h b/src/trace_processor/importers/common/clock_tracker.h
index 2e4a3b1..81588e6 100644
--- a/src/trace_processor/importers/common/clock_tracker.h
+++ b/src/trace_processor/importers/common/clock_tracker.h
@@ -30,7 +30,9 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/status_or.h"
#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/types/trace_processor_context.h"
namespace perfetto {
namespace trace_processor {
@@ -116,9 +118,9 @@
class ClockTracker {
public:
- using ClockId = uint64_t;
+ using ClockId = int64_t;
- explicit ClockTracker(TraceStorage*);
+ explicit ClockTracker(TraceProcessorContext*);
virtual ~ClockTracker();
// Clock description.
@@ -153,7 +155,7 @@
// passed as argument to ClockTracker functions.
static ClockId SeqenceToGlobalClock(uint32_t seq_id, uint32_t clock_id) {
PERFETTO_DCHECK(IsSequenceClock(clock_id));
- return (static_cast<uint64_t>(seq_id) << 32) | clock_id;
+ return (static_cast<int64_t>(seq_id) << 32) | clock_id;
}
// Appends a new snapshot for the given clock domains.
@@ -162,6 +164,12 @@
uint32_t AddSnapshot(const std::vector<ClockTimestamp>&);
base::StatusOr<int64_t> ToTraceTime(ClockId clock_id, int64_t timestamp) {
+ if (PERFETTO_UNLIKELY(!trace_time_clock_id_used_for_conversion_)) {
+ context_->metadata_tracker->SetMetadata(
+ metadata::trace_time_clock_id,
+ Variadic::Integer(trace_time_clock_id_));
+ trace_time_clock_id_used_for_conversion_ = true;
+ }
trace_time_clock_id_used_for_conversion_ = true;
if (clock_id == trace_time_clock_id_)
return timestamp;
@@ -189,6 +197,8 @@
return;
}
trace_time_clock_id_ = clock_id;
+ context_->metadata_tracker->SetMetadata(
+ metadata::trace_time_clock_id, Variadic::Integer(trace_time_clock_id_));
}
void set_cache_lookups_disabled_for_testing(bool v) {
@@ -328,7 +338,7 @@
return &it->second;
}
- TraceStorage* const storage_;
+ TraceProcessorContext* const context_;
ClockId trace_time_clock_id_ = 0;
std::map<ClockId, ClockDomain> clocks_;
std::set<ClockGraphEdge> graph_;
diff --git a/src/trace_processor/importers/common/clock_tracker_unittest.cc b/src/trace_processor/importers/common/clock_tracker_unittest.cc
index 0614372..e625111 100644
--- a/src/trace_processor/importers/common/clock_tracker_unittest.cc
+++ b/src/trace_processor/importers/common/clock_tracker_unittest.cc
@@ -19,6 +19,7 @@
#include <random>
#include "perfetto/ext/base/optional.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"
@@ -31,9 +32,15 @@
class ClockTrackerTest : public ::testing::Test {
public:
+ ClockTrackerTest() {
+ context_.storage.reset(new TraceStorage());
+ context_.metadata_tracker.reset(
+ new MetadataTracker(context_.storage.get()));
+ }
+
// using ClockId = uint64_t;
- TraceStorage storage_;
- ClockTracker ct_{&storage_};
+ TraceProcessorContext context_;
+ ClockTracker ct_{&context_};
base::StatusOr<int64_t> Convert(ClockTracker::ClockId src_clock_id,
int64_t src_timestamp,
ClockTracker::ClockId target_clock_id) {
diff --git a/src/trace_processor/importers/proto/metadata_tracker.cc b/src/trace_processor/importers/common/metadata_tracker.cc
similarity index 98%
rename from src/trace_processor/importers/proto/metadata_tracker.cc
rename to src/trace_processor/importers/common/metadata_tracker.cc
index a5e6928..010b1b7 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.cc
+++ b/src/trace_processor/importers/common/metadata_tracker.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "perfetto/ext/base/crash_keys.h"
#include "src/trace_processor/importers/common/process_tracker.h"
diff --git a/src/trace_processor/importers/proto/metadata_tracker.h b/src/trace_processor/importers/common/metadata_tracker.h
similarity index 91%
rename from src/trace_processor/importers/proto/metadata_tracker.h
rename to src/trace_processor/importers/common/metadata_tracker.h
index c3e587e..80cace9 100644
--- a/src/trace_processor/importers/proto/metadata_tracker.h
+++ b/src/trace_processor/importers/common/metadata_tracker.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
#include "src/trace_processor/storage/trace_storage.h"
@@ -70,4 +70,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_METADATA_TRACKER_H_
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 7033130..78157d1 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -22,6 +22,7 @@
#include "perfetto/protozero/proto_decoder.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/async_track_set_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/parser_types.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/ftrace/binder_tracker.h"
@@ -29,7 +30,6 @@
#include "src/trace_processor/importers/ftrace/v4l2_tracker.h"
#include "src/trace_processor/importers/ftrace/virtio_video_tracker.h"
#include "src/trace_processor/importers/i2c/i2c_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/syscalls/syscall_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_parser.h"
@@ -1403,7 +1403,6 @@
evt.func_name(), tgid, evt.value());
}
-
/** Parses ion heap events present in Pixel kernels. */
void FtraceParser::ParseIonHeapGrowOrShrink(int64_t timestamp,
uint32_t pid,
@@ -1717,7 +1716,8 @@
ThreadNamePriority::kFtrace);
proc_tracker->AssociateThreads(source_utid, new_utid);
- ThreadStateTracker::GetOrCreate(context_)->PushNewTaskEvent(timestamp, new_utid, source_utid);
+ ThreadStateTracker::GetOrCreate(context_)->PushNewTaskEvent(
+ timestamp, new_utid, source_utid);
}
void FtraceParser::ParseTaskRename(ConstBytes blob) {
diff --git a/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc b/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
index 92ccb20..349e9d0 100644
--- a/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
+++ b/src/trace_processor/importers/fuchsia/fuchsia_parser_unittest.cc
@@ -26,13 +26,13 @@
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
#include "src/trace_processor/importers/proto/additional_modules.h"
#include "src/trace_processor/importers/proto/default_modules.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/sorter/trace_sorter.h"
@@ -228,7 +228,7 @@
slice_ = new NiceMock<MockSliceTracker>(&context_);
context_.slice_tracker.reset(slice_);
context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
- context_.clock_tracker.reset(new ClockTracker(context_.storage.get()));
+ context_.clock_tracker.reset(new ClockTracker(&context_));
clock_ = context_.clock_tracker.get();
context_.flow_tracker.reset(new FlowTracker(&context_));
context_.sorter.reset(new TraceSorter(&context_, CreateParser(),
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index 07bdd19..47bf6c7 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -34,8 +34,6 @@
"memory_tracker_snapshot_parser.h",
"metadata_minimal_module.cc",
"metadata_minimal_module.h",
- "metadata_tracker.cc",
- "metadata_tracker.h",
"network_trace_module.cc",
"network_trace_module.h",
"packet_analyzer.cc",
diff --git a/src/trace_processor/importers/proto/android_probes_parser.cc b/src/trace_processor/importers/proto/android_probes_parser.cc
index 6d37b9c..7827d50 100644
--- a/src/trace_processor/importers/proto/android_probes_parser.cc
+++ b/src/trace_processor/importers/proto/android_probes_parser.cc
@@ -23,8 +23,8 @@
#include "src/trace_processor/importers/common/async_track_set_tracker.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/syscalls/syscall_tracker.h"
#include "src/trace_processor/types/tcp_state.h"
#include "src/trace_processor/types/trace_processor_context.h"
diff --git a/src/trace_processor/importers/proto/metadata_minimal_module.cc b/src/trace_processor/importers/proto/metadata_minimal_module.cc
index d29b3d3..099cdac 100644
--- a/src/trace_processor/importers/proto/metadata_minimal_module.cc
+++ b/src/trace_processor/importers/proto/metadata_minimal_module.cc
@@ -17,7 +17,7 @@
#include "src/trace_processor/importers/proto/metadata_minimal_module.h"
#include "perfetto/ext/base/base64.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h"
diff --git a/src/trace_processor/importers/proto/metadata_module.cc b/src/trace_processor/importers/proto/metadata_module.cc
index 81a4ce6..3374043 100644
--- a/src/trace_processor/importers/proto/metadata_module.cc
+++ b/src/trace_processor/importers/proto/metadata_module.cc
@@ -18,10 +18,10 @@
#include "perfetto/ext/base/base64.h"
#include "perfetto/ext/base/uuid.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/proto/config.descriptor.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/util/descriptors.h"
#include "src/trace_processor/util/protozero_to_text.h"
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 600b886..fa1ffd6 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -30,12 +30,12 @@
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/parser_types.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/track_event_module.h"
#include "src/trace_processor/storage/metadata.h"
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
index 5b907a3..ff841aa 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -25,13 +25,13 @@
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
#include "src/trace_processor/importers/proto/additional_modules.h"
#include "src/trace_processor/importers/proto/default_modules.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/sorter/trace_sorter.h"
@@ -243,7 +243,7 @@
slice_ = new NiceMock<MockSliceTracker>(&context_);
context_.slice_tracker.reset(slice_);
context_.slice_translation_table.reset(new SliceTranslationTable(storage_));
- clock_ = new ClockTracker(context_.storage.get());
+ clock_ = new ClockTracker(&context_);
context_.clock_tracker.reset(clock_);
context_.flow_tracker.reset(new FlowTracker(&context_));
context_.sorter.reset(new TraceSorter(&context_, CreateParser(),
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index cb0567b..f3b06fb 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -28,9 +28,9 @@
#include "perfetto/trace_processor/status.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_analyzer.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/proto_incremental_state.h"
@@ -399,7 +399,7 @@
}
base::Optional<StringId> ProtoTraceReader::GetBuiltinClockNameOrNull(
- uint64_t clock_id) {
+ int64_t clock_id) {
switch (clock_id) {
case protos::pbzero::ClockSnapshot::Clock::REALTIME:
return context_->storage->InternString("REALTIME");
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.h b/src/trace_processor/importers/proto/proto_trace_reader.h
index 471503a..3776358 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.h
+++ b/src/trace_processor/importers/proto/proto_trace_reader.h
@@ -75,7 +75,7 @@
TraceBlobView interned_data);
void ParseTraceConfig(ConstBytes);
- base::Optional<StringId> GetBuiltinClockNameOrNull(uint64_t clock_id);
+ base::Optional<StringId> GetBuiltinClockNameOrNull(int64_t clock_id);
PacketSequenceState* GetIncrementalStateForPacketSequence(
uint32_t sequence_id) {
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index a16ca4a..3a3c438 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -23,9 +23,9 @@
#include "perfetto/ext/traced/sys_stats_counters.h"
#include "perfetto/protozero/proto_decoder.h"
#include "src/trace_processor/importers/common/event_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/system_info_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/syscalls/syscall_tracker.h"
#include "src/trace_processor/storage/metadata.h"
#include "src/trace_processor/types/trace_processor_context.h"
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
index 314d205..35c76a3 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.cc
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -19,9 +19,9 @@
#include "perfetto/base/logging.h"
#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/track_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/importers/proto/proto_trace_reader.h"
#include "src/trace_processor/importers/proto/track_event_tracker.h"
diff --git a/src/trace_processor/storage/metadata.h b/src/trace_processor/storage/metadata.h
index de2e651..88eac06 100644
--- a/src/trace_processor/storage/metadata.h
+++ b/src/trace_processor/storage/metadata.h
@@ -50,6 +50,7 @@
F(system_version, KeyType::kSingle, Variadic::kString), \
F(trace_config_pbtxt, KeyType::kSingle, Variadic::kString), \
F(trace_size_bytes, KeyType::kSingle, Variadic::kInt), \
+ F(trace_time_clock_id, KeyType::kSingle, Variadic::kInt), \
F(trace_type, KeyType::kSingle, Variadic::kString), \
F(trace_uuid, KeyType::kSingle, Variadic::kString), \
F(tracing_disabled_ns, KeyType::kSingle, Variadic::kInt), \
diff --git a/src/trace_processor/trace_processor_context.cc b/src/trace_processor/trace_processor_context.cc
index 29fa474..b407e19 100644
--- a/src/trace_processor/trace_processor_context.cc
+++ b/src/trace_processor/trace_processor_context.cc
@@ -26,13 +26,13 @@
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
#include "src/trace_processor/importers/common/global_args_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/slice_translation_table.h"
#include "src/trace_processor/importers/common/track_tracker.h"
#include "src/trace_processor/importers/ftrace/ftrace_module.h"
#include "src/trace_processor/importers/proto/heap_profile_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/perf_sample_tracker.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
#include "src/trace_processor/importers/proto/proto_trace_parser.h"
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 24bb87e..7c38b98 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -33,6 +33,7 @@
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/importers/android_bugreport/android_bugreport_parser.h"
#include "src/trace_processor/importers/common/clock_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.h"
#include "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h"
@@ -43,7 +44,6 @@
#include "src/trace_processor/importers/ninja/ninja_log_parser.h"
#include "src/trace_processor/importers/proto/additional_modules.h"
#include "src/trace_processor/importers/proto/content_analyzer.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
#include "src/trace_processor/iterator_impl.h"
#include "src/trace_processor/prelude/functions/create_function.h"
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index 3bea7eb..75031f8 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -25,6 +25,7 @@
#include "src/trace_processor/importers/common/clock_tracker.h"
#include "src/trace_processor/importers/common/event_tracker.h"
#include "src/trace_processor/importers/common/flow_tracker.h"
+#include "src/trace_processor/importers/common/metadata_tracker.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/importers/common/slice_tracker.h"
#include "src/trace_processor/importers/common/slice_translation_table.h"
@@ -32,7 +33,6 @@
#include "src/trace_processor/importers/proto/chrome_track_event.descriptor.h"
#include "src/trace_processor/importers/proto/default_modules.h"
#include "src/trace_processor/importers/proto/heap_profile_tracker.h"
-#include "src/trace_processor/importers/proto/metadata_tracker.h"
#include "src/trace_processor/importers/proto/packet_analyzer.h"
#include "src/trace_processor/importers/proto/perf_sample_tracker.h"
#include "src/trace_processor/importers/proto/proto_importer_module.h"
@@ -60,7 +60,7 @@
context_.flow_tracker.reset(new FlowTracker(&context_));
context_.event_tracker.reset(new EventTracker(&context_));
context_.process_tracker.reset(new ProcessTracker(&context_));
- context_.clock_tracker.reset(new ClockTracker(context_.storage.get()));
+ context_.clock_tracker.reset(new ClockTracker(&context_));
context_.heap_profile_tracker.reset(new HeapProfileTracker(&context_));
context_.perf_sample_tracker.reset(new PerfSampleTracker(&context_));
context_.global_stack_profile_tracker.reset(new GlobalStackProfileTracker());
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index a590837..5277657 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -623,6 +623,15 @@
cfg.trigger_config().trigger_timeout_ms());
}
+ // This check has been introduced in May 2023 after finding b/274931668.
+ if (static_cast<int>(cfg.trigger_config().trigger_mode()) >
+ TraceConfig::TriggerConfig::TriggerMode_MAX) {
+ MaybeLogUploadEvent(
+ cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+ return PERFETTO_SVC_ERR(
+ "The trace config specified an invalid trigger_mode");
+ }
+
if (has_trigger_config && cfg.duration_ms() != 0) {
MaybeLogUploadEvent(
cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
@@ -982,6 +991,9 @@
tracing_session->config.set_duration_ms(
cfg.trigger_config().trigger_timeout_ms());
break;
+
+ // The case of unknown modes (coming from future versions of the service)
+ // is handled few lines above (search for TriggerMode_MAX).
}
tracing_session->state = TracingSession::CONFIGURED;
diff --git a/src/tracing/core/tracing_service_impl_unittest.cc b/src/tracing/core/tracing_service_impl_unittest.cc
index 8b8c62c..b66e502 100644
--- a/src/tracing/core/tracing_service_impl_unittest.cc
+++ b/src/tracing/core/tracing_service_impl_unittest.cc
@@ -432,6 +432,31 @@
EXPECT_THAT(consumer->ReadBuffers(), IsEmpty());
}
+// Regression test for b/274931668. An unkonwn trigger should not cause a trace
+// that runs indefinitely.
+TEST_F(TracingServiceImplTest, FailOnUnknownTrigger) {
+ std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+ consumer->Connect(svc.get());
+
+ std::unique_ptr<MockProducer> producer = CreateMockProducer();
+ producer->Connect(svc.get(), "mock_producer");
+ producer->RegisterDataSource("ds_1");
+
+ TraceConfig trace_config;
+ trace_config.add_buffers()->set_size_kb(128);
+ trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
+ auto* trigger_config = trace_config.mutable_trigger_config();
+ trigger_config->set_trigger_mode(
+ static_cast<TraceConfig::TriggerConfig::TriggerMode>(
+ TraceConfig::TriggerConfig::TriggerMode_MAX + 1));
+ auto* trigger = trigger_config->add_triggers();
+ trigger->set_name("trigger_from_the_future");
+ trigger_config->set_trigger_timeout_ms(1);
+
+ consumer->EnableTracing(trace_config);
+ consumer->WaitForTracingDisabled();
+}
+
// Creates a tracing session with a START_TRACING trigger and checks that
// the session is not started when the configured trigger producer is different
// than the producer that sent the trigger.
diff --git a/test/trace_processor/diff_tests/parsing/chrome_metadata.out b/test/trace_processor/diff_tests/parsing/chrome_metadata.out
index 7346e41..873e349 100644
--- a/test/trace_processor/diff_tests/parsing/chrome_metadata.out
+++ b/test/trace_processor/diff_tests/parsing/chrome_metadata.out
@@ -1,9 +1,10 @@
"id","type","name","key_type","int_value","str_value"
-0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-dcce-849205cfb03e"
-1,"metadata","cr-playstore_version_code","single",101,"[NULL]"
-2,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
-3,"metadata","cr-background_tracing_metadata","single","[NULL]","CgUlDsAbXx2RziSz"
-4,"metadata","cr-scenario_name_hash","single",3005533841,"[NULL]"
-5,"metadata","cr-triggered_rule_name_hash","single",1595654158,"[NULL]"
-6,"metadata","trace_size_bytes","single",64,"[NULL]"
-7,"metadata","trace_type","single","[NULL]","proto"
+0,"metadata","trace_uuid","single","[NULL]","00000000-0000-0000-dcce-849205cfb03e"
+1,"metadata","trace_time_clock_id","single",6,"[NULL]"
+2,"metadata","cr-playstore_version_code","single",101,"[NULL]"
+3,"metadata","cr-enabled_categories","single","[NULL]","cat1,cat2,cat3"
+4,"metadata","cr-background_tracing_metadata","single","[NULL]","CgUlDsAbXx2RziSz"
+5,"metadata","cr-scenario_name_hash","single",3005533841,"[NULL]"
+6,"metadata","cr-triggered_rule_name_hash","single",1595654158,"[NULL]"
+7,"metadata","trace_size_bytes","single",64,"[NULL]"
+8,"metadata","trace_type","single","[NULL]","proto"
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index c0fdd2c..b9f4ad0 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -339,7 +339,7 @@
for (; it.valid(); it.next()) {
const kind = ASYNC_SLICE_TRACK_KIND;
const rawName = it.name === null ? undefined : it.name;
- const rawParentName = it.parentName === null ? undefined : it.name;
+ const rawParentName = it.parentName === null ? undefined : it.parentName;
const name = TrackDecider.getTrackName({name: rawName, kind});
const rawTrackIds = it.trackIds;
const trackIds = rawTrackIds.split(',').map((v) => Number(v));