Merge "processor: Support pid reuse in ProcessTracker without Start/EndThread"
diff --git a/Android.bp b/Android.bp
index d721882..45bb558 100644
--- a/Android.bp
+++ b/Android.bp
@@ -994,6 +994,10 @@
":perfetto_src_tracing_tracing",
":perfetto_test_test_helper",
],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ ],
export_include_dirs: [
"include",
"include/perfetto/base/build_configs/android_tree",
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index cb35cd0..3440b62 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -85,6 +85,7 @@
"PERFETTO_TP_JSON_IMPORT=$enable_perfetto_trace_processor_json_import",
"PERFETTO_TP_FUCHSIA=$enable_perfetto_trace_processor_fuchsia",
"PERFETTO_LOCAL_SYMBOLIZER=$perfetto_local_symbolizer",
+ "PERFETTO_ZLIB=$enable_perfetto_zlib",
]
rel_out_path = rebase_path(gen_header_path, "$root_build_dir")
@@ -306,7 +307,7 @@
}
# Zlib is used both by trace_processor and by perfetto_cmd.
-if (enable_perfetto_trace_processor || enable_perfetto_platform_services) {
+if (enable_perfetto_zlib) {
group("zlib") {
if (perfetto_root_path == "//") {
public_configs = [ "//buildtools:zlib_config" ]
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index b479435..563db03 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -223,6 +223,11 @@
# Further per-OS conditionals are applied in gn/BUILD.gn.
enable_perfetto_trace_processor_httpd =
enable_perfetto_trace_processor && perfetto_build_standalone
+
+ # Enables Zlib support. This is used both by the "perfetto" cmdline client
+ # (for compressing traces) and by trace processor (for compressed traces).
+ enable_perfetto_zlib =
+ enable_perfetto_trace_processor || enable_perfetto_platform_services
}
declare_args() {
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index 0c77eca..c52b7c1 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -20,6 +20,7 @@
cflags = [
"-Wall",
"-Wextra",
+ "-Wpedantic",
]
# Disable Weverything on fuzzers to avoid breakages when new versions of clang
diff --git a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
index 259721b..dbc68b7 100644
--- a/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/android_tree/perfetto_build_flags.h
@@ -39,6 +39,7 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON_IMPORT() (0)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FUCHSIA() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX())
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
// clang-format on
#endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
index 7919b4d..ce91468 100644
--- a/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
+++ b/include/perfetto/base/build_configs/bazel/perfetto_build_flags.h
@@ -39,6 +39,7 @@
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON_IMPORT() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_FUCHSIA() (1)
#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX())
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1)
// clang-format on
#endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
diff --git a/include/perfetto/base/logging.h b/include/perfetto/base/logging.h
index 2691438..aeebf0b 100644
--- a/include/perfetto/base/logging.h
+++ b/include/perfetto/base/logging.h
@@ -24,6 +24,9 @@
#include "perfetto/base/compiler.h"
#include "perfetto/base/export.h"
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+
// TODO(primiano): move this to base/build_config.h, turn into
// PERFETTO_BUILDFLAG(DCHECK_IS_ON) and update call sites to use that instead.
#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
diff --git a/include/perfetto/ext/base/unix_socket.h b/include/perfetto/ext/base/unix_socket.h
index a0dac27..07e0f58 100644
--- a/include/perfetto/ext/base/unix_socket.h
+++ b/include/perfetto/ext/base/unix_socket.h
@@ -48,9 +48,7 @@
class UnixSocketRaw {
public:
// Creates a new unconnected unix socket.
- static UnixSocketRaw CreateMayFail(SockFamily family, SockType type) {
- return UnixSocketRaw(family, type);
- }
+ static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
// Crates a pair of connected sockets.
static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePair(SockFamily,
diff --git a/include/perfetto/ext/base/utils.h b/include/perfetto/ext/base/utils.h
index f7bfdcd..aadded6 100644
--- a/include/perfetto/ext/base/utils.h
+++ b/include/perfetto/ext/base/utils.h
@@ -28,13 +28,13 @@
#endif
#define PERFETTO_EINTR(x) \
- ({ \
+ ([&] { \
decltype(x) eintr_wrapper_result; \
do { \
eintr_wrapper_result = (x); \
} while (eintr_wrapper_result == -1 && errno == EINTR); \
- eintr_wrapper_result; \
- })
+ return eintr_wrapper_result; \
+ }())
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// TODO(brucedawson) - create a ::perfetto::base::IOSize to replace this.
diff --git a/include/perfetto/tracing/data_source.h b/include/perfetto/tracing/data_source.h
index e283737..1a2f57e 100644
--- a/include/perfetto/tracing/data_source.h
+++ b/include/perfetto/tracing/data_source.h
@@ -453,12 +453,20 @@
} // namespace perfetto
-// Not needed -- only here for backwards compatibility.
-// TODO(skyostil): Remove this macro.
-#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...)
+// If placed at the end of a macro declaration, eats the semicolon at the end of
+// the macro invocation (e.g., "MACRO(...);") to avoid warnings about extra
+// semicolons.
+#define PERFETTO_INTERNAL_SWALLOW_SEMICOLON() \
+ extern int perfetto_internal_unused
// Not needed -- only here for backwards compatibility.
// TODO(skyostil): Remove this macro.
-#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...)
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...) \
+ PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Not needed -- only here for backwards compatibility.
+// TODO(skyostil): Remove this macro.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...) \
+ PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
#endif // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index f291186..bfe6692 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -25,6 +25,9 @@
#include "perfetto/tracing/internal/track_event_data_source.h"
#include "perfetto/tracing/track_event_category_registry.h"
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+
// Defines data structures for backing a category registry.
//
// Each category has one enabled/disabled bit per possible data source instance.
diff --git a/include/perfetto/tracing/track_event.h b/include/perfetto/tracing/track_event.h
index 95c2923..3d8e02f 100644
--- a/include/perfetto/tracing/track_event.h
+++ b/include/perfetto/tracing/track_event.h
@@ -138,14 +138,19 @@
PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__) \
/* The track event data source for this set of categories */ \
PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(); \
- } // namespace PERFETTO_TRACK_EVENT_NAMESPACE
+ } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */ \
+ PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
// Allocate storage for each category by using this macro once per track event
// namespace.
-#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
- namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
- PERFETTO_INTERNAL_CATEGORY_STORAGE() \
- } // namespace PERFETTO_TRACK_EVENT_NAMESPACE
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+ namespace PERFETTO_TRACK_EVENT_NAMESPACE { \
+ PERFETTO_INTERNAL_CATEGORY_STORAGE() \
+ } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */ \
+ PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
// Begin a slice under |category| with the title |name|. Both strings must be
// static constants. The track event is only recorded if |category| is enabled
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index c786391..53681bc 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -95,6 +95,7 @@
deps = [
":base",
"../../gn:default_deps",
+ "../../gn:gtest_and_gmock",
]
sources = [
"test/utils.cc",
diff --git a/src/base/task_runner_unittest.cc b/src/base/task_runner_unittest.cc
index a8368b5..10f047b 100644
--- a/src/base/task_runner_unittest.cc
+++ b/src/base/task_runner_unittest.cc
@@ -30,16 +30,11 @@
namespace base {
namespace {
-template <typename T>
class TaskRunnerTest : public ::testing::Test {
public:
- T task_runner;
+ UnixTaskRunner task_runner;
};
-using TaskRunnerTypes = ::testing::Types<UnixTaskRunner>;
-
-TYPED_TEST_SUITE(TaskRunnerTest, TaskRunnerTypes);
-
struct TestPipe : Pipe {
TestPipe() : Pipe(Pipe::Create()) {
// Make the pipe initially readable.
@@ -59,7 +54,7 @@
}
};
-TYPED_TEST(TaskRunnerTest, PostImmediateTask) {
+TEST_F(TaskRunnerTest, PostImmediateTask) {
auto& task_runner = this->task_runner;
int counter = 0;
task_runner.PostTask([&counter] { counter = (counter << 4) | 1; });
@@ -71,7 +66,7 @@
EXPECT_EQ(0x1234, counter);
}
-TYPED_TEST(TaskRunnerTest, PostDelayedTask) {
+TEST_F(TaskRunnerTest, PostDelayedTask) {
auto& task_runner = this->task_runner;
int counter = 0;
task_runner.PostDelayedTask([&counter] { counter = (counter << 4) | 1; }, 5);
@@ -83,7 +78,7 @@
EXPECT_EQ(0x1234, counter);
}
-TYPED_TEST(TaskRunnerTest, PostImmediateTaskFromTask) {
+TEST_F(TaskRunnerTest, PostImmediateTaskFromTask) {
auto& task_runner = this->task_runner;
task_runner.PostTask([&task_runner] {
task_runner.PostTask([&task_runner] { task_runner.Quit(); });
@@ -91,7 +86,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, PostDelayedTaskFromTask) {
+TEST_F(TaskRunnerTest, PostDelayedTaskFromTask) {
auto& task_runner = this->task_runner;
task_runner.PostTask([&task_runner] {
task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
@@ -99,7 +94,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, PostImmediateTaskFromOtherThread) {
+TEST_F(TaskRunnerTest, PostImmediateTaskFromOtherThread) {
auto& task_runner = this->task_runner;
ThreadChecker thread_checker;
int counter = 0;
@@ -118,7 +113,7 @@
EXPECT_EQ(0x1234, counter);
}
-TYPED_TEST(TaskRunnerTest, PostDelayedTaskFromOtherThread) {
+TEST_F(TaskRunnerTest, PostDelayedTaskFromOtherThread) {
auto& task_runner = this->task_runner;
std::thread thread([&task_runner] {
task_runner.PostDelayedTask([&task_runner] { task_runner.Quit(); }, 10);
@@ -127,7 +122,7 @@
thread.join();
}
-TYPED_TEST(TaskRunnerTest, AddFileDescriptorWatch) {
+TEST_F(TaskRunnerTest, AddFileDescriptorWatch) {
auto& task_runner = this->task_runner;
TestPipe pipe;
task_runner.AddFileDescriptorWatch(pipe.rd.get(),
@@ -135,7 +130,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, RemoveFileDescriptorWatch) {
+TEST_F(TaskRunnerTest, RemoveFileDescriptorWatch) {
auto& task_runner = this->task_runner;
TestPipe pipe;
@@ -149,7 +144,7 @@
EXPECT_FALSE(watch_ran);
}
-TYPED_TEST(TaskRunnerTest, RemoveFileDescriptorWatchFromTask) {
+TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromTask) {
auto& task_runner = this->task_runner;
TestPipe pipe;
@@ -165,7 +160,7 @@
EXPECT_FALSE(watch_ran);
}
-TYPED_TEST(TaskRunnerTest, AddFileDescriptorWatchFromAnotherWatch) {
+TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherWatch) {
auto& task_runner = this->task_runner;
TestPipe pipe;
TestPipe pipe2;
@@ -179,7 +174,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, RemoveFileDescriptorWatchFromAnotherWatch) {
+TEST_F(TaskRunnerTest, RemoveFileDescriptorWatchFromAnotherWatch) {
auto& task_runner = this->task_runner;
TestPipe pipe;
TestPipe pipe2;
@@ -198,7 +193,7 @@
EXPECT_FALSE(watch_ran);
}
-TYPED_TEST(TaskRunnerTest, ReplaceFileDescriptorWatchFromAnotherWatch) {
+TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromAnotherWatch) {
auto& task_runner = this->task_runner;
TestPipe pipe;
TestPipe pipe2;
@@ -216,7 +211,7 @@
EXPECT_FALSE(watch_ran);
}
-TYPED_TEST(TaskRunnerTest, AddFileDescriptorWatchFromAnotherThread) {
+TEST_F(TaskRunnerTest, AddFileDescriptorWatchFromAnotherThread) {
auto& task_runner = this->task_runner;
TestPipe pipe;
@@ -228,7 +223,7 @@
thread.join();
}
-TYPED_TEST(TaskRunnerTest, FileDescriptorWatchWithMultipleEvents) {
+TEST_F(TaskRunnerTest, FileDescriptorWatchWithMultipleEvents) {
auto& task_runner = this->task_runner;
TestPipe pipe;
@@ -246,7 +241,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, FileDescriptorClosedEvent) {
+TEST_F(TaskRunnerTest, FileDescriptorClosedEvent) {
auto& task_runner = this->task_runner;
TestPipe pipe;
pipe.wr.reset();
@@ -255,7 +250,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, PostManyDelayedTasks) {
+TEST_F(TaskRunnerTest, PostManyDelayedTasks) {
// Check that PostTask doesn't start failing if there are too many scheduled
// wake-ups.
auto& task_runner = this->task_runner;
@@ -265,7 +260,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, RunAgain) {
+TEST_F(TaskRunnerTest, RunAgain) {
auto& task_runner = this->task_runner;
int counter = 0;
task_runner.PostTask([&task_runner, &counter] {
@@ -281,31 +276,28 @@
EXPECT_EQ(2, counter);
}
-template <typename TaskRunner>
-void RepeatingTask(TaskRunner* task_runner) {
- task_runner->PostTask(std::bind(&RepeatingTask<TaskRunner>, task_runner));
+void RepeatingTask(UnixTaskRunner* task_runner) {
+ task_runner->PostTask(std::bind(&RepeatingTask, task_runner));
}
-TYPED_TEST(TaskRunnerTest, FileDescriptorWatchesNotStarved) {
+TEST_F(TaskRunnerTest, FileDescriptorWatchesNotStarved) {
auto& task_runner = this->task_runner;
TestPipe pipe;
- task_runner.PostTask(std::bind(&RepeatingTask<TypeParam>, &task_runner));
+ task_runner.PostTask(std::bind(&RepeatingTask, &task_runner));
task_runner.AddFileDescriptorWatch(pipe.rd.get(),
[&task_runner] { task_runner.Quit(); });
task_runner.Run();
}
-template <typename TaskRunner>
-void CountdownTask(TaskRunner* task_runner, int* counter) {
+void CountdownTask(UnixTaskRunner* task_runner, int* counter) {
if (!--(*counter)) {
task_runner->Quit();
return;
}
- task_runner->PostTask(
- std::bind(&CountdownTask<TaskRunner>, task_runner, counter));
+ task_runner->PostTask(std::bind(&CountdownTask, task_runner, counter));
}
-TYPED_TEST(TaskRunnerTest, NoDuplicateFileDescriptorWatchCallbacks) {
+TEST_F(TaskRunnerTest, NoDuplicateFileDescriptorWatchCallbacks) {
auto& task_runner = this->task_runner;
TestPipe pipe;
bool watch_called = 0;
@@ -315,12 +307,11 @@
pipe.Read();
watch_called = true;
});
- task_runner.PostTask(
- std::bind(&CountdownTask<TypeParam>, &task_runner, &counter));
+ task_runner.PostTask(std::bind(&CountdownTask, &task_runner, &counter));
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, ReplaceFileDescriptorWatchFromOtherThread) {
+TEST_F(TaskRunnerTest, ReplaceFileDescriptorWatchFromOtherThread) {
auto& task_runner = this->task_runner;
TestPipe pipe;
@@ -339,7 +330,7 @@
thread.join();
}
-TYPED_TEST(TaskRunnerTest, IsIdleForTesting) {
+TEST_F(TaskRunnerTest, IsIdleForTesting) {
auto& task_runner = this->task_runner;
task_runner.PostTask(
[&task_runner] { EXPECT_FALSE(task_runner.IsIdleForTesting()); });
@@ -350,7 +341,7 @@
task_runner.Run();
}
-TYPED_TEST(TaskRunnerTest, RunsTasksOnCurrentThread) {
+TEST_F(TaskRunnerTest, RunsTasksOnCurrentThread) {
auto& main_tr = this->task_runner;
EXPECT_TRUE(main_tr.RunsTasksOnCurrentThread());
diff --git a/src/base/test/benchmark_main.cc b/src/base/test/benchmark_main.cc
index e410e52..3a3feaa 100644
--- a/src/base/test/benchmark_main.cc
+++ b/src/base/test/benchmark_main.cc
@@ -14,4 +14,4 @@
#include <benchmark/benchmark.h>
-BENCHMARK_MAIN();
+BENCHMARK_MAIN()
diff --git a/src/base/test/utils.h b/src/base/test/utils.h
index 673362a..a064fa2 100644
--- a/src/base/test/utils.h
+++ b/src/base/test/utils.h
@@ -20,6 +20,7 @@
#include <string>
#include "perfetto/base/logging.h"
+#include "test/gtest_and_gmock.h"
#if PERFETTO_DCHECK_IS_ON()
@@ -30,11 +31,20 @@
#else // PERFETTO_DCHECK_IS_ON()
+// Since PERFETTO_DCHECK_IS_ON() is false these statements should not die (if
+// they should/do we should use EXPECT/ASSERT DEATH_TEST_IF_SUPPORTED directly).
+// Therefore if the platform supports DEATH_TESTS we can use the handy
+// GTEST_EXECUTE_STATEMENT_ which prevents optimizing the code away, and if not
+// we just fall back on executing the code directly.
+#if GTEST_HAS_DEATH_TEST
#define EXPECT_DCHECK_DEATH(statement) \
GTEST_EXECUTE_STATEMENT_(statement, "PERFETTO_CHECK")
#define ASSERT_DCHECK_DEATH(statement) \
GTEST_EXECUTE_STATEMENT_(statement, "PERFETTO_CHECK")
-
+#else
+#define EXPECT_DCHECK_DEATH(statement) statement
+#define ASSERT_DCHECK_DEATH(statement) statement
+#endif // GTEST_HAS_DEATH_TEST
#endif // PERFETTO_DCHECK_IS_ON()
namespace perfetto {
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index e63f978..f6db62a 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -172,6 +172,15 @@
}
// static
+UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
+ auto fd = ScopedFile(socket(GetSockFamily(family), GetSockType(type), 0));
+ if (!fd) {
+ return UnixSocketRaw();
+ }
+ return UnixSocketRaw(std::move(fd), family, type);
+}
+
+// static
std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePair(
SockFamily family,
SockType type) {
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index 969b732..6e920a9 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -61,7 +61,6 @@
":perfetto_atoms",
":trigger_producer",
"../../gn:default_deps",
- "../../gn:zlib",
"../../protos/perfetto/common:cpp",
"../../protos/perfetto/config:cpp",
"../../protos/perfetto/config/ftrace:cpp",
@@ -70,6 +69,9 @@
"../protozero",
"../tracing:ipc",
]
+ if (enable_perfetto_zlib) {
+ deps += [ "../../gn:zlib" ]
+ }
sources = [
"config.cc",
"config.h",
@@ -131,7 +133,6 @@
":perfetto_cmd",
"../../gn:default_deps",
"../../gn:gtest_and_gmock",
- "../../gn:zlib",
"../../include/perfetto/base",
"../../include/perfetto/ext/base",
"../../protos/perfetto/config:cpp",
@@ -139,6 +140,9 @@
"../../protos/perfetto/trace:cpp",
"../tracing",
]
+ if (enable_perfetto_zlib) {
+ deps += [ "../../gn:zlib" ]
+ }
sources = [
"config_unittest.cc",
"packet_writer_unittest.cc",
diff --git a/src/perfetto_cmd/packet_writer.cc b/src/perfetto_cmd/packet_writer.cc
index 9d5a8d6..2fb0562 100644
--- a/src/perfetto_cmd/packet_writer.cc
+++ b/src/perfetto_cmd/packet_writer.cc
@@ -24,13 +24,17 @@
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <zlib.h>
+#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/paged_memory.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
#include "perfetto/protozero/proto_utils.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#endif
+
namespace perfetto {
namespace {
@@ -43,14 +47,20 @@
// ID of the |packet| field in trace.proto. Hardcoded as this we don't
// want to depend on protos/trace:lite for binary size saving reasons.
constexpr uint32_t kPacketId = 1;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
// ID of |compressed_packets| in trace_packet.proto.
constexpr uint32_t kCompressedPacketsId = 50;
// Maximum allowable size for a single packet.
const size_t kMaxPacketSize = 500 * 1024;
+
// After every kPendingBytesLimit we do a Z_SYNC_FLUSH in the zlib stream.
const size_t kPendingBytesLimit = 32 * 1024;
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
template <uint32_t id>
size_t GetPreamble(size_t sz, Preamble* preamble) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(preamble->data());
@@ -73,6 +83,31 @@
FILE* fd_;
};
+FilePacketWriter::FilePacketWriter(FILE* fd) : fd_(fd) {}
+
+FilePacketWriter::~FilePacketWriter() {
+ fflush(fd_);
+}
+
+bool FilePacketWriter::WritePackets(const std::vector<TracePacket>& packets) {
+ for (const TracePacket& packet : packets) {
+ Preamble preamble;
+ size_t size = GetPreamble<kPacketId>(packet.size(), &preamble);
+ if (fwrite(preamble.data(), 1, size, fd_) != size)
+ return false;
+ for (const Slice& slice : packet.slices()) {
+ if (fwrite(reinterpret_cast<const char*>(slice.start), 1, slice.size,
+ fd_) != slice.size) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
class ZipPacketWriter : public PacketWriter {
public:
ZipPacketWriter(std::unique_ptr<PacketWriter>);
@@ -102,29 +137,6 @@
size_t pending_bytes_ = 0;
};
-FilePacketWriter::FilePacketWriter(FILE* fd) : fd_(fd) {}
-
-FilePacketWriter::~FilePacketWriter() {
- fflush(fd_);
-}
-
-bool FilePacketWriter::WritePackets(const std::vector<TracePacket>& packets) {
- for (const TracePacket& packet : packets) {
- Preamble preamble;
- size_t size = GetPreamble<kPacketId>(packet.size(), &preamble);
- if (fwrite(preamble.data(), 1, size, fd_) != size)
- return false;
- for (const Slice& slice : packet.slices()) {
- if (fwrite(reinterpret_cast<const char*>(slice.start), 1, slice.size,
- fd_) != slice.size) {
- return false;
- }
- }
- }
-
- return true;
-}
-
ZipPacketWriter::ZipPacketWriter(std::unique_ptr<PacketWriter> writer)
: writer_(std::move(writer)),
buf_(base::PagedMemory::Allocate(kMaxPacketSize)),
@@ -237,6 +249,8 @@
pending_bytes_ += size;
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
} // namespace
PacketWriter::PacketWriter() {}
@@ -247,9 +261,11 @@
return std::unique_ptr<PacketWriter>(new FilePacketWriter(fd));
}
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
std::unique_ptr<PacketWriter> CreateZipPacketWriter(
std::unique_ptr<PacketWriter> writer) {
return std::unique_ptr<PacketWriter>(new ZipPacketWriter(std::move(writer)));
}
+#endif
} // namespace perfetto
diff --git a/src/perfetto_cmd/packet_writer_unittest.cc b/src/perfetto_cmd/packet_writer_unittest.cc
index c1fab21..fbf9603 100644
--- a/src/perfetto_cmd/packet_writer_unittest.cc
+++ b/src/perfetto_cmd/packet_writer_unittest.cc
@@ -21,8 +21,7 @@
#include <random>
-#include <zlib.h>
-
+#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/temp_file.h"
@@ -34,6 +33,10 @@
#include "protos/perfetto/trace/trace.gen.h"
#include "protos/perfetto/trace/trace_packet.gen.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#endif
+
namespace perfetto {
namespace {
@@ -51,6 +54,7 @@
return packet;
}
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
std::string Decompress(const std::string& data) {
uint8_t out[1024];
@@ -76,6 +80,7 @@
inflateEnd(&stream);
return s;
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
TEST(PacketWriterTest, FilePacketWriter) {
base::TempFile tmp = base::TempFile::Create();
@@ -105,6 +110,8 @@
EXPECT_EQ(trace.packet()[0].for_testing().str(), "abc");
}
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
TEST(PacketWriterTest, ZipPacketWriter) {
base::TempFile tmp = base::TempFile::Create();
base::ScopedResource<FILE*, fclose, nullptr> f(
@@ -281,5 +288,7 @@
EXPECT_EQ(packet_count, 1000u);
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
} // namespace
} // namespace perfetto
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 638112f..bb48f6f 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -603,7 +603,11 @@
if (trace_config_->compression_type() ==
TraceConfig::COMPRESSION_TYPE_DEFLATE) {
if (packet_writer_) {
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
packet_writer_ = CreateZipPacketWriter(std::move(packet_writer_));
+#else
+ PERFETTO_ELOG("Cannot compress. Zlib not enabled in the build config");
+#endif
} else {
PERFETTO_ELOG("Cannot compress when tracing directly to file.");
}
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 0455917..ebabeb3 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -88,8 +88,6 @@
"ftrace_utils.h",
"global_args_tracker.cc",
"global_args_tracker.h",
- "gzip_trace_parser.cc",
- "gzip_trace_parser.h",
"heap_profile_tracker.cc",
"heap_profile_tracker.h",
"importers/ftrace/ftrace_module.cc",
@@ -140,11 +138,9 @@
"track_tracker.h",
"virtual_destructors.cc",
]
-
deps = [
":descriptors",
"../../gn:default_deps",
- "../../gn:zlib",
"../base",
"../protozero",
"containers",
@@ -167,6 +163,13 @@
"../../protos/perfetto/trace/sys_stats:zero",
"../../protos/perfetto/trace/track_event:zero",
]
+ if (enable_perfetto_zlib) {
+ sources += [
+ "gzip_trace_parser.cc",
+ "gzip_trace_parser.h",
+ ]
+ deps += [ "../../gn:zlib" ]
+ }
if (enable_perfetto_trace_processor_json_import) {
sources += [
"importers/json/json_trace_parser.cc",
diff --git a/src/trace_processor/containers/string_pool.cc b/src/trace_processor/containers/string_pool.cc
index 167d285..ac45ceb 100644
--- a/src/trace_processor/containers/string_pool.cc
+++ b/src/trace_processor/containers/string_pool.cc
@@ -81,7 +81,7 @@
// Compute the id from the block index and offset and add a mapping from the
// hash to the id.
- Id string_id = BlockIndexAndOffsetToId(blocks_.size() - 1, offset);
+ Id string_id = Id::BlockString(blocks_.size() - 1, offset);
string_index_.emplace(hash, string_id);
return string_id;
}
@@ -90,7 +90,7 @@
uint64_t hash) {
large_strings_.emplace_back(new std::string(str.begin(), str.size()));
// Compute id from the index and add a mapping from the hash to the id.
- Id string_id = LargeStringIndexToId(large_strings_.size() - 1);
+ Id string_id = Id::LargeString(large_strings_.size() - 1);
string_index_.emplace(hash, string_id);
return string_id;
}
@@ -172,11 +172,11 @@
// If we're at (0, 0), we have the null string which has id 0.
if (block_index_ == 0 && block_offset_ == 0)
- return 0;
- return BlockIndexAndOffsetToId(block_index_, block_offset_);
+ return Id::Null();
+ return Id::BlockString(block_index_, block_offset_);
}
PERFETTO_DCHECK(large_strings_index_ < pool_->large_strings_.size());
- return LargeStringIndexToId(large_strings_index_);
+ return Id::LargeString(large_strings_index_);
}
} // namespace trace_processor
diff --git a/src/trace_processor/containers/string_pool.h b/src/trace_processor/containers/string_pool.h
index 0f50bcc..154bfb2 100644
--- a/src/trace_processor/containers/string_pool.h
+++ b/src/trace_processor/containers/string_pool.h
@@ -37,7 +37,6 @@
public:
struct Id {
Id() = default;
- constexpr Id(uint32_t i) : id(i) {}
bool operator==(const Id& other) const { return other.id == id; }
bool operator!=(const Id& other) const { return !(other == *this); }
@@ -45,6 +44,42 @@
bool is_null() const { return id == 0u; }
+ bool is_large_string() const { return id & kLargeStringFlagBitMask; }
+
+ uint32_t block_offset() const { return id & kBlockOffsetBitMask; }
+
+ uint32_t block_index() const {
+ return (id & kBlockIndexBitMask) >> kNumBlockOffsetBits;
+ }
+
+ uint32_t large_string_index() const {
+ PERFETTO_DCHECK(is_large_string());
+ return id & ~kLargeStringFlagBitMask;
+ }
+
+ uint32_t raw_id() const { return id; }
+
+ static Id LargeString(size_t index) {
+ PERFETTO_DCHECK(index <= static_cast<uint32_t>(index));
+ PERFETTO_DCHECK(!(index & kLargeStringFlagBitMask));
+ return Id(kLargeStringFlagBitMask | static_cast<uint32_t>(index));
+ }
+
+ static Id BlockString(size_t index, uint32_t offset) {
+ PERFETTO_DCHECK(index < (1u << (kNumBlockIndexBits + 1)));
+ PERFETTO_DCHECK(offset < (1u << (kNumBlockOffsetBits + 1)));
+ return Id(~kLargeStringFlagBitMask &
+ (static_cast<uint32_t>(index << kNumBlockOffsetBits) |
+ (offset & kBlockOffsetBitMask)));
+ }
+
+ static constexpr Id Raw(uint32_t raw) { return Id(raw); }
+
+ static constexpr Id Null() { return Id(0u); }
+
+ private:
+ constexpr Id(uint32_t i) : id(i) {}
+
uint32_t id;
};
@@ -79,7 +114,7 @@
Id InternString(base::StringView str) {
if (str.data() == nullptr)
- return Id(0);
+ return Id::Null();
auto hash = str.Hash();
auto id_it = string_index_.find(hash);
@@ -92,7 +127,7 @@
base::Optional<Id> GetId(base::StringView str) const {
if (str.data() == nullptr)
- return Id(0u);
+ return Id::Null();
auto hash = str.Hash();
auto id_it = string_index_.find(hash);
@@ -104,9 +139,9 @@
}
NullTermStringView Get(Id id) const {
- if (id.id == 0)
+ if (id.is_null())
return NullTermStringView();
- if (id.id & kLargeStringFlagBitMask)
+ if (id.is_large_string())
return GetLargeString(id);
return GetFromBlockPtr(IdToPtr(id));
}
@@ -199,10 +234,10 @@
const uint8_t* IdToPtr(Id id) const {
// If the MSB is set, the ID represents an index into |large_strings_|, so
// shouldn't be converted into a block pointer.
- PERFETTO_DCHECK(!(id.id & kLargeStringFlagBitMask));
+ PERFETTO_DCHECK(!id.is_large_string());
- size_t block_index = (id.id & kBlockIndexBitMask) >> kNumBlockOffsetBits;
- uint32_t block_offset = id.id & kBlockOffsetBitMask;
+ size_t block_index = id.block_index();
+ uint32_t block_offset = id.block_offset();
PERFETTO_DCHECK(block_index < blocks_.size());
PERFETTO_DCHECK(block_offset < blocks_[block_index].pos());
@@ -210,20 +245,6 @@
return blocks_[block_index].Get(block_offset);
}
- static Id BlockIndexAndOffsetToId(size_t index, uint32_t offset) {
- PERFETTO_DCHECK(index < (1u << (kNumBlockIndexBits + 1)));
- PERFETTO_DCHECK(offset < (1u << (kNumBlockOffsetBits + 1)));
- return Id(~kLargeStringFlagBitMask &
- (static_cast<uint32_t>(index << kNumBlockOffsetBits) |
- (offset & kBlockOffsetBitMask)));
- }
-
- static Id LargeStringIndexToId(size_t index) {
- PERFETTO_DCHECK(index <= static_cast<uint32_t>(index) &&
- !(index & kLargeStringFlagBitMask));
- return Id(kLargeStringFlagBitMask | static_cast<uint32_t>(index));
- }
-
// |ptr| should point to the start of the string metadata (i.e. the first byte
// of the size).
// Returns pointer to the start of the string.
@@ -248,8 +269,8 @@
// Lookup a string in the |large_strings_| vector. |id| should have the MSB
// set.
NullTermStringView GetLargeString(Id id) const {
- PERFETTO_DCHECK(id.id & kLargeStringFlagBitMask);
- size_t index = id.id & ~kLargeStringFlagBitMask;
+ PERFETTO_DCHECK(id.is_large_string());
+ size_t index = id.large_string_index();
PERFETTO_DCHECK(index < large_strings_.size());
const std::string* str = large_strings_[index].get();
return NullTermStringView(str->c_str(), str->size());
@@ -280,7 +301,7 @@
using result_type = size_t;
result_type operator()(const argument_type& r) const {
- return std::hash<uint32_t>{}(r.id);
+ return std::hash<uint32_t>{}(r.raw_id());
}
};
diff --git a/src/trace_processor/containers/string_pool_unittest.cc b/src/trace_processor/containers/string_pool_unittest.cc
index 37d85d8..eb6dc1b 100644
--- a/src/trace_processor/containers/string_pool_unittest.cc
+++ b/src/trace_processor/containers/string_pool_unittest.cc
@@ -27,8 +27,6 @@
class StringPoolTest : public testing::Test {
protected:
static constexpr size_t kNumBlockOffsetBits = StringPool::kNumBlockOffsetBits;
- static constexpr size_t kLargeStringFlagBitMask =
- StringPool::kLargeStringFlagBitMask;
static constexpr size_t kBlockIndexBitMask = StringPool::kBlockIndexBitMask;
static constexpr size_t kBlockSizeBytes = StringPool::kBlockSizeBytes;
static constexpr size_t kMinLargeStringSizeBytes =
@@ -40,7 +38,7 @@
namespace {
TEST_F(StringPoolTest, EmptyPool) {
- ASSERT_EQ(pool_.Get(0).c_str(), nullptr);
+ ASSERT_EQ(pool_.Get(StringPool::Id::Null()).c_str(), nullptr);
auto it = pool_.CreateIterator();
ASSERT_TRUE(it);
@@ -58,7 +56,7 @@
TEST_F(StringPoolTest, NullPointerHandling) {
auto id = pool_.InternString(NullTermStringView());
- ASSERT_EQ(id, 0u);
+ ASSERT_TRUE(id.is_null());
ASSERT_EQ(pool_.Get(id).c_str(), nullptr);
}
@@ -122,7 +120,7 @@
auto it_pair = string_map.equal_range(it.StringId());
for (auto in_it = it_pair.first; in_it != it_pair.second; ++in_it) {
ASSERT_EQ(it.StringView(), in_it->second)
- << it.StringId().id << ": " << it.StringView().Hash() << " vs "
+ << it.StringId().raw_id() << ": " << it.StringView().Hash() << " vs "
<< in_it->second.Hash();
}
string_map.erase(it_pair.first, it_pair.second);
@@ -178,21 +176,21 @@
big_strings[i].get(), kStringSizes[i])));
}
- ASSERT_FALSE(string_ids[0].id & kLargeStringFlagBitMask);
- ASSERT_FALSE(string_ids[1].id & kLargeStringFlagBitMask);
- ASSERT_TRUE(string_ids[2].id & kLargeStringFlagBitMask);
- ASSERT_FALSE(string_ids[3].id & kLargeStringFlagBitMask);
- ASSERT_FALSE(string_ids[4].id & kLargeStringFlagBitMask);
- ASSERT_FALSE(string_ids[5].id & kLargeStringFlagBitMask);
- ASSERT_TRUE(string_ids[6].id & kLargeStringFlagBitMask);
- ASSERT_FALSE(string_ids[7].id & kLargeStringFlagBitMask);
+ ASSERT_FALSE(string_ids[0].is_large_string());
+ ASSERT_FALSE(string_ids[1].is_large_string());
+ ASSERT_TRUE(string_ids[2].is_large_string());
+ ASSERT_FALSE(string_ids[3].is_large_string());
+ ASSERT_FALSE(string_ids[4].is_large_string());
+ ASSERT_FALSE(string_ids[5].is_large_string());
+ ASSERT_TRUE(string_ids[6].is_large_string());
+ ASSERT_FALSE(string_ids[7].is_large_string());
- ASSERT_EQ(string_ids[0].id & kBlockIndexBitMask, 0u << kNumBlockOffsetBits);
- ASSERT_EQ(string_ids[1].id & kBlockIndexBitMask, 0u << kNumBlockOffsetBits);
- ASSERT_EQ(string_ids[3].id & kBlockIndexBitMask, 0u << kNumBlockOffsetBits);
- ASSERT_EQ(string_ids[4].id & kBlockIndexBitMask, 0u << kNumBlockOffsetBits);
- ASSERT_EQ(string_ids[5].id & kBlockIndexBitMask, 1u << kNumBlockOffsetBits);
- ASSERT_EQ(string_ids[7].id & kBlockIndexBitMask, 1u << kNumBlockOffsetBits);
+ ASSERT_EQ(string_ids[0].block_index(), 0u);
+ ASSERT_EQ(string_ids[1].block_index(), 0u);
+ ASSERT_EQ(string_ids[3].block_index(), 0u);
+ ASSERT_EQ(string_ids[4].block_index(), 0u);
+ ASSERT_EQ(string_ids[5].block_index(), 1u);
+ ASSERT_EQ(string_ids[7].block_index(), 1u);
for (size_t i = 0; i < big_strings.size(); i++) {
ASSERT_EQ(big_strings[i].get(), pool_.Get(string_ids[i]));
diff --git a/src/trace_processor/db/typed_column.h b/src/trace_processor/db/typed_column.h
index a7183f6..9a3dd5e 100644
--- a/src/trace_processor/db/typed_column.h
+++ b/src/trace_processor/db/typed_column.h
@@ -189,7 +189,7 @@
// TODO(lalitm): remove this special casing if we migrate all tables over
// to macro tables and find that we can remove support for null stringids
// in the stringpool.
- return TypedColumn<StringPool::Id>::Append(v ? *v : StringPool::Id(0u));
+ return TypedColumn<StringPool::Id>::Append(v ? *v : StringPool::Id::Null());
}
// Implements equality between two items of type |T|.
diff --git a/src/trace_processor/event_tracker.h b/src/trace_processor/event_tracker.h
index 983dad0..bde0588 100644
--- a/src/trace_processor/event_tracker.h
+++ b/src/trace_processor/event_tracker.h
@@ -76,7 +76,7 @@
// Represents a counter event which is currently pending upid resolution.
struct PendingUpidResolutionCounter {
uint32_t row = 0;
- StringId name_id = 0;
+ StringId name_id = kNullStringId;
UniqueTid utid = 0;
};
diff --git a/src/trace_processor/event_tracker_unittest.cc b/src/trace_processor/event_tracker_unittest.cc
index f4e20cb..d8f41ed 100644
--- a/src/trace_processor/event_tracker_unittest.cc
+++ b/src/trace_processor/event_tracker_unittest.cc
@@ -114,7 +114,7 @@
TEST_F(EventTrackerTest, CounterDuration) {
uint32_t cpu = 3;
int64_t timestamp = 100;
- StringId name_id = 0;
+ StringId name_id = kNullStringId;
TrackId track = context.track_tracker->InternCpuCounterTrack(name_id, cpu);
context.event_tracker->PushCounter(timestamp, 1000, track);
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index c7cf7ab..b1f92f4 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -226,7 +226,7 @@
TEST_F(ExportJsonTest, SystemEventsIgnored) {
constexpr int64_t kCookie = 22;
TrackId track = context_.track_tracker->InternAndroidAsyncTrack(
- /*name=*/0, /*upid=*/0, kCookie);
+ /*name=*/kNullStringId, /*upid=*/0, kCookie);
context_.args_tracker->Flush(); // Flush track args.
// System events have no category.
@@ -794,7 +794,7 @@
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
- /*source_scope=*/0);
+ /*source_scope=*/kNullStringId);
context_.args_tracker->Flush(); // Flush track args.
context_.storage->mutable_slice_table()->Insert(
@@ -885,7 +885,7 @@
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
- /*source_scope=*/0);
+ /*source_scope=*/kNullStringId);
context_.args_tracker->Flush(); // Flush track args.
auto slice_id = context_.storage->mutable_slice_table()->Insert(
@@ -940,7 +940,7 @@
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
- /*source_scope=*/0);
+ /*source_scope=*/kNullStringId);
context_.args_tracker->Flush(); // Flush track args.
auto slice_id = context_.storage->mutable_slice_table()->Insert(
@@ -983,7 +983,7 @@
constexpr int64_t kSourceId = 235;
TrackId track = context_.track_tracker->InternLegacyChromeAsyncTrack(
name_id, upid, kSourceId, /*source_id_is_process_scoped=*/true,
- /*source_scope=*/0);
+ /*source_scope=*/kNullStringId);
context_.args_tracker->Flush(); // Flush track args.
context_.storage->mutable_slice_table()->Insert(
@@ -1174,10 +1174,11 @@
// TODO(140860736): Once we support null values for
// stack_profile_frame.symbol_set_id remove this hack
- storage->mutable_symbol_table()->Insert({0, 0, 0, 0});
+ storage->mutable_symbol_table()->Insert({0, kNullStringId, kNullStringId, 0});
auto* frames = storage->mutable_stack_profile_frame_table();
- auto frame_id_1 = frames->Insert({/*name_id=*/0, module_id_1.value, 0x42});
+ auto frame_id_1 =
+ frames->Insert({/*name_id=*/kNullStringId, module_id_1.value, 0x42});
uint32_t frame_row_1 = *frames->id().IndexOf(frame_id_1);
uint32_t symbol_set_id = storage->symbol_table().row_count();
@@ -1186,7 +1187,8 @@
storage->InternString("foo_file"), 66});
frames->mutable_symbol_set_id()->Set(frame_row_1, symbol_set_id);
- auto frame_id_2 = frames->Insert({/*name_id=*/0, module_id_2.value, 0x4242});
+ auto frame_id_2 =
+ frames->Insert({/*name_id=*/kNullStringId, module_id_2.value, 0x4242});
uint32_t frame_row_2 = *frames->id().IndexOf(frame_id_2);
symbol_set_id = storage->symbol_table().row_count();
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index ea63b8e..89798f2 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -39,6 +39,11 @@
namespace trace_processor {
namespace {
+#if !PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+const char kNoZlibErr[] =
+ "Cannot open compressed trace. zlib not enabled in the build config";
+#endif
+
inline bool isspace(unsigned char c) {
return ::isspace(c);
}
@@ -119,12 +124,20 @@
}
case kGzipTraceType:
PERFETTO_DLOG("gzip trace detected");
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
reader_.reset(new GzipTraceParser(context_));
break;
+#else
+ return util::ErrStatus(kNoZlibErr);
+#endif
case kCtraceTraceType:
PERFETTO_DLOG("ctrace trace detected");
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
reader_.reset(new GzipTraceParser(context_));
break;
+#else
+ return util::ErrStatus(kNoZlibErr);
+#endif
case kUnknownTraceType:
return util::ErrStatus("Unknown trace type provided");
}
diff --git a/src/trace_processor/global_args_tracker.h b/src/trace_processor/global_args_tracker.h
index 09cf9af..74c5152 100644
--- a/src/trace_processor/global_args_tracker.h
+++ b/src/trace_processor/global_args_tracker.h
@@ -31,8 +31,8 @@
class GlobalArgsTracker {
public:
struct Arg {
- StringId flat_key = 0;
- StringId key = 0;
+ StringId flat_key = kNullStringId;
+ StringId key = kNullStringId;
Variadic value = Variadic::Integer(0);
Column* column;
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.h b/src/trace_processor/importers/ftrace/ftrace_parser.h
index 3f5bec5..10eacfe 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.h
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.h
@@ -98,7 +98,7 @@
struct FtraceMessageStrings {
// The string id of name of the event field (e.g. sched_switch's id).
- StringId message_name_id = 0;
+ StringId message_name_id = kNullStringId;
std::array<StringId, kMaxFtraceEventFields> field_name_ids;
};
std::vector<FtraceMessageStrings> ftrace_message_strings_;
@@ -108,9 +108,9 @@
MmEventCounterNames(StringId _count, StringId _max_lat, StringId _avg_lat)
: count(_count), max_lat(_max_lat), avg_lat(_avg_lat) {}
- StringId count = 0;
- StringId max_lat = 0;
- StringId avg_lat = 0;
+ StringId count = kNullStringId;
+ StringId max_lat = kNullStringId;
+ StringId avg_lat = kNullStringId;
};
// Keep kMmEventCounterSize equal to mm_event_type::MM_TYPE_NUM in the kernel.
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index 5d55216..eb58594 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -170,7 +170,7 @@
gpu_counter_track_ids_.end()) {
auto desc = spec.description();
- StringId unit_id = 0;
+ StringId unit_id = kNullStringId;
if (spec.has_numerator_units() || spec.has_denominator_units()) {
char buffer[1024];
base::StringWriter unit(buffer, sizeof(buffer));
@@ -277,7 +277,7 @@
StringId track_name = context_->storage->InternString(hw_queue.name());
if (gpu_hw_queue_counter_ >= gpu_hw_queue_ids_.size() ||
!gpu_hw_queue_ids_[gpu_hw_queue_counter_].has_value()) {
- tables::GpuTrackTable::Row track(track_name.id);
+ tables::GpuTrackTable::Row track(track_name);
track.scope = gpu_render_stage_scope_id_;
track.description = context_->storage->InternString(hw_queue.description());
if (gpu_hw_queue_counter_ >= gpu_hw_queue_ids_.size()) {
@@ -304,7 +304,7 @@
context_->storage->mutable_gpu_track_table()->mutable_description()->Set(
row, context_->storage->InternString(hw_queue.description()));
} else {
- tables::GpuTrackTable::Row track(track_name.id);
+ tables::GpuTrackTable::Row track(track_name);
track.scope = gpu_render_stage_scope_id_;
track.description =
context_->storage->InternString(hw_queue.description());
@@ -426,7 +426,7 @@
}
StringId track_name =
context_->storage->InternString(writer.GetStringView());
- tables::GpuTrackTable::Row track(track_name.id);
+ tables::GpuTrackTable::Row track(track_name);
track.scope = gpu_render_stage_scope_id_;
track_id = context_->track_tracker->InternGpuTrack(track);
gpu_hw_queue_ids_.resize(hw_queue_id + 1);
@@ -508,7 +508,7 @@
const uint32_t frame_number =
event.has_frame_number() ? event.frame_number() : 0;
- tables::GpuTrackTable::Row track(track_name_id.id);
+ tables::GpuTrackTable::Row track(track_name_id);
track.scope = graphics_event_scope_id_;
TrackId track_id = context_->track_tracker->InternGpuTrack(track);
@@ -532,7 +532,7 @@
if (previous_timestamp_ == 0) {
const StringId present_track_name_id =
context_->storage->InternString("Displayed Frame");
- tables::GpuTrackTable::Row present_track(present_track_name_id.id);
+ tables::GpuTrackTable::Row present_track(present_track_name_id);
present_track.scope = graphics_event_scope_id_;
present_track_id_ =
context_->track_tracker->InternGpuTrack(present_track);
@@ -770,7 +770,7 @@
sequence_state,
static_cast<uint64_t>(annotation.string_iid()));
- inserter.AddArg(key_id, Variadic::String(string_id.id));
+ inserter.AddArg(key_id, Variadic::String(string_id));
}
}
}
@@ -779,7 +779,7 @@
void GraphicsEventParser::ParseGpuLog(int64_t ts, ConstBytes blob) {
protos::pbzero::GpuLog::Decoder event(blob.data, blob.size);
- tables::GpuTrackTable::Row track(gpu_log_track_name_id_.id);
+ tables::GpuTrackTable::Row track(gpu_log_track_name_id_);
track.scope = gpu_log_scope_id_;
TrackId track_id = context_->track_tracker->InternGpuTrack(track);
diff --git a/src/trace_processor/importers/proto/heap_graph_tracker.cc b/src/trace_processor/importers/proto/heap_graph_tracker.cc
index 7942263..3c1001f 100644
--- a/src/trace_processor/importers/proto/heap_graph_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_graph_tracker.cc
@@ -121,7 +121,7 @@
sequence_state.object_id_to_row.emplace(obj.object_id, row);
class_to_rows_[type_name].emplace_back(row);
sequence_state.walker.AddNode(row, obj.self_size,
- static_cast<int32_t>(type_name.id));
+ static_cast<int32_t>(type_name.raw_id()));
}
for (const SourceObject& obj : sequence_state.current_objects) {
@@ -230,7 +230,7 @@
tables::StackProfileFrameTable::Row row{};
PERFETTO_CHECK(node.class_name > 0);
- row.name = StringId(static_cast<uint32_t>(node.class_name));
+ row.name = StringId::Raw(static_cast<uint32_t>(node.class_name));
row.mapping = mapping_row;
auto id =
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index ce48d17..b2b852f 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -174,7 +174,8 @@
context->storage->InternString("chrome_event.legacy_user_trace")) {
// TODO(140860736): Once we support null values for
// stack_profile_frame.symbol_set_id remove this hack
- context_->storage->mutable_symbol_table()->Insert({0, 0, 0, 0});
+ context_->storage->mutable_symbol_table()->Insert(
+ {0, kNullStringId, kNullStringId, 0});
}
ProtoTraceParser::~ProtoTraceParser() = default;
@@ -455,7 +456,8 @@
int64_t callstack_id = *maybe_callstack_id;
tables::CpuProfileStackSampleTable::Row sample_row{
- sequence_state->state()->IncrementAndGetTrackEventTimeNs(*timestamp_it),
+ sequence_state->state()->IncrementAndGetTrackEventTimeNs(*timestamp_it *
+ 1000),
callstack_id, utid};
storage->mutable_cpu_profile_stack_sample_table()->Insert(sample_row);
}
@@ -575,7 +577,7 @@
auto utid = context_->process_tracker->GetOrCreateThread(event.thread_id());
StringId cat_id = metatrace_id_;
- StringId name_id = 0;
+ StringId name_id = kNullStringId;
char fallback[64];
if (event.has_event_id()) {
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 c6b789d..adb1a2e 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_unittest.cc
@@ -155,25 +155,6 @@
void(UniquePid upid, StringId process_name_id));
};
-// Mock trace storage that behaves like the real implementation, but allows for
-// the interactions with string interning/lookup to be overridden/inspected.
-class MockTraceStorage : public TraceStorage {
- public:
- MockTraceStorage() : TraceStorage() {
- ON_CALL(*this, InternString(_))
- .WillByDefault(Invoke([this](base::StringView str) {
- return TraceStorage::InternString(str);
- }));
-
- ON_CALL(*this, GetString(_)).WillByDefault(Invoke([this](StringId id) {
- return TraceStorage::GetString(id);
- }));
- }
-
- MOCK_METHOD1(InternString, StringId(base::StringView));
- MOCK_CONST_METHOD1(GetString, NullTermStringView(StringId));
-};
-
class MockBoundInserter : public ArgsTracker::BoundInserter {
public:
MockBoundInserter() : ArgsTracker::BoundInserter(nullptr, nullptr, 0u) {
@@ -214,7 +195,7 @@
class ProtoTraceParserTest : public ::testing::Test {
public:
ProtoTraceParserTest() {
- storage_ = new NiceMock<MockTraceStorage>();
+ storage_ = new TraceStorage();
context_.storage.reset(storage_);
context_.track_tracker.reset(new TrackTracker(&context_));
context_.global_args_tracker.reset(new GlobalArgsTracker(&context_));
@@ -285,7 +266,7 @@
MockProcessTracker* process_;
MockSliceTracker* slice_;
ClockTracker* clock_;
- NiceMock<MockTraceStorage>* storage_;
+ TraceStorage* storage_;
};
// TODO(eseckler): Refactor these into a new file for ftrace tests.
@@ -388,12 +369,6 @@
field->set_name("meta3");
field->set_uint_value(3);
- EXPECT_CALL(*storage_, InternString(base::StringView("Test")));
- EXPECT_CALL(*storage_, InternString(base::StringView("meta1")));
- EXPECT_CALL(*storage_, InternString(base::StringView("value1")));
- EXPECT_CALL(*storage_, InternString(base::StringView("meta2")));
- EXPECT_CALL(*storage_, InternString(base::StringView("meta3")));
-
Tokenize();
const auto& raw = storage_->raw_table();
@@ -402,18 +377,23 @@
ASSERT_EQ(raw.ts()[raw.row_count() - 1], 100);
ASSERT_EQ(storage_->thread_table().tid()[raw.utid()[raw.row_count() - 1]],
10u);
+ ASSERT_EQ(raw.name().GetString(raw.row_count() - 1), "Test");
auto set_id = raw.arg_set_id()[raw.row_count() - 1];
const auto& args = storage_->arg_table();
RowMap rm = args.FilterToRowMap({args.arg_set_id().eq(set_id)});
- // Ignore string calls as they are handled by checking InternString calls
- // above.
-
auto row = rm.Get(0);
- ASSERT_EQ(args.int_value()[++row], -2);
- ASSERT_EQ(args.int_value()[++row], 3);
+
+ ASSERT_EQ(args.key().GetString(row), "meta1");
+ ASSERT_EQ(args.string_value().GetString(row++), "value1");
+
+ ASSERT_EQ(args.key().GetString(row), "meta2");
+ ASSERT_EQ(args.int_value()[row++], -2);
+
+ ASSERT_EQ(args.key().GetString(row), "meta3");
+ ASSERT_EQ(args.int_value()[row++], 3);
}
TEST_F(ProtoTraceParserTest, LoadMultipleEvents) {
@@ -667,16 +647,14 @@
.WillRepeatedly(testing::Return(1u));
EXPECT_CALL(*process_, GetOrCreateProcess(16)).WillOnce(testing::Return(2u));
- EXPECT_CALL(*storage_, InternString(base::StringView("OldProcessName")))
- .WillOnce(Return(1));
- EXPECT_CALL(*process_, SetProcessNameIfUnset(1u, StringId(1)));
+ EXPECT_CALL(*process_, SetProcessNameIfUnset(
+ 1u, storage_->InternString("OldProcessName")));
// Packet with same thread, but different name should update the name.
- EXPECT_CALL(*storage_, InternString(base::StringView("NewProcessName")))
- .WillOnce(Return(2));
- EXPECT_CALL(*process_, SetProcessNameIfUnset(1u, StringId(2)));
- EXPECT_CALL(*storage_, InternString(base::StringView("DifferentProcessName")))
- .WillOnce(Return(3));
- EXPECT_CALL(*process_, SetProcessNameIfUnset(2u, StringId(3)));
+ EXPECT_CALL(*process_, SetProcessNameIfUnset(
+ 1u, storage_->InternString("NewProcessName")));
+ EXPECT_CALL(*process_,
+ SetProcessNameIfUnset(
+ 2u, storage_->InternString("DifferentProcessName")));
Tokenize();
context_.sorter->ExtractEventsForced();
@@ -723,16 +701,14 @@
.WillRepeatedly(testing::Return(1u));
EXPECT_CALL(*process_, UpdateThread(11, 15)).WillOnce(testing::Return(2u));
- EXPECT_CALL(*storage_, InternString(base::StringView("OldThreadName")))
- .WillOnce(Return(1));
- EXPECT_CALL(*process_, SetThreadNameIfUnset(1u, StringId(1)));
+ EXPECT_CALL(*process_, SetThreadNameIfUnset(
+ 1u, storage_->InternString("OldThreadName")));
// Packet with same thread, but different name should update the name.
- EXPECT_CALL(*storage_, InternString(base::StringView("NewThreadName")))
- .WillOnce(Return(2));
- EXPECT_CALL(*process_, SetThreadNameIfUnset(1u, StringId(2)));
- EXPECT_CALL(*storage_, InternString(base::StringView("DifferentThreadName")))
- .WillOnce(Return(3));
- EXPECT_CALL(*process_, SetThreadNameIfUnset(2u, StringId(3)));
+ EXPECT_CALL(*process_, SetThreadNameIfUnset(
+ 1u, storage_->InternString("NewThreadName")));
+ EXPECT_CALL(
+ *process_,
+ SetThreadNameIfUnset(2u, storage_->InternString("DifferentThreadName")));
Tokenize();
context_.sorter->ExtractEventsForced();
@@ -1016,39 +992,30 @@
constexpr TrackId thread_1_track{0u};
constexpr TrackId process_2_track{1u};
- EXPECT_CALL(*storage_, InternString(base::StringView("cat2,cat3")))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
- .WillOnce(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillRepeatedly(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillRepeatedly(Return(4));
+ StringId cat_2_3 = storage_->InternString("cat2,cat3");
+ StringId ev_2 = storage_->InternString("ev2");
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
InSequence in_sequence; // Below slices should be sorted by timestamp.
MockBoundInserter inserter;
- EXPECT_CALL(*slice_, Scoped(1005000, thread_1_track, StringId(1), StringId(2),
- 23000, _))
+ EXPECT_CALL(*slice_, Scoped(1005000, thread_1_track, cat_2_3, ev_2, 23000, _))
.WillOnce(DoAll(InvokeArgument<5>(&inserter), Return(0u)));
EXPECT_CALL(inserter, AddArg(_, _, Variadic::UnsignedInteger(9999u)));
EXPECT_CALL(inserter, AddArg(_, _, Variadic::Boolean(true)));
EXPECT_CALL(inserter, AddArg(_, _, _));
- EXPECT_CALL(*slice_,
- Begin(1010000, thread_1_track, StringId(3), StringId(4), _))
+ EXPECT_CALL(*slice_, Begin(1010000, thread_1_track, cat_1, ev_1, _))
.WillOnce(DoAll(InvokeArgument<4>(&inserter), Return(1u)));
- EXPECT_CALL(*slice_,
- End(1020000, thread_1_track, StringId(3), StringId(4), _))
+ EXPECT_CALL(*slice_, End(1020000, thread_1_track, cat_1, ev_1, _))
.WillOnce(DoAll(InvokeArgument<4>(&inserter), Return(1u)));
- EXPECT_CALL(*slice_,
- Scoped(1040000, thread_1_track, StringId(3), StringId(4), 0, _))
+ EXPECT_CALL(*slice_, Scoped(1040000, thread_1_track, cat_1, ev_1, 0, _))
.WillOnce(DoAll(InvokeArgument<5>(&inserter), Return(2u)));
- EXPECT_CALL(*slice_,
- Scoped(1050000, process_2_track, StringId(3), StringId(4), 0, _))
+ EXPECT_CALL(*slice_, Scoped(1050000, process_2_track, cat_1, ev_1, 0, _))
.WillOnce(DoAll(InvokeArgument<5>(&inserter), Return(3u)));
// Second slice should have a legacy_event.original_tid arg.
EXPECT_CALL(inserter, AddArg(_, _, Variadic::Integer(16)));
@@ -1178,39 +1145,28 @@
row.upid = 1u;
storage_->mutable_thread_table()->Insert(row);
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillRepeatedly(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillRepeatedly(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
- .WillRepeatedly(Return(4));
- EXPECT_CALL(*storage_, InternString(base::StringView("cat2")))
- .WillRepeatedly(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("cat2:scope1")))
- .WillOnce(Return(5));
- EXPECT_CALL(*storage_, GetString(StringId(1))).WillRepeatedly(Return("cat1"));
- EXPECT_CALL(*storage_, GetString(StringId(3))).WillRepeatedly(Return("cat2"));
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId cat_2 = storage_->InternString("cat2");
+ StringId ev_2 = storage_->InternString("ev2");
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*slice_, Begin(1010000, TrackId{1}, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, Begin(1010000, TrackId{1}, cat_1, ev_1, _))
.WillOnce(Return(0u));
- EXPECT_CALL(*slice_,
- Scoped(1015000, TrackId{1}, StringId(1), StringId(4), 0, _));
- EXPECT_CALL(*slice_,
- Scoped(1018000, TrackId{2}, StringId(3), StringId(4), 0, _));
- EXPECT_CALL(*slice_, End(1020000, TrackId{1}, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, Scoped(1015000, TrackId{1}, cat_1, ev_2, 0, _));
+ EXPECT_CALL(*slice_, Scoped(1018000, TrackId{2}, cat_2, ev_2, 0, _));
+ EXPECT_CALL(*slice_, End(1020000, TrackId{1}, cat_1, ev_1, _))
.WillOnce(Return(0u));
- EXPECT_CALL(*slice_,
- Scoped(1030000, TrackId{3}, StringId(3), StringId(4), 0, _));
+ EXPECT_CALL(*slice_, Scoped(1030000, TrackId{3}, cat_2, ev_2, 0, _));
context_.sorter->ExtractEventsForced();
// First track is for the thread; others are the async event tracks.
EXPECT_EQ(storage_->track_table().row_count(), 4u);
- EXPECT_EQ(storage_->track_table().name()[1], 2u);
- EXPECT_EQ(storage_->track_table().name()[2], 4u);
- EXPECT_EQ(storage_->track_table().name()[3], 4u);
+ EXPECT_EQ(storage_->track_table().name()[1], ev_1);
+ EXPECT_EQ(storage_->track_table().name()[2], ev_2);
+ EXPECT_EQ(storage_->track_table().name()[3], ev_2);
EXPECT_EQ(storage_->process_track_table().row_count(), 3u);
EXPECT_EQ(storage_->process_track_table().upid()[0], 1u);
@@ -1355,41 +1311,28 @@
t2.upid = 2u;
storage_->mutable_thread_table()->Insert(t2);
- EXPECT_CALL(*storage_, InternString(base::StringView("Thread track 1")))
- .WillOnce(Return(10));
- EXPECT_CALL(*storage_, InternString(base::StringView("Async track 1")))
- .WillOnce(Return(11));
- EXPECT_CALL(*storage_, InternString(base::StringView("Thread track 2")))
- .WillOnce(Return(12));
-
Tokenize();
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId cat_2 = storage_->InternString("cat2");
+ StringId ev_2 = storage_->InternString("ev2");
+ StringId cat_3 = storage_->InternString("cat3");
+ StringId ev_3 = storage_->InternString("ev3");
+
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillOnce(Return(2));
- EXPECT_CALL(*slice_, Begin(1010000, TrackId{1}, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, Begin(1010000, TrackId{1}, cat_1, ev_1, _))
.WillOnce(Return(0u));
- EXPECT_CALL(*storage_, InternString(base::StringView("cat2")))
- .WillOnce(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
- .WillOnce(Return(4));
- EXPECT_CALL(*slice_,
- Scoped(1015000, TrackId{0}, StringId(3), StringId(4), 0, _))
+ EXPECT_CALL(*slice_, Scoped(1015000, TrackId{0}, cat_2, ev_2, 0, _))
.WillOnce(Return(1u));
- EXPECT_CALL(*storage_, InternString(base::StringView("cat3")))
- .WillOnce(Return(5));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev3")))
- .WillOnce(Return(6));
- EXPECT_CALL(*slice_,
- Scoped(1016000, TrackId{2}, StringId(5), StringId(6), 0, _))
+ EXPECT_CALL(*slice_, Scoped(1016000, TrackId{2}, cat_3, ev_3, 0, _))
.WillOnce(Return(2u));
- EXPECT_CALL(*slice_, End(1020000, TrackId{1}, StringId(0), StringId(0), _))
+ EXPECT_CALL(*slice_,
+ End(1020000, TrackId{1}, kNullStringId, kNullStringId, _))
.WillOnce(Return(0u));
context_.sorter->ExtractEventsForced();
@@ -1397,9 +1340,9 @@
// First track is "Thread track 1"; second is "Async track 1", third is
// "Thread track 2".
EXPECT_EQ(storage_->track_table().row_count(), 3u);
- EXPECT_EQ(storage_->track_table().name()[0], 10u); // "Thread track 1"
- EXPECT_EQ(storage_->track_table().name()[1], 11u); // "Async track 1"
- EXPECT_EQ(storage_->track_table().name()[2], 12u); // "Thread track 2"
+ EXPECT_EQ(storage_->track_table().name().GetString(0), "Thread track 1");
+ EXPECT_EQ(storage_->track_table().name().GetString(1), "Async track 1");
+ EXPECT_EQ(storage_->track_table().name().GetString(2), "Thread track 2");
EXPECT_EQ(storage_->thread_track_table().row_count(), 2u);
EXPECT_EQ(storage_->thread_track_table().utid()[0], 1u);
EXPECT_EQ(storage_->thread_track_table().utid()[1], 2u);
@@ -1683,25 +1626,18 @@
t2.upid = 1u;
storage_->mutable_thread_table()->Insert(t2);
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillRepeatedly(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev2")))
- .WillRepeatedly(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillRepeatedly(Return(3));
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_2 = storage_->InternString("ev2");
+ StringId ev_1 = storage_->InternString("ev1");
constexpr TrackId thread_2_track{0u};
constexpr TrackId thread_1_track{1u};
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*slice_,
- Begin(1005000, thread_2_track, StringId(1), StringId(2), _));
- EXPECT_CALL(*slice_,
- Begin(1010000, thread_1_track, StringId(1), StringId(3), _));
- EXPECT_CALL(*slice_,
- End(1015000, thread_2_track, StringId(1), StringId(2), _));
- EXPECT_CALL(*slice_,
- End(1020000, thread_1_track, StringId(1), StringId(3), _));
+ EXPECT_CALL(*slice_, Begin(1005000, thread_2_track, cat_1, ev_2, _));
+ EXPECT_CALL(*slice_, Begin(1010000, thread_1_track, cat_1, ev_1, _));
+ EXPECT_CALL(*slice_, End(1015000, thread_2_track, cat_1, ev_2, _));
+ EXPECT_CALL(*slice_, End(1020000, thread_1_track, cat_1, ev_1, _));
context_.sorter->ExtractEventsForced();
}
@@ -1839,82 +1775,58 @@
row.upid = 1u;
storage_->mutable_thread_table()->Insert(row);
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillRepeatedly(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillRepeatedly(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an1")))
- .WillOnce(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2")))
- .WillOnce(Return(4));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2.child1")))
- .WillRepeatedly(Return(5));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2.child2")))
- .WillRepeatedly(Return(6));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2.child2[0]")))
- .WillOnce(Return(7));
- EXPECT_CALL(*storage_, InternString(base::StringView("child21")))
- .WillOnce(Return(8));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2.child2[1]")))
- .WillOnce(Return(9));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an2.child2[2]")))
- .WillOnce(Return(10));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an3")))
- .WillOnce(Return(11));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an4")))
- .WillOnce(Return(12));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an5")))
- .WillOnce(Return(13));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an6")))
- .WillOnce(Return(14));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an7")))
- .WillOnce(Return(15));
- EXPECT_CALL(*storage_, InternString(base::StringView("val7")))
- .WillOnce(Return(16));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an8")))
- .WillOnce(Return(17));
- EXPECT_CALL(*storage_, InternString(base::StringView("val8")))
- .WillOnce(Return(18));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an8_foo")))
- .WillOnce(Return(19));
-
- EXPECT_CALL(*storage_, GetString(StringId(4))).WillOnce(Return("debug.an2"));
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId debug_an_1 = storage_->InternString("debug.an1");
+ StringId debug_an_2_child_1 = storage_->InternString("debug.an2.child1");
+ StringId debug_an_2_child_2 = storage_->InternString("debug.an2.child2");
+ StringId debug_an_2_child_2_0 = storage_->InternString("debug.an2.child2[0]");
+ StringId child21 = storage_->InternString("child21");
+ StringId debug_an_2_child_2_1 = storage_->InternString("debug.an2.child2[1]");
+ StringId debug_an_2_child_2_2 = storage_->InternString("debug.an2.child2[2]");
+ StringId debug_an_3 = storage_->InternString("debug.an3");
+ StringId debug_an_4 = storage_->InternString("debug.an4");
+ StringId debug_an_5 = storage_->InternString("debug.an5");
+ StringId debug_an_6 = storage_->InternString("debug.an6");
+ StringId debug_an_7 = storage_->InternString("debug.an7");
+ StringId val_7 = storage_->InternString("val7");
+ StringId debug_an_8 = storage_->InternString("debug.an8");
+ StringId val_8 = storage_->InternString("val8");
+ StringId debug_an_8_foo = storage_->InternString("debug.an8_foo");
constexpr TrackId track{0u};
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*slice_, Begin(1010000, track, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, Begin(1010000, track, cat_1, ev_1, _))
.WillOnce(DoAll(InvokeArgument<4>(&inserter), Return(1u)));
EXPECT_CALL(inserter,
- AddArg(StringId(3), StringId(3), Variadic::UnsignedInteger(10u)));
+ AddArg(debug_an_1, debug_an_1, Variadic::UnsignedInteger(10u)));
- EXPECT_CALL(inserter,
- AddArg(StringId(5), StringId(5), Variadic::Boolean(true)));
+ EXPECT_CALL(inserter, AddArg(debug_an_2_child_1, debug_an_2_child_1,
+ Variadic::Boolean(true)));
- EXPECT_CALL(inserter,
- AddArg(StringId(6), StringId(7), Variadic::String(StringId(8))));
+ EXPECT_CALL(inserter, AddArg(debug_an_2_child_2, debug_an_2_child_2_0,
+ Variadic::String(child21)));
- EXPECT_CALL(inserter, AddArg(StringId(6), StringId(9), Variadic::Real(2.2)));
+ EXPECT_CALL(inserter, AddArg(debug_an_2_child_2, debug_an_2_child_2_1,
+ Variadic::Real(2.2)));
- EXPECT_CALL(inserter,
- AddArg(StringId(6), StringId(10), Variadic::Integer(23)));
+ EXPECT_CALL(inserter, AddArg(debug_an_2_child_2, debug_an_2_child_2_2,
+ Variadic::Integer(23)));
- EXPECT_CALL(*slice_, End(1020000, track, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, End(1020000, track, cat_1, ev_1, _))
.WillOnce(DoAll(InvokeArgument<4>(&inserter), Return(1u)));
+ EXPECT_CALL(inserter, AddArg(debug_an_3, debug_an_3, Variadic::Integer(-3)));
EXPECT_CALL(inserter,
- AddArg(StringId(11), StringId(11), Variadic::Integer(-3)));
+ AddArg(debug_an_4, debug_an_4, Variadic::Boolean(true)));
+ EXPECT_CALL(inserter, AddArg(debug_an_5, debug_an_5, Variadic::Real(-5.5)));
+ EXPECT_CALL(inserter, AddArg(debug_an_6, debug_an_6, Variadic::Pointer(20u)));
EXPECT_CALL(inserter,
- AddArg(StringId(12), StringId(12), Variadic::Boolean(true)));
+ AddArg(debug_an_7, debug_an_7, Variadic::String(val_7)));
+ EXPECT_CALL(inserter, AddArg(debug_an_8, debug_an_8, Variadic::Json(val_8)));
EXPECT_CALL(inserter,
- AddArg(StringId(13), StringId(13), Variadic::Real(-5.5)));
- EXPECT_CALL(inserter,
- AddArg(StringId(14), StringId(14), Variadic::Pointer(20u)));
- EXPECT_CALL(inserter,
- AddArg(StringId(15), StringId(15), Variadic::String(16)));
- EXPECT_CALL(inserter, AddArg(StringId(17), StringId(17), Variadic::Json(18)));
- EXPECT_CALL(inserter,
- AddArg(StringId(19), StringId(19), Variadic::Integer(15)));
+ AddArg(debug_an_8_foo, debug_an_8_foo, Variadic::Integer(15)));
context_.sorter->ExtractEventsForced();
}
@@ -1969,21 +1881,19 @@
storage_->mutable_thread_table()->Insert(row);
constexpr TrackId track{0u};
+
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId file_1 = storage_->InternString("file1");
+ StringId func_1 = storage_->InternString("func1");
+
InSequence in_sequence; // Below slices should be sorted by timestamp.
MockBoundInserter inserter;
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillOnce(Return(2));
- EXPECT_CALL(*slice_, Begin(1010000, track, StringId(1), StringId(2), _))
+ EXPECT_CALL(*slice_, Begin(1010000, track, cat_1, ev_1, _))
.WillOnce(DoAll(InvokeArgument<4>(&inserter), Return(1u)));
- EXPECT_CALL(*storage_, InternString(base::StringView("file1")))
- .WillOnce(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("func1")))
- .WillOnce(Return(4));
- EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(3)));
- EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(4)));
+ EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(file_1)));
+ EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(func_1)));
EXPECT_CALL(inserter, AddArg(_, _, Variadic::UnsignedInteger(42)));
context_.sorter->ExtractEventsForced();
@@ -2047,29 +1957,25 @@
row.upid = 1u;
storage_->mutable_thread_table()->Insert(row);
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId body_1 = storage_->InternString("body1");
+
constexpr TrackId track{0};
InSequence in_sequence; // Below slices should be sorted by timestamp.
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillOnce(Return(2));
-
MockBoundInserter inserter;
- EXPECT_CALL(*slice_, Scoped(1010000, track, StringId(1), StringId(2), 0, _))
+ EXPECT_CALL(*slice_, Scoped(1010000, track, cat_1, ev_1, 0, _))
.WillOnce(DoAll(InvokeArgument<5>(&inserter), Return(1u)));
- EXPECT_CALL(*storage_, InternString(base::StringView("body1")))
- .WillOnce(Return(3));
-
// Call with logMessageBody (body1 in this case).
- EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(StringId(3))));
+ EXPECT_CALL(inserter, AddArg(_, _, Variadic::String(body_1)));
context_.sorter->ExtractEventsForced();
EXPECT_GT(context_.storage->android_log_table().row_count(), 0u);
EXPECT_EQ(context_.storage->android_log_table().ts()[0], 1010000);
- EXPECT_EQ(context_.storage->android_log_table().msg()[0], 3u);
+ EXPECT_EQ(context_.storage->android_log_table().msg()[0], body_1);
}
TEST_F(ProtoTraceParserTest, TrackEventParseLegacyEventIntoRawTable) {
@@ -2132,17 +2038,11 @@
row.upid = 1u;
storage_->mutable_thread_table()->Insert(row);
- EXPECT_CALL(*storage_, InternString(base::StringView("cat1")))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView("ev1")))
- .WillOnce(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView("scope1")))
- .Times(1)
- .WillRepeatedly(Return(3));
- EXPECT_CALL(*storage_, InternString(base::StringView("?")))
- .WillOnce(Return(4));
- EXPECT_CALL(*storage_, InternString(base::StringView("debug.an1")))
- .WillOnce(Return(5));
+ StringId cat_1 = storage_->InternString("cat1");
+ StringId ev_1 = storage_->InternString("ev1");
+ StringId scope_1 = storage_->InternString("scope1");
+ StringId question = storage_->InternString("?");
+ StringId debug_an_1 = storage_->InternString("debug.an1");
context_.sorter->ExtractEventsForced();
@@ -2161,11 +2061,11 @@
EXPECT_GE(storage_->arg_table().row_count(), 13u);
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.category"),
- Variadic::String(1u)));
+ Variadic::String(cat_1)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.name"),
- Variadic::String(2u)));
+ Variadic::String(ev_1)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.phase"),
- Variadic::String(4u)));
+ Variadic::String(question)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.duration_ns"),
Variadic::Integer(23000)));
EXPECT_TRUE(HasArg(1u,
@@ -2179,7 +2079,7 @@
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.global_id"),
Variadic::UnsignedInteger(99u)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.id_scope"),
- Variadic::String(3u)));
+ Variadic::String(scope_1)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.bind_id"),
Variadic::UnsignedInteger(98u)));
EXPECT_TRUE(HasArg(1u,
@@ -2187,7 +2087,7 @@
Variadic::Boolean(true)));
EXPECT_TRUE(HasArg(1u, storage_->InternString("legacy_event.flow_direction"),
Variadic::String(storage_->InternString("inout"))));
- EXPECT_TRUE(HasArg(1u, 5u, Variadic::UnsignedInteger(10u)));
+ EXPECT_TRUE(HasArg(1u, debug_an_1, Variadic::UnsignedInteger(10u)));
}
TEST_F(ProtoTraceParserTest, TrackEventLegacyTimestampsWithClockSnapshot) {
@@ -2378,12 +2278,9 @@
Tokenize();
- EXPECT_CALL(*storage_, InternString(base::StringView(kName)))
- .WillOnce(Return(1));
- EXPECT_CALL(*storage_, InternString(base::StringView(kTag1)))
- .WillOnce(Return(2));
- EXPECT_CALL(*storage_, InternString(base::StringView(kTag2)))
- .WillOnce(Return(3));
+ StringId name_1 = storage_->InternString(kName);
+ StringId tag_1 = storage_->InternString(kTag1);
+ StringId tag_2 = storage_->InternString(kTag2);
StringId benchmark_id = *storage_->string_pool().GetId(
metadata::kNames[metadata::benchmark_name]);
@@ -2401,9 +2298,9 @@
meta_entries.emplace_back(std::make_pair(meta_keys[i], meta_values[i]));
}
EXPECT_THAT(meta_entries,
- UnorderedElementsAreArray({std::make_pair(benchmark_id, 1),
- std::make_pair(tags_id, 2),
- std::make_pair(tags_id, 3)}));
+ UnorderedElementsAreArray({std::make_pair(benchmark_id, name_1),
+ std::make_pair(tags_id, tag_1),
+ std::make_pair(tags_id, tag_2)}));
}
TEST_F(ProtoTraceParserTest, AndroidPackagesList) {
@@ -2543,15 +2440,15 @@
const auto& samples = storage_->cpu_profile_stack_sample_table();
EXPECT_EQ(samples.row_count(), 3u);
- EXPECT_EQ(samples.ts()[0], 1010);
+ EXPECT_EQ(samples.ts()[0], 11000);
EXPECT_EQ(samples.callsite_id()[0], 0);
EXPECT_EQ(samples.utid()[0], 1u);
- EXPECT_EQ(samples.ts()[1], 1025);
+ EXPECT_EQ(samples.ts()[1], 26000);
EXPECT_EQ(samples.callsite_id()[1], 1);
EXPECT_EQ(samples.utid()[1], 1u);
- EXPECT_EQ(samples.ts()[2], 1067);
+ EXPECT_EQ(samples.ts()[2], 68000);
EXPECT_EQ(samples.callsite_id()[2], 0);
EXPECT_EQ(samples.utid()[2], 1u);
}
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
index b964a2c..ca746b7 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -18,8 +18,7 @@
#include <string>
-#include <zlib.h>
-
+#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_view.h"
@@ -42,6 +41,10 @@
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#endif
+
namespace perfetto {
namespace trace_processor {
@@ -53,6 +56,7 @@
constexpr uint8_t kTracePacketTag =
MakeTagLengthDelimited(protos::pbzero::Trace::kPacketFieldNumber);
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
TraceBlobView Decompress(TraceBlobView input) {
uint8_t out[4096];
std::string s;
@@ -81,6 +85,7 @@
memcpy(output.get(), s.data(), s.size());
return TraceBlobView(std::move(output), 0, s.size());
}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
} // namespace
@@ -309,6 +314,7 @@
}
if (decoder.has_compressed_packets()) {
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
protozero::ConstBytes field = decoder.compressed_packets();
const size_t field_off = packet.offset_of(field.data);
TraceBlobView compressed_packets = packet.slice(field_off, field.size);
@@ -334,6 +340,9 @@
}
return util::OkStatus();
+#else
+ return util::Status("Cannot decode compressed packets. Zlib not enabled");
+#endif
}
// If we're not forcing a full sort and this is a write_into_file trace, then
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 5355ad5..5ca7ca1 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -254,7 +254,7 @@
continue;
}
bool is_counter_field = fld.id() < proc_stats_process_names_.size() &&
- proc_stats_process_names_[fld.id()] != 0;
+ !proc_stats_process_names_[fld.id()].is_null();
if (is_counter_field) {
// Memory counters are in KB, keep values in bytes in the trace
// processor.
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 650156f..60a3318 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -393,7 +393,7 @@
category_strings.push_back(*it);
}
- StringId category_id = 0;
+ StringId category_id = kNullStringId;
// If there's a single category, we can avoid building a concatenated
// string.
@@ -430,7 +430,7 @@
category_id = storage->InternString(base::StringView(categories));
}
- StringId name_id = 0;
+ StringId name_id = kNullStringId;
uint64_t name_iid = event.name_iid();
if (!name_iid)
@@ -978,7 +978,7 @@
protos::pbzero::DebugAnnotation::Decoder annotation(debug_annotation.data,
debug_annotation.size);
- StringId name_id = 0;
+ StringId name_id = kNullStringId;
uint64_t name_iid = annotation.name_iid();
if (PERFETTO_LIKELY(name_iid)) {
@@ -1095,8 +1095,8 @@
if (!decoder)
return;
- StringId file_name_id = 0;
- StringId function_name_id = 0;
+ StringId file_name_id = kNullStringId;
+ StringId function_name_id = kNullStringId;
uint32_t line_number = 0;
TraceStorage* storage = context_->storage.get();
@@ -1128,7 +1128,7 @@
TraceStorage* storage = context_->storage.get();
- StringId log_message_id = 0;
+ StringId log_message_id = kNullStringId;
auto* decoder = sequence_state->LookupInternedMessage<
protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
@@ -1143,8 +1143,8 @@
context_->storage->mutable_android_log_table()->Insert(
{ts, *utid,
/*priority*/ 0,
- /*tag_id*/ 0, // TODO(nicomazz): Abuse tag_id to display
- // "file_name:line_number".
+ /*tag_id*/ kNullStringId, // TODO(nicomazz): Abuse tag_id to display
+ // "file_name:line_number".
log_message_id});
inserter->AddArg(log_message_body_key_id_, Variadic::String(log_message_id));
diff --git a/src/trace_processor/importers/systrace/systrace_parser.cc b/src/trace_processor/importers/systrace/systrace_parser.cc
index b6642a2..745a447 100644
--- a/src/trace_processor/importers/systrace/systrace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_parser.cc
@@ -109,7 +109,8 @@
StringId name_id = context_->storage->InternString(point.name);
UniqueTid utid = context_->process_tracker->UpdateThread(pid, point.tgid);
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Begin(ts, track_id, 0 /* cat */, name_id);
+ context_->slice_tracker->Begin(ts, track_id, kNullStringId /* cat */,
+ name_id);
break;
}
@@ -142,7 +143,7 @@
TrackId track_id = context_->track_tracker->InternAndroidAsyncTrack(
name_id, upid, cookie);
if (point.phase == 'S') {
- context_->slice_tracker->Begin(ts, track_id, 0, name_id);
+ context_->slice_tracker->Begin(ts, track_id, kNullStringId, name_id);
} else {
context_->slice_tracker->End(ts, track_id);
}
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.h b/src/trace_processor/importers/systrace/systrace_trace_parser.h
index 1b5926b..26553e9 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.h
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.h
@@ -47,8 +47,8 @@
util::Status ParseSingleSystraceEvent(const std::string& buffer);
TraceProcessorContext* const context_;
- const StringId sched_wakeup_name_id_ = 0;
- const StringId cpu_idle_name_id_ = 0;
+ const StringId sched_wakeup_name_id_ = kNullStringId;
+ const StringId cpu_idle_name_id_ = kNullStringId;
const std::regex line_matcher_;
ParseState state_ = ParseState::kBeforeParse;
diff --git a/src/trace_processor/metadata.h b/src/trace_processor/metadata.h
index eb55e15..2546cec 100644
--- a/src/trace_processor/metadata.h
+++ b/src/trace_processor/metadata.h
@@ -56,6 +56,9 @@
F(kMulti, "multi")
// clang-format
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+
#define PERFETTO_TP_META_TYPE_ENUM(varname, ...) varname
enum class KeyType : size_t {
PERFETTO_TP_METADATA_KEY_TYPES(PERFETTO_TP_META_TYPE_ENUM),
diff --git a/src/trace_processor/process_tracker.cc b/src/trace_processor/process_tracker.cc
index fe80471..82aa32d 100644
--- a/src/trace_processor/process_tracker.cc
+++ b/src/trace_processor/process_tracker.cc
@@ -178,7 +178,7 @@
// Create a new UTID for the main thread, so we don't end up reusing an old
// entry in case of TID recycling.
- StartNewThread(timestamp, /*tid=*/pid, 0);
+ StartNewThread(timestamp, /*tid=*/pid, kNullStringId);
// Note that we erased the pid above so this should always return a new
// process.
@@ -187,7 +187,7 @@
auto* process_table = context_->storage->mutable_process_table();
auto* thread_table = context_->storage->mutable_thread_table();
- PERFETTO_DCHECK(process_table->name()[upid] == 0);
+ PERFETTO_DCHECK(process_table->name()[upid].is_null());
PERFETTO_DCHECK(!process_table->start_ts()[upid].has_value());
if (timestamp) {
diff --git a/src/trace_processor/process_tracker_unittest.cc b/src/trace_processor/process_tracker_unittest.cc
index bd6d2b7..e626681 100644
--- a/src/trace_processor/process_tracker_unittest.cc
+++ b/src/trace_processor/process_tracker_unittest.cc
@@ -59,7 +59,8 @@
TEST_F(ProcessTrackerTest, StartNewProcess) {
TraceStorage storage;
- auto upid = context.process_tracker->StartNewProcess(1000, 0u, 123, 0);
+ auto upid =
+ context.process_tracker->StartNewProcess(1000, 0u, 123, kNullStringId);
ASSERT_EQ(context.process_tracker->GetOrCreateProcess(123), upid);
ASSERT_EQ(context.storage->process_table().start_ts()[upid], 1000);
}
diff --git a/src/trace_processor/slice_tracker_unittest.cc b/src/trace_processor/slice_tracker_unittest.cc
index f6debfa..6b27258 100644
--- a/src/trace_processor/slice_tracker_unittest.cc
+++ b/src/trace_processor/slice_tracker_unittest.cc
@@ -56,16 +56,18 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Begin(2 /*ts*/, track, 0 /*cat*/, 1 /*name*/);
- tracker.End(10 /*ts*/, track, 0 /*cat*/, 1 /*name*/);
+ tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/);
+ tracker.End(10 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/);
const auto& slices = context.storage->slice_table();
EXPECT_EQ(slices.row_count(), 1u);
EXPECT_EQ(slices.ts()[0], 2);
EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track.value);
- EXPECT_EQ(slices.category()[0], 0u);
- EXPECT_EQ(slices.name()[0], 1u);
+ EXPECT_EQ(slices.category()[0].raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].raw_id(), 1u);
EXPECT_EQ(slices.depth()[0], 0u);
EXPECT_EQ(slices.arg_set_id()[0], kInvalidArgSetId);
}
@@ -77,14 +79,18 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Begin(2 /*ts*/, track, 0 /*cat*/, 1 /*name*/,
+ tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/,
[](ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(/*flat_key=*/1, /*key=*/2,
+ inserter->AddArg(/*flat_key=*/StringId::Raw(1),
+ /*key=*/StringId::Raw(2),
/*value=*/Variadic::Integer(10));
});
- tracker.End(10 /*ts*/, track, 0 /*cat*/, 1 /*name*/,
+ tracker.End(10 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/,
[](ArgsTracker::BoundInserter* inserter) {
- inserter->AddArg(/*flat_key=*/3, /*key=*/4,
+ inserter->AddArg(/*flat_key=*/StringId::Raw(3),
+ /*key=*/StringId::Raw(4),
/*value=*/Variadic::Integer(20));
});
@@ -93,19 +99,19 @@
EXPECT_EQ(slices.ts()[0], 2);
EXPECT_EQ(slices.dur()[0], 8);
EXPECT_EQ(slices.track_id()[0], track.value);
- EXPECT_EQ(slices.category()[0], 0u);
- EXPECT_EQ(slices.name()[0], 1u);
+ EXPECT_EQ(slices.category()[0].raw_id(), 0u);
+ EXPECT_EQ(slices.name()[0].raw_id(), 1u);
EXPECT_EQ(slices.depth()[0], 0u);
auto set_id = slices.arg_set_id()[0];
const auto& args = context.storage->arg_table();
EXPECT_EQ(args.arg_set_id()[0], set_id);
- EXPECT_EQ(args.flat_key()[0], 1u);
- EXPECT_EQ(args.key()[0], 2u);
+ EXPECT_EQ(args.flat_key()[0].raw_id(), 1u);
+ EXPECT_EQ(args.key()[0].raw_id(), 2u);
EXPECT_EQ(args.int_value()[0], 10);
EXPECT_EQ(args.arg_set_id()[1], set_id);
- EXPECT_EQ(args.flat_key()[1], 3u);
- EXPECT_EQ(args.key()[1], 4u);
+ EXPECT_EQ(args.flat_key()[1].raw_id(), 3u);
+ EXPECT_EQ(args.key()[1].raw_id(), 4u);
EXPECT_EQ(args.int_value()[1], 20);
}
@@ -115,8 +121,10 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Begin(2 /*ts*/, track, 0 /*cat*/, 1 /*name*/);
- tracker.Begin(3 /*ts*/, track, 0 /*cat*/, 2 /*name*/);
+ tracker.Begin(2 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/);
+ tracker.Begin(3 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(2) /*name*/);
tracker.End(5 /*ts*/, track);
tracker.End(10 /*ts*/, track);
@@ -128,15 +136,15 @@
EXPECT_EQ(slices.ts()[idx], 2);
EXPECT_EQ(slices.dur()[idx], 8);
EXPECT_EQ(slices.track_id()[idx], track.value);
- EXPECT_EQ(slices.category()[idx], 0u);
- EXPECT_EQ(slices.name()[idx], 1u);
+ EXPECT_EQ(slices.category()[idx].raw_id(), 0u);
+ EXPECT_EQ(slices.name()[idx].raw_id(), 1u);
EXPECT_EQ(slices.depth()[idx++], 0u);
EXPECT_EQ(slices.ts()[idx], 3);
EXPECT_EQ(slices.dur()[idx], 2);
EXPECT_EQ(slices.track_id()[idx], track.value);
- EXPECT_EQ(slices.category()[idx], 0u);
- EXPECT_EQ(slices.name()[idx], 2u);
+ EXPECT_EQ(slices.category()[idx].raw_id(), 0u);
+ EXPECT_EQ(slices.name()[idx].raw_id(), 2u);
EXPECT_EQ(slices.depth()[idx], 1u);
EXPECT_EQ(slices.parent_stack_id()[0], 0);
@@ -150,9 +158,9 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Begin(0 /*ts*/, track, 0, 0);
- tracker.Begin(1 /*ts*/, track, 0, 0);
- tracker.Scoped(2 /*ts*/, track, 0, 0, 6);
+ tracker.Begin(0 /*ts*/, track, kNullStringId, kNullStringId);
+ tracker.Begin(1 /*ts*/, track, kNullStringId, kNullStringId);
+ tracker.Scoped(2 /*ts*/, track, kNullStringId, kNullStringId, 6);
tracker.End(9 /*ts*/, track);
tracker.End(10 /*ts*/, track);
@@ -167,10 +175,14 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Begin(2 /*ts*/, track, 5 /*cat*/, 1 /*name*/);
- tracker.End(3 /*ts*/, track, 1 /*cat*/, 1 /*name*/);
- tracker.End(4 /*ts*/, track, 0 /*cat*/, 2 /*name*/);
- tracker.End(5 /*ts*/, track, 5 /*cat*/, 1 /*name*/);
+ tracker.Begin(2 /*ts*/, track, StringId::Raw(5) /*cat*/,
+ StringId::Raw(1) /*name*/);
+ tracker.End(3 /*ts*/, track, StringId::Raw(1) /*cat*/,
+ StringId::Raw(1) /*name*/);
+ tracker.End(4 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(2) /*name*/);
+ tracker.End(5 /*ts*/, track, StringId::Raw(5) /*cat*/,
+ StringId::Raw(1) /*name*/);
auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 3}));
@@ -185,10 +197,14 @@
// from being closed, leading to an inconsistency when we try to insert the
// final slice and it doesn't intersect with the still pending first slice.
constexpr TrackId track{22u};
- tracker.Scoped(2 /*ts*/, track, 0 /*cat*/, 1 /*name*/, 10 /* dur */);
- tracker.Scoped(2 /*ts*/, track, 0 /*cat*/, 1 /*name*/, 0 /* dur */);
- tracker.Scoped(12 /*ts*/, track, 0 /*cat*/, 1 /*name*/, 1 /* dur */);
- tracker.Scoped(13 /*ts*/, track, 0 /*cat*/, 1 /*name*/, 1 /* dur */);
+ tracker.Scoped(2 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/, 10 /* dur */);
+ tracker.Scoped(2 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/, 0 /* dur */);
+ tracker.Scoped(12 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/, 1 /* dur */);
+ tracker.Scoped(13 /*ts*/, track, kNullStringId /*cat*/,
+ StringId::Raw(1) /*name*/, 1 /* dur */);
auto slices = ToSliceInfo(context.storage->slice_table());
EXPECT_THAT(slices, ElementsAre(SliceInfo{2, 10}, SliceInfo{2, 0},
@@ -202,9 +218,9 @@
constexpr TrackId track_a{22u};
constexpr TrackId track_b{23u};
- tracker.Begin(0 /*ts*/, track_a, 0, 0);
- tracker.Scoped(2 /*ts*/, track_b, 0, 0, 6);
- tracker.Scoped(3 /*ts*/, track_b, 0, 0, 4);
+ tracker.Begin(0 /*ts*/, track_a, kNullStringId, kNullStringId);
+ tracker.Scoped(2 /*ts*/, track_b, kNullStringId, kNullStringId, 6);
+ tracker.Scoped(3 /*ts*/, track_b, kNullStringId, kNullStringId, 4);
tracker.End(10 /*ts*/, track_a);
tracker.FlushPendingSlices();
@@ -226,26 +242,36 @@
SliceTracker tracker(&context);
constexpr TrackId track{22u};
- tracker.Scoped(50 /*ts*/, track, 11 /*cat*/, 21 /*name*/, 100 /*dur*/);
- tracker.Begin(100 /*ts*/, track, 12 /*cat*/, 22 /*name*/);
+ tracker.Scoped(50 /*ts*/, track, StringId::Raw(11) /*cat*/,
+ StringId::Raw(21) /*name*/, 100 /*dur*/);
+ tracker.Begin(100 /*ts*/, track, StringId::Raw(12) /*cat*/,
+ StringId::Raw(22) /*name*/);
// This slice should now have depth 0.
- tracker.Scoped(450 /*ts*/, track, 12 /*cat*/, 22 /*name*/, 100 /*dur*/);
+ tracker.Scoped(450 /*ts*/, track, StringId::Raw(12) /*cat*/,
+ StringId::Raw(22) /*name*/, 100 /*dur*/);
// This slice should be ignored.
- tracker.End(500 /*ts*/, track, 12 /*cat*/, 22 /*name*/);
+ tracker.End(500 /*ts*/, track, StringId::Raw(12) /*cat*/,
+ StringId::Raw(22) /*name*/);
- tracker.Begin(800 /*ts*/, track, 13 /*cat*/, 23 /*name*/);
+ tracker.Begin(800 /*ts*/, track, StringId::Raw(13) /*cat*/,
+ StringId::Raw(23) /*name*/);
// Null cat and name matches everything.
- tracker.End(1000 /*ts*/, track, 0 /*cat*/, 0 /*name*/);
+ tracker.End(1000 /*ts*/, track, kNullStringId /*cat*/,
+ kNullStringId /*name*/);
// Slice will not close if category is different.
- tracker.Begin(1100 /*ts*/, track, 11 /*cat*/, 21 /*name*/);
- tracker.End(1200 /*ts*/, track, 12 /*cat*/, 21 /*name*/);
+ tracker.Begin(1100 /*ts*/, track, StringId::Raw(11) /*cat*/,
+ StringId::Raw(21) /*name*/);
+ tracker.End(1200 /*ts*/, track, StringId::Raw(12) /*cat*/,
+ StringId::Raw(21) /*name*/);
// Slice will not close if name is different.
- tracker.Begin(1300 /*ts*/, track, 11 /*cat*/, 21 /*name*/);
- tracker.End(1400 /*ts*/, track, 11 /*cat*/, 22 /*name*/);
+ tracker.Begin(1300 /*ts*/, track, StringId::Raw(11) /*cat*/,
+ StringId::Raw(21) /*name*/);
+ tracker.End(1400 /*ts*/, track, StringId::Raw(11) /*cat*/,
+ StringId::Raw(22) /*name*/);
tracker.FlushPendingSlices();
diff --git a/src/trace_processor/stats.h b/src/trace_processor/stats.h
index 19b35b3..8d52968 100644
--- a/src/trace_processor/stats.h
+++ b/src/trace_processor/stats.h
@@ -150,6 +150,9 @@
kAnalysis
};
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+
// Declares an enum of literals (one for each stat). The enum values of each
// literal corresponds to the string index in the arrays below.
#define PERFETTO_TP_STATS_ENUM(name, ...) name
diff --git a/src/trace_processor/syscall_tracker.cc b/src/trace_processor/syscall_tracker.cc
index 609284d..5991497 100644
--- a/src/trace_processor/syscall_tracker.cc
+++ b/src/trace_processor/syscall_tracker.cc
@@ -83,7 +83,7 @@
}
for (size_t i = 0; i < kMaxSyscalls; i++) {
- StringId id = 0;
+ StringId id = kNullStringId;
if (i < num_syscalls && syscall_table[i] && *syscall_table[i]) {
const char* name = syscall_table[i];
id = context_->storage->InternString(name);
diff --git a/src/trace_processor/syscall_tracker.h b/src/trace_processor/syscall_tracker.h
index 1dba57d..88d67b4 100644
--- a/src/trace_processor/syscall_tracker.h
+++ b/src/trace_processor/syscall_tracker.h
@@ -58,7 +58,8 @@
StringId name = SyscallNumberToStringId(syscall_num);
if (!name.is_null()) {
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->Begin(ts, track_id, 0 /* cat */, name);
+ context_->slice_tracker->Begin(ts, track_id, kNullStringId /* cat */,
+ name);
}
}
@@ -66,7 +67,7 @@
StringId name = SyscallNumberToStringId(syscall_num);
if (!name.is_null()) {
TrackId track_id = context_->track_tracker->InternThreadTrack(utid);
- context_->slice_tracker->End(ts, track_id, 0 /* cat */, name);
+ context_->slice_tracker->End(ts, track_id, kNullStringId /* cat */, name);
}
}
@@ -77,14 +78,14 @@
inline StringId SyscallNumberToStringId(uint32_t syscall_num) {
if (syscall_num > kMaxSyscalls)
- return 0;
+ return kNullStringId;
// We see two write sys calls around each userspace slice that is going via
// trace_marker, this violates the assumption that userspace slices are
// perfectly nested. For the moment ignore all write sys calls.
// TODO(hjd): Remove this limitation.
StringId id = arch_syscall_to_string_id_[syscall_num];
if (id == sys_write_string_id_)
- return 0;
+ return kNullStringId;
return id;
}
diff --git a/src/trace_processor/syscall_tracker_unittest.cc b/src/trace_processor/syscall_tracker_unittest.cc
index f7a2eef..61124d1 100644
--- a/src/trace_processor/syscall_tracker_unittest.cc
+++ b/src/trace_processor/syscall_tracker_unittest.cc
@@ -64,8 +64,8 @@
TEST_F(SyscallTrackerTest, ReportUnknownSyscalls) {
constexpr TrackId track{0u};
- StringId begin_name = 0;
- StringId end_name = 0;
+ StringId begin_name = kNullStringId;
+ StringId end_name = kNullStringId;
EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
.WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
@@ -90,8 +90,8 @@
TEST_F(SyscallTrackerTest, Aarch64) {
constexpr TrackId track{0u};
- StringId begin_name = 0;
- StringId end_name = 0;
+ StringId begin_name = kNullStringId;
+ StringId end_name = kNullStringId;
EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
.WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
@@ -107,8 +107,8 @@
TEST_F(SyscallTrackerTest, x8664) {
constexpr TrackId track{0u};
- StringId begin_name = 0;
- StringId end_name = 0;
+ StringId begin_name = kNullStringId;
+ StringId end_name = kNullStringId;
EXPECT_CALL(*slice_tracker, Begin(100, track, kNullStringId, _, _))
.WillOnce(DoAll(SaveArg<3>(&begin_name), Return(base::nullopt)));
EXPECT_CALL(*slice_tracker, End(110, track, kNullStringId, _, _))
diff --git a/src/trace_processor/tables/macros_internal.h b/src/trace_processor/tables/macros_internal.h
index ada4b8c..71895b2 100644
--- a/src/trace_processor/tables/macros_internal.h
+++ b/src/trace_processor/tables/macros_internal.h
@@ -122,6 +122,9 @@
} // namespace macros_internal
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+
// Basic helper macros.
#define PERFETTO_TP_NOOP(...)
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index d06580d..9b44058 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -539,7 +539,12 @@
auto it = ExecuteQuery(query);
while (it.Next()) {
}
- PERFETTO_CHECK(it.Status().ok());
+ // Index deletion can legitimately fail. If one creates an index "i" on a
+ // table "t" but issues the deletion in the order (t, i), the DROP index i
+ // will fail with "no such index" because deleting the table "t"
+ // automatically deletes all associated indexes.
+ if (!it.Status().ok() && tn.first != "index")
+ PERFETTO_FATAL("%s -> %s", query.c_str(), it.Status().c_message());
}
return deletion_list.size();
}
diff --git a/src/trace_processor/trace_storage.h b/src/trace_processor/trace_storage.h
index da7d12a..8b0634b 100644
--- a/src/trace_processor/trace_storage.h
+++ b/src/trace_processor/trace_storage.h
@@ -58,7 +58,7 @@
// StringId is an offset into |string_pool_|.
using StringId = StringPool::Id;
-static const StringId kNullStringId = StringId(0);
+static const StringId kNullStringId = StringId::Null();
using ArgSetId = uint32_t;
static const ArgSetId kInvalidArgSetId = 0;
@@ -710,7 +710,7 @@
// TODO(lalitm): remove this when we find a better home for this.
using FrameKey = std::pair<size_t /* mapping row */, uint64_t /* rel_pc */>;
- std::map<MappingKey, std::vector<int64_t>> stack_profile_frame_index_;
+ std::map<FrameKey, std::vector<int64_t>> stack_profile_frame_index_;
// One entry for each unique string in the trace.
StringPool string_pool_;
diff --git a/src/trace_processor/track_tracker.cc b/src/trace_processor/track_tracker.cc
index 4ac6f5b..94661b8 100644
--- a/src/trace_processor/track_tracker.cc
+++ b/src/trace_processor/track_tracker.cc
@@ -81,7 +81,7 @@
}
TrackId TrackTracker::InternGpuTrack(const tables::GpuTrackTable::Row& row) {
- GpuTrackTuple tuple{row.name.id, row.scope, row.context_id.value_or(0)};
+ GpuTrackTuple tuple{row.name, row.scope, row.context_id.value_or(0)};
auto it = gpu_tracks_.find(tuple);
if (it != gpu_tracks_.end())
diff --git a/src/trace_processor/track_tracker.h b/src/trace_processor/track_tracker.h
index 803b908..de6233a 100644
--- a/src/trace_processor/track_tracker.h
+++ b/src/trace_processor/track_tracker.h
@@ -131,8 +131,8 @@
// Creates a counter track associated with a GPU into the storage.
TrackId CreateGpuCounterTrack(StringId name,
uint32_t gpu_id,
- StringId description = 0,
- StringId unit = 0);
+ StringId description = StringId::Null(),
+ StringId unit = StringId::Null());
private:
struct GpuTrackTuple {
@@ -148,7 +148,7 @@
struct ChromeTrackTuple {
base::Optional<int64_t> upid;
int64_t source_id = 0;
- StringId source_scope = 0;
+ StringId source_scope = StringId::Null();
friend bool operator<(const ChromeTrackTuple& l,
const ChromeTrackTuple& r) {
@@ -212,17 +212,17 @@
std::map<UniquePid, uint64_t /*uuid*/> descriptor_uuids_by_upid_;
std::map<UniqueTid, uint64_t /*uuid*/> descriptor_uuids_by_utid_;
- const StringId source_key_ = 0;
- const StringId source_id_key_ = 0;
- const StringId source_id_is_process_scoped_key_ = 0;
- const StringId source_scope_key_ = 0;
+ const StringId source_key_ = kNullStringId;
+ const StringId source_id_key_ = kNullStringId;
+ const StringId source_id_is_process_scoped_key_ = kNullStringId;
+ const StringId source_scope_key_ = kNullStringId;
- const StringId fuchsia_source_ = 0;
- const StringId chrome_source_ = 0;
- const StringId android_source_ = 0;
- const StringId descriptor_source_ = 0;
+ const StringId fuchsia_source_ = kNullStringId;
+ const StringId chrome_source_ = kNullStringId;
+ const StringId android_source_ = kNullStringId;
+ const StringId descriptor_source_ = kNullStringId;
- const StringId default_descriptor_track_name_ = 0;
+ const StringId default_descriptor_track_name_ = kNullStringId;
TraceProcessorContext* const context_;
};
diff --git a/src/traced/probes/ftrace/format_parser.cc b/src/traced/probes/ftrace/format_parser.cc
index c5ce2c1..d4e119f 100644
--- a/src/traced/probes/ftrace/format_parser.cc
+++ b/src/traced/probes/ftrace/format_parser.cc
@@ -141,7 +141,7 @@
for (base::StringSplitter ss(std::move(input), '\n'); ss.Next();) {
const char* line = ss.cur_token();
- if (!has_id && sscanf(line, "ID: %d", &id) == 1) {
+ if (!has_id && sscanf(line, "ID: %u", &id) == 1) {
has_id = true;
continue;
}
diff --git a/src/traced/probes/ftrace/ftrace_data_source.cc b/src/traced/probes/ftrace/ftrace_data_source.cc
index f576f16..f28a491 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.cc
+++ b/src/traced/probes/ftrace/ftrace_data_source.cc
@@ -36,12 +36,12 @@
: ProbesDataSource(session_id, kTypeId),
config_(config),
writer_(std::move(writer)),
- controller_weak_(std::move(controller_weak)){};
+ controller_weak_(std::move(controller_weak)) {}
FtraceDataSource::~FtraceDataSource() {
if (controller_weak_)
controller_weak_->RemoveDataSource(this);
-};
+}
void FtraceDataSource::Initialize(
FtraceConfigId config_id,
diff --git a/src/traced/probes/ftrace/proto_translation_table.cc b/src/traced/probes/ftrace/proto_translation_table.cc
index 86c61f0..ceb0973 100644
--- a/src/traced/probes/ftrace/proto_translation_table.cc
+++ b/src/traced/probes/ftrace/proto_translation_table.cc
@@ -521,12 +521,12 @@
group_to_events_[e->group].push_back(&events_.at(e->ftrace_event_id));
return e;
-};
+}
const char* ProtoTranslationTable::InternString(const std::string& str) {
auto it_and_inserted = interned_strings_.insert(str);
return it_and_inserted.first->c_str();
-};
+}
uint16_t ProtoTranslationTable::CreateGenericEventField(
const FtraceEvent::Field& ftrace_field,
diff --git a/test/benchmark_main.cc b/test/benchmark_main.cc
index e410e52..3a3feaa 100644
--- a/test/benchmark_main.cc
+++ b/test/benchmark_main.cc
@@ -14,4 +14,4 @@
#include <benchmark/benchmark.h>
-BENCHMARK_MAIN();
+BENCHMARK_MAIN()
diff --git a/tools/trace_to_text/BUILD.gn b/tools/trace_to_text/BUILD.gn
index 41c844d..6892d1a 100644
--- a/tools/trace_to_text/BUILD.gn
+++ b/tools/trace_to_text/BUILD.gn
@@ -50,10 +50,12 @@
"../../src/profiling/symbolizer:symbolize_database",
]
public_deps = [
- "../../gn:zlib",
"../../include/perfetto/ext/base",
"../../include/perfetto/profiling:deobfuscator",
]
+ if (enable_perfetto_zlib) {
+ public_deps += [ "../../gn:zlib" ]
+ }
sources = [
"utils.cc",
"utils.h",
@@ -144,9 +146,11 @@
":utils",
"../../gn:default_deps",
"../../gn:protobuf_full",
- "../../gn:zlib",
"../../protos/perfetto/trace:zero",
]
+ if (enable_perfetto_zlib) {
+ deps += [ "../../gn:zlib" ]
+ }
sources = [
"proto_full_utils.cc",
"proto_full_utils.h",
diff --git a/tools/trace_to_text/trace_to_text.cc b/tools/trace_to_text/trace_to_text.cc
index 3fb86d8..1616a2d 100644
--- a/tools/trace_to_text/trace_to_text.cc
+++ b/tools/trace_to_text/trace_to_text.cc
@@ -16,8 +16,6 @@
#include "tools/trace_to_text/trace_to_text.h"
-#include <zlib.h>
-
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -31,6 +29,10 @@
#include "protos/perfetto/trace/trace.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#endif
+
namespace perfetto {
namespace trace_to_text {
@@ -78,6 +80,7 @@
void PrintCompressedPackets(const std::string& packets,
Message* compressed_msg_scratch,
ZeroCopyOutputStream* output) {
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
uint8_t out[4096];
std::vector<uint8_t> data;
@@ -120,6 +123,24 @@
}
WriteToZeroCopyOutput(output, kCompressedPacketsSuffix,
sizeof(kCompressedPacketsSuffix) - 1);
+#else
+ base::ignore_result(packets);
+ base::ignore_result(compressed_msg_scratch);
+ base::ignore_result(kIndentedPacketPrefix);
+ base::ignore_result(kIndentedPacketSuffix);
+ WriteToZeroCopyOutput(output, kCompressedPacketsPrefix,
+ sizeof(kCompressedPacketsPrefix) - 1);
+ static const char kErrMsg[] =
+ "Cannot decode compressed packets. zlib not enabled in the build config";
+ WriteToZeroCopyOutput(output, kErrMsg, sizeof(kErrMsg) - 1);
+ WriteToZeroCopyOutput(output, kCompressedPacketsSuffix,
+ sizeof(kCompressedPacketsSuffix) - 1);
+ static bool log_once = [] {
+ PERFETTO_ELOG("%s", kErrMsg);
+ return true;
+ }();
+ base::ignore_result(log_once);
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
}
} // namespace
diff --git a/tools/trace_to_text/utils.cc b/tools/trace_to_text/utils.cc
index 73645f6..e655b38 100644
--- a/tools/trace_to_text/utils.cc
+++ b/tools/trace_to_text/utils.cc
@@ -39,8 +39,9 @@
using Iterator = trace_processor::TraceProcessor::Iterator;
-
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
constexpr size_t kCompressionBufferSize = 500 * 1024;
+#endif
std::map<std::string, std::set<std::string>> GetHeapGraphClasses(
trace_processor::TraceProcessor* tp) {
@@ -179,7 +180,6 @@
return true;
}
-
void DeobfuscateDatabase(
trace_processor::TraceProcessor* tp,
const std::map<std::string, profiling::ObfuscatedClass>& mapping,
@@ -229,6 +229,8 @@
output_->write(data, static_cast<std::streamsize>(sz));
}
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
DeflateTraceWriter::DeflateTraceWriter(std::ostream* output)
: TraceWriter(output),
buf_(base::PagedMemory::Allocate(kCompressionBufferSize)),
@@ -270,6 +272,15 @@
PERFETTO_FATAL("Expected %d got %d: %s", actual_code, expected_code,
stream_.msg);
}
+#else
+
+DeflateTraceWriter::DeflateTraceWriter(std::ostream* output)
+ : TraceWriter(output) {
+ PERFETTO_ELOG("Cannot compress. Zlib is not enabled in the build config");
+}
+DeflateTraceWriter::~DeflateTraceWriter() = default;
+
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
} // namespace trace_to_text
} // namespace perfetto
diff --git a/tools/trace_to_text/utils.h b/tools/trace_to_text/utils.h
index 19bd3ca..d708e04 100644
--- a/tools/trace_to_text/utils.h
+++ b/tools/trace_to_text/utils.h
@@ -26,13 +26,15 @@
#include <memory>
#include <vector>
-#include <zlib.h>
-
#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/paged_memory.h"
#include "perfetto/profiling/deobfuscator.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+#include <zlib.h>
+#endif
+
namespace perfetto {
namespace trace_processor {
@@ -83,6 +85,7 @@
std::ostream* output_;
};
+#if PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
class DeflateTraceWriter : public TraceWriter {
public:
DeflateTraceWriter(std::ostream* output);
@@ -100,6 +103,17 @@
uint8_t* const end_;
};
+#else
+
+// Fallback implementation. Will print an error and write uncompressed.
+class DeflateTraceWriter : public TraceWriter {
+ public:
+ DeflateTraceWriter(std::ostream* output);
+ ~DeflateTraceWriter() override;
+};
+
+#endif // PERFETTO_BUILDFLAG(PERFETTO_ZLIB)
+
} // namespace trace_to_text
} // namespace perfetto