Merge "Add note to download_changed_screenshots.py about running test_data"
diff --git a/Android.bp b/Android.bp
index 0d0ad96..0153be7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1980,6 +1980,7 @@
":perfetto_src_trace_processor_sqlite_functions_functions",
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_sqlite_sqlite_minimal",
+ ":perfetto_src_trace_processor_stdlib_stdlib",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
":perfetto_src_trace_processor_storage_storage",
@@ -2171,6 +2172,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
],
defaults: [
"perfetto_defaults",
@@ -9456,12 +9458,12 @@
"src/trace_processor/metrics/sql/trace_stats.sql",
"src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
],
- cmd: "$(location tools/gen_amalgamated_sql_metrics.py) --cpp_out=$(out) $(in)",
+ cmd: "$(location tools/gen_amalgamated_sql.py) --type=METRICS --cpp_out=$(out) $(in)",
out: [
"src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
],
tool_files: [
- "tools/gen_amalgamated_sql_metrics.py",
+ "tools/gen_amalgamated_sql.py",
],
}
@@ -9505,6 +9507,7 @@
"src/trace_processor/sqlite/functions/create_function.cc",
"src/trace_processor/sqlite/functions/create_function_internal.cc",
"src/trace_processor/sqlite/functions/create_view_function.cc",
+ "src/trace_processor/sqlite/functions/import.cc",
"src/trace_processor/sqlite/functions/pprof_functions.cc",
"src/trace_processor/sqlite/functions/register_function.cc",
"src/trace_processor/sqlite/functions/sqlite3_str_split.cc",
@@ -9553,6 +9556,26 @@
],
}
+// GN: //src/trace_processor/stdlib:gen_amalgamated_stdlib
+genrule {
+ name: "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
+ srcs: [
+ "src/trace_processor/stdlib/android/binder.sql",
+ ],
+ cmd: "$(location tools/gen_amalgamated_sql.py) --type=LIB --cpp_out=$(out) $(in)",
+ out: [
+ "src/trace_processor/stdlib/amalgamated_stdlib.h",
+ ],
+ tool_files: [
+ "tools/gen_amalgamated_sql.py",
+ ],
+}
+
+// GN: //src/trace_processor/stdlib:stdlib
+filegroup {
+ name: "perfetto_src_trace_processor_stdlib_stdlib",
+}
+
// GN: //src/trace_processor:storage_full
filegroup {
name: "perfetto_src_trace_processor_storage_full",
@@ -11102,6 +11125,7 @@
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_sqlite_sqlite_minimal",
":perfetto_src_trace_processor_sqlite_unittests",
+ ":perfetto_src_trace_processor_stdlib_stdlib",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
":perfetto_src_trace_processor_storage_storage",
@@ -11322,6 +11346,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_traced_probes_ftrace_test_messages_cpp_gen_headers",
"perfetto_src_traced_probes_ftrace_test_messages_lite_gen_headers",
"perfetto_src_traced_probes_ftrace_test_messages_zero_gen_headers",
@@ -11736,6 +11761,7 @@
":perfetto_src_trace_processor_sqlite_functions_functions",
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_sqlite_sqlite_minimal",
+ ":perfetto_src_trace_processor_stdlib_stdlib",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
":perfetto_src_trace_processor_storage_storage",
@@ -11804,6 +11830,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
],
defaults: [
"perfetto_defaults",
@@ -11924,6 +11951,7 @@
":perfetto_src_trace_processor_sqlite_functions_functions",
":perfetto_src_trace_processor_sqlite_sqlite",
":perfetto_src_trace_processor_sqlite_sqlite_minimal",
+ ":perfetto_src_trace_processor_stdlib_stdlib",
":perfetto_src_trace_processor_storage_full",
":perfetto_src_trace_processor_storage_minimal",
":perfetto_src_trace_processor_storage_storage",
@@ -11996,6 +12024,7 @@
"perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
"perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
"perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
+ "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
"perfetto_src_traceconv_gen_cc_trace_descriptor",
],
defaults: [
diff --git a/BUILD b/BUILD
index 780a477..241398f 100644
--- a/BUILD
+++ b/BUILD
@@ -1379,9 +1379,9 @@
outs = [
"src/trace_processor/metrics/sql/amalgamated_sql_metrics.h",
],
- cmd = "$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)",
+ cmd = "$(location gen_amalgamated_sql_py) --type=METRICS --cpp_out=$@ $(SRCS)",
exec_tools = [
- ":gen_amalgamated_sql_metrics_py",
+ ":gen_amalgamated_sql_py",
],
)
@@ -1444,6 +1444,8 @@
"src/trace_processor/sqlite/functions/create_function_internal.h",
"src/trace_processor/sqlite/functions/create_view_function.cc",
"src/trace_processor/sqlite/functions/create_view_function.h",
+ "src/trace_processor/sqlite/functions/import.cc",
+ "src/trace_processor/sqlite/functions/import.h",
"src/trace_processor/sqlite/functions/pprof_functions.cc",
"src/trace_processor/sqlite/functions/pprof_functions.h",
"src/trace_processor/sqlite/functions/register_function.cc",
@@ -1490,6 +1492,28 @@
],
)
+perfetto_genrule(
+ name = "src_trace_processor_stdlib_gen_amalgamated_stdlib",
+ srcs = [
+ "src/trace_processor/stdlib/android/binder.sql",
+ ],
+ outs = [
+ "src/trace_processor/stdlib/amalgamated_stdlib.h",
+ ],
+ cmd = "$(location gen_amalgamated_sql_py) --type=LIB --cpp_out=$@ $(SRCS)",
+ exec_tools = [
+ ":gen_amalgamated_sql_py",
+ ],
+)
+
+# GN target: //src/trace_processor/stdlib:stdlib
+perfetto_filegroup(
+ name = "src_trace_processor_stdlib_stdlib",
+ srcs = [
+ "src/trace_processor/stdlib/utils.h",
+ ],
+)
+
# GN target: //src/trace_processor/storage:storage
perfetto_filegroup(
name = "src_trace_processor_storage_storage",
@@ -4254,6 +4278,7 @@
":src_trace_processor_sqlite_functions_functions",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_sqlite_sqlite_minimal",
+ ":src_trace_processor_stdlib_stdlib",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
":src_trace_processor_storage_storage",
@@ -4339,6 +4364,8 @@
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
":cc_amalgamated_sql_metrics",
+ ] + [
+ ":cc_amalgamated_stdlib",
] +
PERFETTO_CONFIG.deps.demangle_wrapper,
linkstatic = True,
@@ -4383,6 +4410,7 @@
":src_trace_processor_sqlite_functions_functions",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_sqlite_sqlite_minimal",
+ ":src_trace_processor_stdlib_stdlib",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
":src_trace_processor_storage_storage",
@@ -4461,6 +4489,8 @@
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
":cc_amalgamated_sql_metrics",
+ ] + [
+ ":cc_amalgamated_stdlib",
] +
PERFETTO_CONFIG.deps.demangle_wrapper,
)
@@ -4567,6 +4597,7 @@
":src_trace_processor_sqlite_functions_functions",
":src_trace_processor_sqlite_sqlite",
":src_trace_processor_sqlite_sqlite_minimal",
+ ":src_trace_processor_stdlib_stdlib",
":src_trace_processor_storage_full",
":src_trace_processor_storage_minimal",
":src_trace_processor_storage_storage",
@@ -4644,6 +4675,8 @@
PERFETTO_CONFIG.deps.sqlite_ext_percentile +
PERFETTO_CONFIG.deps.zlib + [
":cc_amalgamated_sql_metrics",
+ ] + [
+ ":cc_amalgamated_stdlib",
] +
PERFETTO_CONFIG.deps.demangle_wrapper,
)
@@ -4695,12 +4728,17 @@
hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
+perfetto_cc_library(
+ name = "cc_amalgamated_stdlib",
+ hdrs = ["src/trace_processor/stdlib/amalgamated_stdlib.h"],
+)
+
perfetto_py_binary(
- name = "gen_amalgamated_sql_metrics_py",
+ name = "gen_amalgamated_sql_py",
srcs = [
- "tools/gen_amalgamated_sql_metrics.py",
+ "tools/gen_amalgamated_sql.py",
],
- main = "tools/gen_amalgamated_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql.py",
python_version = "PY3",
)
diff --git a/BUILD.extras b/BUILD.extras
index f870aa6..5a11740 100644
--- a/BUILD.extras
+++ b/BUILD.extras
@@ -13,12 +13,17 @@
hdrs = ["src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"],
)
+perfetto_cc_library(
+ name = "cc_amalgamated_stdlib",
+ hdrs = ["src/trace_processor/stdlib/amalgamated_stdlib.h"],
+)
+
perfetto_py_binary(
- name = "gen_amalgamated_sql_metrics_py",
+ name = "gen_amalgamated_sql_py",
srcs = [
- "tools/gen_amalgamated_sql_metrics.py",
+ "tools/gen_amalgamated_sql.py",
],
- main = "tools/gen_amalgamated_sql_metrics.py",
+ main = "tools/gen_amalgamated_sql.py",
python_version = "PY3",
)
diff --git a/bazel/rules.bzl b/bazel/rules.bzl
index c2a649b..b699471 100644
--- a/bazel/rules.bzl
+++ b/bazel/rules.bzl
@@ -22,7 +22,7 @@
def default_cc_args():
return {
"deps": PERFETTO_CONFIG.deps.build_config,
- "copts": [
+ "copts": PERFETTO_CONFIG.default_copts + [
"-Wno-pragma-system-header-outside-header",
],
"includes": ["include"],
diff --git a/bazel/standalone/perfetto_cfg.bzl b/bazel/standalone/perfetto_cfg.bzl
index d1b77e4..ce2764e 100644
--- a/bazel/standalone/perfetto_cfg.bzl
+++ b/bazel/standalone/perfetto_cfg.bzl
@@ -125,4 +125,9 @@
go_proto_library = None,
),
+
+ # The default copts which we use to compile C++ code.
+ default_copts = [
+ "-std=c++17",
+ ]
)
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index 99627a2..023fa7d 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -705,11 +705,15 @@
]
configs -= [
- "//gn/standalone:c++11",
"//gn/standalone:extra_warnings",
"//gn/standalone:no_exceptions",
"//gn/standalone:no_rtti",
]
+ if (perfetto_cpp11_until_q1_2023) {
+ configs -= [ "//gn/standalone:c++11" ]
+ } else {
+ configs -= [ "//gn/standalone:c++17" ]
+ }
configs += [
":libc++config",
"//gn/standalone/sanitizers:sanitizer_options_link_helper",
@@ -804,11 +808,15 @@
configs += [ ":libc++winver" ]
}
configs -= [
- "//gn/standalone:c++11",
"//gn/standalone:extra_warnings",
"//gn/standalone:no_exceptions",
"//gn/standalone:no_rtti",
]
+ if (perfetto_cpp11_until_q1_2023) {
+ configs -= [ "//gn/standalone:c++11" ]
+ } else {
+ configs -= [ "//gn/standalone:c++17" ]
+ }
if ((is_android || is_mac) && !custom_libcxx_is_static) {
# Use libc++_perfetto to avoid conflicting with system libc++
output_name = "libc++_perfettto"
@@ -1190,17 +1198,18 @@
}
configs -= [
"//gn/standalone:extra_warnings",
- "//gn/standalone:c++11",
"//gn/standalone:visibility_hidden",
]
cflags = [ "-DFAKE_LOG_DEVICE=1" ]
if (!is_win) {
cflags += [ "-Wno-deprecated-declarations" ]
}
- public_configs = [
- ":libunwindstack_config",
- "//gn/standalone:c++17",
- ]
+ public_configs = [ ":libunwindstack_config" ]
+
+ if (perfetto_cpp11_until_q1_2023) {
+ configs -= [ "//gn/standalone:c++11" ]
+ public_configs += [ "//gn/standalone:c++17" ]
+ }
}
config("bionic_kernel_uapi_headers") {
@@ -1306,18 +1315,19 @@
include_dirs = [ "llvm-project/llvm/include" ]
}
-# NB: this is built under c++14 and linked into code that is c++11 by default.
-# We rely on the ABIs being compatible for this to be sane. At the time of
-# writing, the only c++14 specific code is behind an #ifndef NDEBUG, so we
-# could keep building as c++11 in non-debug builds, but we always use c++14 for
-# consistency.
source_set("llvm_demangle") {
visibility = _buildtools_visibility
- configs -= [
- "//gn/standalone:extra_warnings",
- "//gn/standalone:c++11",
- ]
- configs += [ "//gn/standalone:c++14" ]
+ configs -= [ "//gn/standalone:extra_warnings" ]
+
+ # NB: this is built under c++14 and linked into code that is c++11 by default.
+ # We rely on the ABIs being compatible for this to be sane. At the time of
+ # writing, the only c++14 specific code is behind an #ifndef NDEBUG, so we
+ # could keep building as c++11 in non-debug builds, but we always use c++14 for
+ # consistency.
+ if (perfetto_cpp11_until_q1_2023) {
+ configs -= [ "//gn/standalone:c++11" ]
+ configs += [ "//gn/standalone:c++14" ]
+ }
public_configs = [ ":llvm_demangle_config" ]
sources = [
"llvm-project/llvm/include/llvm/Demangle/Demangle.h",
diff --git a/docs/README.md b/docs/README.md
index 9152c0a..1ce43f8 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -82,7 +82,7 @@
to the Linux/Android tracing daemon through a UNIX socket, allowing to combine
app-specific instrumentation points with system-wide tracing events.
-The SDK is based on portable C++11 code [tested](/docs/contributing/testing.md)
+The SDK is based on portable C++17 code [tested](/docs/contributing/testing.md)
with the major C++ sanitizers (ASan, TSan, MSan, LSan). It doesn't rely on
run-time code modifications or compiler plugins.
@@ -109,7 +109,7 @@
dedicated project for importing, parsing and querying new and legacy trace
formats, [Trace Processor](/docs/analysis/trace-processor.md).
-Trace Processor is a portable C++11 library that provides column-oriented
+Trace Processor is a portable C++17 library that provides column-oriented
table storage, designed ad-hoc for efficiently holding hours of trace data
into memory and exposes a SQL query interface based on the popular SQLite query
engine.
diff --git a/docs/instrumentation/tracing-sdk.md b/docs/instrumentation/tracing-sdk.md
index 6bba47b..43261fb 100644
--- a/docs/instrumentation/tracing-sdk.md
+++ b/docs/instrumentation/tracing-sdk.md
@@ -1,6 +1,6 @@
# Tracing SDK
-The Perfetto Tracing SDK is a C++11 library that allows userspace applications
+The Perfetto Tracing SDK is a C++17 library that allows userspace applications
to emit trace events and add more app-specific context to a Perfetto trace.
When using the Tracing SDK there are two main aspects to consider:
@@ -35,7 +35,7 @@
The SDK consists of two files, `sdk/perfetto.h` and `sdk/perfetto.cc`. These are
an amalgamation of the Client API designed to easy to integrate to existing
-build systems. The sources are self-contained and require only a C++11 compliant
+build systems. The sources are self-contained and require only a C++17 compliant
standard library.
For example, to add the SDK to a CMake project, edit your CMakeLists.txt:
diff --git a/examples/sdk/README.md b/examples/sdk/README.md
index 31e7145..e25c308 100644
--- a/examples/sdk/README.md
+++ b/examples/sdk/README.md
@@ -8,7 +8,7 @@
Dependencies:
- [CMake](https://cmake.org/)
-- C++11
+- C++17
## Building
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index 0d17328..bd21589 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -111,6 +111,10 @@
}
config("c++11") {
+ if (!perfetto_cpp11_until_q1_2023) {
+ visibility = []
+ }
+
# C++11 is the default on Windows.
if (!is_win) {
cflags_cc = [ "-std=c++11" ]
@@ -118,11 +122,16 @@
# Enable standards-conforming compiler behavior.
cflags_cc = [ "/permissive-" ]
}
+ defines = [ "PERFETTO_ALLOW_SUB_CPP17" ]
}
# Used in buildtools dependencies for standalone builds.
config("c++14") {
- visibility = [ "//buildtools:llvm_demangle" ]
+ if (perfetto_cpp11_until_q1_2023) {
+ visibility = [ "//buildtools:llvm_demangle" ]
+ } else {
+ visibility = []
+ }
if (is_win) {
cflags_cc = [ "/std:c++14" ]
} else {
@@ -132,7 +141,9 @@
# Used in buildtools dependencies for standalone builds.
config("c++17") {
- visibility = [ "//buildtools:libunwindstack" ]
+ if (perfetto_cpp11_until_q1_2023) {
+ visibility = [ "//buildtools:libunwindstack" ]
+ }
if (is_win) {
cflags_cc = [ "/std:c++17" ]
} else {
@@ -196,6 +207,7 @@
"/Gy", # Enable function-level linking.
"/FS", # Preserve previous PDB behavior.
"/utf-8", # Assume UTF-8 by default to avoid code page dependencies.
+ "/Zc:__cplusplus", # Allow use of __cplusplus macro.
]
defines += [
"_CRT_NONSTDC_NO_WARNINGS",
@@ -237,9 +249,11 @@
not_needed([ "hermetic_clang_suppressions" ])
}
- if (is_clang && !is_hermetic_clang && !is_wasm) {
- cflags_cc += [ "-stdlib=" + non_hermetic_clang_stdlib ]
- ldflags += [ "-stdlib=" + non_hermetic_clang_stdlib ]
+ if (non_hermetic_clang_stdlib != "") {
+ if (is_clang && !is_hermetic_clang && !is_wasm) {
+ cflags_cc += [ "-stdlib=" + non_hermetic_clang_stdlib ]
+ ldflags += [ "-stdlib=" + non_hermetic_clang_stdlib ]
+ }
}
if (is_lto) {
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
index 6f32686..772161b 100644
--- a/gn/standalone/BUILDCONFIG.gn
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -17,6 +17,7 @@
is_clang = true
is_system_compiler = false
is_lto = false
+ perfetto_cpp11_until_q1_2023 = false
# This is defined here because it's needed below for determining the value of
# |is_cross_compiling|.
@@ -65,7 +66,6 @@
default_configs = [
"//gn/standalone:debug_symbols",
"//gn/standalone:default",
- "//gn/standalone:c++11",
"//gn/standalone:extra_warnings",
"//gn/standalone:no_exceptions",
"//gn/standalone:no_rtti",
@@ -74,6 +74,12 @@
"//gn/standalone/sanitizers:sanitizers_cflags",
]
+if (perfetto_cpp11_until_q1_2023) {
+ default_configs += [ "//gn/standalone:c++11" ]
+} else {
+ default_configs += [ "//gn/standalone:c++17" ]
+}
+
if (is_win) {
default_configs += [ "//gn/standalone:win32_lean_and_mean" ]
}
diff --git a/gn/standalone/toolchain/llvm.gni b/gn/standalone/toolchain/llvm.gni
index 3726411..13bae47 100644
--- a/gn/standalone/toolchain/llvm.gni
+++ b/gn/standalone/toolchain/llvm.gni
@@ -16,11 +16,7 @@
declare_args() {
is_hermetic_clang = is_clang && (is_linux_host || is_win_host)
- if (is_linux_host) {
- non_hermetic_clang_stdlib = "libstdc++"
- } else {
- non_hermetic_clang_stdlib = "libc++"
- }
+ non_hermetic_clang_stdlib = ""
}
assert(!is_hermetic_clang || is_clang, "is_hermetic_clang requires is_clang")
diff --git a/include/perfetto/base/compiler.h b/include/perfetto/base/compiler.h
index e95b676..c67e315 100644
--- a/include/perfetto/base/compiler.h
+++ b/include/perfetto/base/compiler.h
@@ -23,6 +23,22 @@
#include "perfetto/base/build_config.h"
#include "perfetto/public/compiler.h"
+#if __cplusplus >= 201703
+#define PERFETTO_IS_AT_LEAST_CPP17() 1
+#else
+#define PERFETTO_IS_AT_LEAST_CPP17() 0
+#endif
+
+#if !PERFETTO_IS_AT_LEAST_CPP17() && !defined(PERFETTO_ALLOW_SUB_CPP17)
+#error Perfetto is exploring a switch to C++17 in v34 (Feb 2023). During this \
+transitionary period, we are throwing an error when compiling Perfetto \
+with a standard less than C++17. Please reach out to \
+perfetto-dev@googlegroups.com if you have objections or thoughts on \
+this move. To continue compiling this release of Perfetto with \
+C++11/14, specify the define PERFETTO_ALLOW_SUB_CPP17. \
+*Note*: this define *will* stop working in v34 (Feb 2023).
+#endif
+
// __has_attribute is supported only by clang and recent versions of GCC.
// Add a layer to wrap the __has_attribute macro.
#if defined(__has_attribute)
diff --git a/include/perfetto/trace_processor/basic_types.h b/include/perfetto/trace_processor/basic_types.h
index 7cfff9d..fd5539b 100644
--- a/include/perfetto/trace_processor/basic_types.h
+++ b/include/perfetto/trace_processor/basic_types.h
@@ -77,7 +77,8 @@
enum class DropFtraceDataBefore {
// Drops ftrace data before timestmap specified by the
// TracingServiceEvent::tracing_started packet. If this packet is not in the
- // trace, no data is dropped.
+ // trace, no data is dropped. If preserve_ftrace_buffer (from the trace
+ // config) is set, no data is dropped.
// Note: this event was introduced in S+ so no data will be dropped on R-
// traces.
// This is the default approach.
diff --git a/include/perfetto/tracing/internal/track_event_macros.h b/include/perfetto/tracing/internal/track_event_macros.h
index d4e1017..3e91f96 100644
--- a/include/perfetto/tracing/internal/track_event_macros.h
+++ b/include/perfetto/tracing/internal/track_event_macros.h
@@ -144,6 +144,14 @@
} \
} while (false)
+// C++17 doesn't like a move constructor being defined for the EventFinalizer
+// class but C++11 doesn't compile without it being defined so support both.
+#if PERFETTO_IS_AT_LEAST_CPP17()
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD delete
+#else
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD default
+#endif
+
#define PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ...) \
struct PERFETTO_UID(ScopedEvent) { \
struct EventFinalizer { \
@@ -160,7 +168,8 @@
EventFinalizer(const EventFinalizer&) = delete; \
inline EventFinalizer& operator=(const EventFinalizer&) = delete; \
\
- EventFinalizer(EventFinalizer&&) = default; \
+ EventFinalizer(EventFinalizer&&) = \
+ PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD; \
EventFinalizer& operator=(EventFinalizer&&) = delete; \
} finalizer; \
} PERFETTO_UID(scoped_event) { \
diff --git a/infra/ci/config.py b/infra/ci/config.py
index ba8bf93..7a10502 100755
--- a/infra/ci/config.py
+++ b/infra/ci/config.py
@@ -66,10 +66,10 @@
# Only variables starting with PERFETTO_ are propagated into the sandbox.
JOB_CONFIGS = {
'linux-clang-x86_64-debug': {
- 'PERFETTO_TEST_GN_ARGS':
- 'is_debug=true is_hermetic_clang=false non_hermetic_clang_stdlib="libc++"',
- 'PERFETTO_TEST_SCRIPT':
- 'test/ci/linux_tests.sh',
+ 'PERFETTO_TEST_GN_ARGS': 'is_debug=true is_hermetic_clang=false '
+ 'non_hermetic_clang_stdlib="libc++" '
+ 'perfetto_cpp11_until_q1_2023=true',
+ 'PERFETTO_TEST_SCRIPT': 'test/ci/linux_tests.sh',
},
'linux-clang-x86_64-tsan': {
'PERFETTO_TEST_GN_ARGS': 'is_debug=false is_tsan=true',
diff --git a/meson.build b/meson.build
index 5295c52..5ef6fce 100644
--- a/meson.build
+++ b/meson.build
@@ -19,7 +19,7 @@
project(
'perfetto',
['cpp'],
- default_options: ['cpp_std=c++11']
+ default_options: ['cpp_std=c++17']
)
fs = import('fs')
diff --git a/protos/perfetto/config/ftrace/ftrace_config.proto b/protos/perfetto/config/ftrace/ftrace_config.proto
index 24727ed..f1267d0 100644
--- a/protos/perfetto/config/ftrace/ftrace_config.proto
+++ b/protos/perfetto/config/ftrace/ftrace_config.proto
@@ -18,7 +18,7 @@
package perfetto.protos;
-// Next id: 23.
+// Next id: 24.
message FtraceConfig {
repeated string ftrace_events = 1;
repeated string atrace_categories = 2;
@@ -152,4 +152,11 @@
// * Available only on debuggable builds.
// * Introduced in: Android U.
repeated string function_graph_roots = 21;
+
+ // If true, does not clear ftrace buffers before the start of the program.
+ // This makes sense only if this is the first ftrace data source instance
+ // created after the daemon has been started. Can be useful for gathering boot
+ // traces, if ftrace has been separately configured (e.g. via kernel
+ // commandline).
+ optional bool preserve_ftrace_buffer = 23;
}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index d991280..a30527c 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -466,7 +466,7 @@
// Begin of protos/perfetto/config/ftrace/ftrace_config.proto
-// Next id: 23.
+// Next id: 24.
message FtraceConfig {
repeated string ftrace_events = 1;
repeated string atrace_categories = 2;
@@ -600,6 +600,13 @@
// * Available only on debuggable builds.
// * Introduced in: Android U.
repeated string function_graph_roots = 21;
+
+ // If true, does not clear ftrace buffers before the start of the program.
+ // This makes sense only if this is the first ftrace data source instance
+ // created after the daemon has been started. Can be useful for gathering boot
+ // traces, if ftrace has been separately configured (e.g. via kernel
+ // commandline).
+ optional bool preserve_ftrace_buffer = 23;
}
// End of protos/perfetto/config/ftrace/ftrace_config.proto
diff --git a/protos/perfetto/trace/ftrace/ftrace_stats.proto b/protos/perfetto/trace/ftrace/ftrace_stats.proto
index 9f26fa3..fac68b0 100644
--- a/protos/perfetto/trace/ftrace/ftrace_stats.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_stats.proto
@@ -92,4 +92,8 @@
// failed to enable due to permissions, or due to a conflicting option
// (currently FtraceConfig.disable_generic_events).
repeated string failed_ftrace_events = 7;
+
+ // The data source was configured to preserve existing events in the ftrace
+ // buffer before the start of the trace.
+ optional bool preserve_ftrace_buffer = 8;
}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 6e01ded..251c12b 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -466,7 +466,7 @@
// Begin of protos/perfetto/config/ftrace/ftrace_config.proto
-// Next id: 23.
+// Next id: 24.
message FtraceConfig {
repeated string ftrace_events = 1;
repeated string atrace_categories = 2;
@@ -600,6 +600,13 @@
// * Available only on debuggable builds.
// * Introduced in: Android U.
repeated string function_graph_roots = 21;
+
+ // If true, does not clear ftrace buffers before the start of the program.
+ // This makes sense only if this is the first ftrace data source instance
+ // created after the daemon has been started. Can be useful for gathering boot
+ // traces, if ftrace has been separately configured (e.g. via kernel
+ // commandline).
+ optional bool preserve_ftrace_buffer = 23;
}
// End of protos/perfetto/config/ftrace/ftrace_config.proto
@@ -7933,6 +7940,10 @@
// failed to enable due to permissions, or due to a conflicting option
// (currently FtraceConfig.disable_generic_events).
repeated string failed_ftrace_events = 7;
+
+ // The data source was configured to preserve existing events in the ftrace
+ // buffer before the start of the trace.
+ optional bool preserve_ftrace_buffer = 8;
}
// End of protos/perfetto/trace/ftrace/ftrace_stats.proto
diff --git a/src/base/metatrace.cc b/src/base/metatrace.cc
index c676d80..1464ed3 100644
--- a/src/base/metatrace.cc
+++ b/src/base/metatrace.cc
@@ -29,7 +29,6 @@
std::atomic<uint64_t> g_enabled_timestamp{0};
// static members
-constexpr size_t RingBuffer::kCapacity;
std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
std::atomic<bool> RingBuffer::read_task_queued_;
std::atomic<uint64_t> RingBuffer::wr_index_;
@@ -37,9 +36,12 @@
std::atomic<bool> RingBuffer::has_overruns_;
Record RingBuffer::bankruptcy_record_;
+#if !PERFETTO_IS_AT_LEAST_CPP17()
+constexpr size_t RingBuffer::kCapacity;
constexpr uint16_t Record::kTypeMask;
constexpr uint16_t Record::kTypeCounter;
constexpr uint16_t Record::kTypeEvent;
+#endif
namespace {
diff --git a/src/protozero/packed_repeated_fields.cc b/src/protozero/packed_repeated_fields.cc
index b0e23c5..16d4539 100644
--- a/src/protozero/packed_repeated_fields.cc
+++ b/src/protozero/packed_repeated_fields.cc
@@ -20,8 +20,10 @@
namespace protozero {
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr size_t PackedBufferBase::kOnStackStorageSize;
+#endif
void PackedBufferBase::GrowSlowpath() {
size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 9b1cc09..d815d04 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -367,6 +367,7 @@
"metrics",
"sqlite",
"sqlite/functions",
+ "stdlib",
"storage",
"tables",
"types",
diff --git a/src/trace_processor/containers/string_pool.cc b/src/trace_processor/containers/string_pool.cc
index 0189054..0ca5d0b 100644
--- a/src/trace_processor/containers/string_pool.cc
+++ b/src/trace_processor/containers/string_pool.cc
@@ -24,6 +24,7 @@
namespace perfetto {
namespace trace_processor {
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr size_t StringPool::kNumBlockIndexBits;
// static
@@ -38,6 +39,7 @@
constexpr size_t StringPool::kBlockSizeBytes;
// static
constexpr size_t StringPool::kMinLargeStringSizeBytes;
+#endif
StringPool::StringPool() {
static_assert(
diff --git a/src/trace_processor/importers/common/args_translation_table.cc b/src/trace_processor/importers/common/args_translation_table.cc
index 1e4e22f..b35f427 100644
--- a/src/trace_processor/importers/common/args_translation_table.cc
+++ b/src/trace_processor/importers/common/args_translation_table.cc
@@ -49,6 +49,7 @@
} // namespace
+#if !PERFETTO_IS_AT_LEAST_CPP17()
constexpr char ArgsTranslationTable::kChromeHistogramHashKey[];
constexpr char ArgsTranslationTable::kChromeHistogramNameKey[];
@@ -65,6 +66,7 @@
constexpr char ArgsTranslationTable::kMojoMethodRelPcKey[];
constexpr char ArgsTranslationTable::kMojoMethodNameKey[];
constexpr char ArgsTranslationTable::kMojoIntefaceTagKey[];
+#endif
ArgsTranslationTable::ArgsTranslationTable(TraceStorage* storage)
: storage_(storage),
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 691f170..766c345 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -502,6 +502,9 @@
auto error_str_id = storage->InternString(base::StringView(error_str));
context_->metadata_tracker->SetMetadata(metadata::ftrace_setup_errors,
Variadic::String(error_str_id));
+ if (evt.preserve_ftrace_buffer()) {
+ preserve_ftrace_buffer_ = true;
+ }
}
}
@@ -1002,7 +1005,10 @@
if (PERFETTO_LIKELY(has_seen_first_ftrace_packet_)) {
return;
}
- DropFtraceDataBefore drop_before = context_->config.drop_ftrace_data_before;
+
+ DropFtraceDataBefore drop_before =
+ preserve_ftrace_buffer_ ? DropFtraceDataBefore::kNoDrop
+ : context_->config.drop_ftrace_data_before;
switch (drop_before) {
case DropFtraceDataBefore::kNoDrop: {
drop_ftrace_data_before_ts_ = 0;
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.h b/src/trace_processor/importers/ftrace/ftrace_parser.h
index 65a66d1..361d31f 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.h
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.h
@@ -367,6 +367,9 @@
// Stores information about the timestamp from the metadata table which is
// used to filter ftrace packets which happen before this point.
int64_t drop_ftrace_data_before_ts_ = 0;
+
+ // Does not skip any ftrace events.
+ bool preserve_ftrace_buffer_ = false;
};
} // namespace trace_processor
diff --git a/src/trace_processor/importers/proto/track_event_tracker.cc b/src/trace_processor/importers/proto/track_event_tracker.cc
index 6497df1..c37eccd 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.cc
+++ b/src/trace_processor/importers/proto/track_event_tracker.cc
@@ -24,8 +24,10 @@
namespace perfetto {
namespace trace_processor {
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr uint64_t TrackEventTracker::kDefaultDescriptorTrackUuid;
+#endif
TrackEventTracker::TrackEventTracker(TraceProcessorContext* context)
: source_key_(context->storage->InternString("source")),
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index fe0d4a0..28ba43c 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -169,7 +169,7 @@
"chrome/touch_jank.sql",
]
-experiemntal_sql_files = [
+experimental_sql_files = [
"experimental/blink_gc_metric.sql",
"experimental/chrome_dropped_frames.sql",
"experimental/chrome_long_latency.sql",
@@ -185,7 +185,7 @@
"webview/webview_power_usage.sql",
]
-sql_files = android_sql_files + chrome_sql_files + experiemntal_sql_files +
+sql_files = android_sql_files + chrome_sql_files + experimental_sql_files +
other_sql_files
config("gen_config") {
@@ -193,9 +193,10 @@
}
action("gen_amalgamated_sql_metrics") {
- script = "../../../../tools/gen_amalgamated_sql_metrics.py"
+ script = "../../../../tools/gen_amalgamated_sql.py"
generated_header = "${target_gen_dir}/amalgamated_sql_metrics.h"
args = rebase_path(sql_files, root_build_dir) + [
+ "--type=METRICS",
"--cpp_out",
rebase_path(generated_header, root_build_dir),
]
diff --git a/src/trace_processor/sqlite/functions/BUILD.gn b/src/trace_processor/sqlite/functions/BUILD.gn
index a4f9e1f..3671615 100644
--- a/src/trace_processor/sqlite/functions/BUILD.gn
+++ b/src/trace_processor/sqlite/functions/BUILD.gn
@@ -23,6 +23,8 @@
"create_function_internal.h",
"create_view_function.cc",
"create_view_function.h",
+ "import.cc",
+ "import.h",
"pprof_functions.cc",
"pprof_functions.h",
"register_function.cc",
@@ -46,6 +48,7 @@
"../../db",
"../../dynamic",
"../../importers/common",
+ "../../stdlib:stdlib",
"../../storage",
"../../types",
"../../util",
diff --git a/src/trace_processor/sqlite/functions/import.cc b/src/trace_processor/sqlite/functions/import.cc
new file mode 100644
index 0000000..971cf0c
--- /dev/null
+++ b/src/trace_processor/sqlite/functions/import.cc
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/sqlite/functions/import.h"
+
+#include <numeric>
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/trace_processor/basic_types.h"
+#include "src/trace_processor/sqlite/functions/create_function_internal.h"
+#include "src/trace_processor/sqlite/scoped_db.h"
+#include "src/trace_processor/sqlite/sqlite_table.h"
+#include "src/trace_processor/sqlite/sqlite_utils.h"
+#include "src/trace_processor/tp_metatrace.h"
+#include "src/trace_processor/util/status_macros.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+base::Status Import::Run(Import::Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue&,
+ Destructors&) {
+ if (argc != 1) {
+ return base::ErrStatus(
+ "IMPORT: invalid number of args; expected 1, received "
+ "%zu",
+ argc);
+ }
+ sqlite3_value* path_val = argv[0];
+
+ // Type check
+ {
+ base::Status status =
+ TypeCheckSqliteValue(path_val, SqlValue::Type::kString);
+ if (!status.ok()) {
+ return base::ErrStatus("IMPORT(%s): %s", sqlite3_value_text(path_val),
+ status.c_message());
+ }
+ }
+
+ const char* path =
+ reinterpret_cast<const char*>(sqlite3_value_text(path_val));
+
+ auto lib_file = ctx->path_to_lib_file.Find(std::string(path));
+ if (!lib_file) {
+ return base::ErrStatus("IMPORT: Unknown filename provided - %s", path);
+ }
+ // IMPORT is noop for already imported files.
+ if (lib_file->imported) {
+ return base::OkStatus();
+ }
+
+ auto import_iter = ctx->tp->ExecuteQuery(lib_file->sql);
+ bool import_has_more = import_iter.Next();
+ if (import_has_more)
+ return base::ErrStatus("IMPORT: Imported file returning values.");
+ {
+ auto status = import_iter.Status();
+ if (!status.ok())
+ return base::ErrStatus("SQLite error on IMPORT: %s", status.c_message());
+ }
+
+ lib_file->imported = true;
+ return base::OkStatus();
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/sqlite/functions/import.h b/src/trace_processor/sqlite/functions/import.h
new file mode 100644
index 0000000..be20926
--- /dev/null
+++ b/src/trace_processor/sqlite/functions/import.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_SQLITE_FUNCTIONS_IMPORT_H_
+#define SRC_TRACE_PROCESSOR_SQLITE_FUNCTIONS_IMPORT_H_
+
+#include <sqlite3.h>
+#include <string>
+#include <unordered_map>
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/trace_processor/trace_processor.h"
+#include "src/trace_processor/sqlite/functions/register_function.h"
+#include "src/trace_processor/stdlib/utils.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+struct Import : public SqlFunction {
+ struct Context {
+ sqlite3* db;
+ TraceProcessor* tp;
+ base::FlatHashMap<std::string, stdlib::LibFile> path_to_lib_file;
+ };
+
+ static constexpr bool kVoidReturn = true;
+
+ static base::Status Run(Context* ctx,
+ size_t argc,
+ sqlite3_value** argv,
+ SqlValue& out,
+ Destructors&);
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_SQLITE_FUNCTIONS_IMPORT_H_
diff --git a/src/trace_processor/sqlite/sqlite_utils_unittest.cc b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
index 5d85383..1d1de13 100644
--- a/src/trace_processor/sqlite/sqlite_utils_unittest.cc
+++ b/src/trace_processor/sqlite/sqlite_utils_unittest.cc
@@ -16,7 +16,6 @@
#include "src/trace_processor/sqlite/sqlite_utils.h"
-#include "gtest/gtest.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
diff --git a/src/trace_processor/stdlib/BUILD.gn b/src/trace_processor/stdlib/BUILD.gn
new file mode 100644
index 0000000..7d186ca
--- /dev/null
+++ b/src/trace_processor/stdlib/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../gn/perfetto.gni")
+import("android/sql_files.gni")
+
+config("gen_config") {
+ include_dirs = [ "${root_gen_dir}/${perfetto_root_path}" ]
+}
+
+sql_files = android_sql_files
+
+action("gen_amalgamated_stdlib") {
+ script = "../../../tools/gen_amalgamated_sql.py"
+ generated_header = "${target_gen_dir}/amalgamated_stdlib.h"
+ args = rebase_path(sql_files, root_build_dir) + [
+ "--type=LIB",
+ "--cpp_out",
+ rebase_path(generated_header, root_build_dir),
+ ]
+ inputs = sql_files
+ outputs = [ generated_header ]
+ public_configs = [ ":gen_config" ]
+}
+if (enable_perfetto_trace_processor_sqlite) {
+ source_set("stdlib") {
+ sources = [ "utils.h" ]
+ deps = [ ":gen_amalgamated_stdlib" ]
+ }
+}
diff --git a/src/trace_processor/stdlib/android/binder.sql b/src/trace_processor/stdlib/android/binder.sql
new file mode 100644
index 0000000..261916e
--- /dev/null
+++ b/src/trace_processor/stdlib/android/binder.sql
@@ -0,0 +1,33 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+-- Count Binder transactions per process
+DROP VIEW IF EXISTS binder_metrics_by_process;
+CREATE VIEW binder_metrics_by_process AS
+SELECT
+ process.name as process_name,
+ process.pid as pid,
+ slice.name as slice_name,
+ COUNT(*) as event_count
+FROM slice
+ INNER JOIN thread_track ON slice.track_id=thread_track.id
+ INNER JOIN thread ON thread.utid=thread_track.utid
+ INNER JOIN process ON thread.upid=process.upid
+WHERE
+ slice.name glob 'binder*'
+GROUP BY
+ process_name,
+ slice_name;
diff --git a/src/trace_processor/stdlib/android/sql_files.gni b/src/trace_processor/stdlib/android/sql_files.gni
new file mode 100644
index 0000000..4304349
--- /dev/null
+++ b/src/trace_processor/stdlib/android/sql_files.gni
@@ -0,0 +1,16 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Keep this list sorted.
+android_sql_files = [ "android/binder.sql" ]
diff --git a/src/trace_processor/stdlib/utils.h b/src/trace_processor/stdlib/utils.h
new file mode 100644
index 0000000..a61a669
--- /dev/null
+++ b/src/trace_processor/stdlib/utils.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_STDLIB_UTILS_H_
+#define SRC_TRACE_PROCESSOR_STDLIB_UTILS_H_
+
+#include <string>
+
+#include "perfetto/ext/base/flat_hash_map.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_view.h"
+#include "src/trace_processor/stdlib/amalgamated_stdlib.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace stdlib {
+
+struct LibFile {
+ std::string sql;
+ bool imported;
+};
+
+inline std::string ReplaceSlashWithDot(std::string str) {
+ size_t found = str.find('/');
+ while (found != std::string::npos) {
+ str.replace(found, 1, ".");
+ found = str.find('/');
+ }
+ return str;
+}
+
+inline std::string GetImportKey(std::string root, std::string path) {
+ base::StringView path_view(path);
+ auto path_no_extension = path_view.substr(0, path_view.rfind('.'));
+ return ReplaceSlashWithDot(root) + "." +
+ ReplaceSlashWithDot(path_no_extension.ToStdString());
+}
+
+inline base::FlatHashMap<std::string, LibFile> SetupStdLib() {
+ base::FlatHashMap<std::string, LibFile> lib_files;
+ for (const auto& file_to_sql : stdlib::kFileToSql) {
+ lib_files.Insert(GetImportKey(stdlib::kRootPath, file_to_sql.path),
+ {file_to_sql.sql, false});
+ }
+ return lib_files;
+}
+
+} // namespace stdlib
+} // namespace trace_processor
+} // namespace perfetto
+#endif // SRC_TRACE_PROCESSOR_STDLIB_UTILS_H_
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 558b27a..4ea7a55 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -52,6 +52,7 @@
#include "src/trace_processor/iterator_impl.h"
#include "src/trace_processor/sqlite/functions/create_function.h"
#include "src/trace_processor/sqlite/functions/create_view_function.h"
+#include "src/trace_processor/sqlite/functions/import.h"
#include "src/trace_processor/sqlite/functions/pprof_functions.h"
#include "src/trace_processor/sqlite/functions/register_function.h"
#include "src/trace_processor/sqlite/functions/sqlite3_str_split.h"
@@ -65,6 +66,7 @@
#include "src/trace_processor/sqlite/sqlite_utils.h"
#include "src/trace_processor/sqlite/stats_table.h"
#include "src/trace_processor/sqlite/window_operator_table.h"
+#include "src/trace_processor/stdlib/utils.h"
#include "src/trace_processor/tp_metatrace.h"
#include "src/trace_processor/types/variadic.h"
#include "src/trace_processor/util/protozero_to_text.h"
@@ -705,6 +707,9 @@
db, "CREATE_VIEW_FUNCTION", 3,
std::unique_ptr<CreateViewFunction::Context>(
new CreateViewFunction::Context{db_.get()}));
+ RegisterFunction<Import>(db, "IMPORT", 1,
+ std::unique_ptr<Import::Context>(new Import::Context{
+ db_.get(), this, stdlib::SetupStdLib()}));
// Old style function registration.
// TODO(lalitm): migrate this over to using RegisterFunction once aggregate
@@ -1001,8 +1006,8 @@
}
}
- // Check if the metric with the given path already exists and if it does, just
- // update the SQL associated with it.
+ // Check if the metric with the given path already exists and if it does,
+ // just update the SQL associated with it.
auto it = std::find_if(
sql_metrics_.begin(), sql_metrics_.end(),
[&path](const metrics::SqlMetricFile& m) { return m.path == path; });
@@ -1040,7 +1045,8 @@
const auto& prev_path = field_it_and_inserted.first->second;
PERFETTO_DCHECK(prev_path != path);
return base::ErrStatus(
- "RegisterMetric Error: Metric paths %s (which is already registered) "
+ "RegisterMetric Error: Metric paths %s (which is already "
+ "registered) "
"and %s are both trying to output the proto field %s",
prev_path.c_str(), path.c_str(), metric.proto_field_name->c_str());
}
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index 7a4ecb8..49192e5 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -29,6 +29,7 @@
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/status.h"
#include "perfetto/trace_processor/trace_processor.h"
+#include "sqlite/functions/import.h"
#include "src/trace_processor/sqlite/db_sqlite_table.h"
#include "src/trace_processor/sqlite/functions/create_function.h"
#include "src/trace_processor/sqlite/functions/create_view_function.h"
diff --git a/src/trace_processor/trace_sorter_queue_unittest.cc b/src/trace_processor/trace_sorter_queue_unittest.cc
index b233fe7..d013c91 100644
--- a/src/trace_processor/trace_sorter_queue_unittest.cc
+++ b/src/trace_processor/trace_sorter_queue_unittest.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "src/trace_processor/trace_sorter_queue.h"
-#include "gtest/gtest.h"
+
#include "src/trace_processor/types/variadic.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/trace_processor/types/variadic.cc b/src/trace_processor/types/variadic.cc
index 837bfeb..9a26bd5 100644
--- a/src/trace_processor/types/variadic.cc
+++ b/src/trace_processor/types/variadic.cc
@@ -19,7 +19,9 @@
namespace perfetto {
namespace trace_processor {
+#if !PERFETTO_IS_AT_LEAST_CPP17()
constexpr const char* Variadic::kTypeNames[];
+#endif
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/traced/probes/ftrace/cpu_reader_benchmark.cc b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
index a22fc1b..fff4e78 100644
--- a/src/traced/probes/ftrace/cpu_reader_benchmark.cc
+++ b/src/traced/probes/ftrace/cpu_reader_benchmark.cc
@@ -575,7 +575,8 @@
base::nullopt,
{},
{},
- false /*symbolize_ksyms*/};
+ false /*symbolize_ksyms*/,
+ false /*preserve_ftrace_buffer*/};
if (print_filter.has_value()) {
ds_config.print_filter =
FtracePrintFilterConfig::Create(print_filter.value(), table);
diff --git a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
index 04891a3..52a986d 100644
--- a/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
+++ b/src/traced/probes/ftrace/cpu_reader_fuzzer.cc
@@ -60,7 +60,8 @@
base::nullopt,
{},
{},
- /*symbolize_ksyms=*/false};
+ /*symbolize_ksyms=*/false,
+ /*preserve_ftrace_buffer=*/false};
ds_config.event_filter.AddEnabledEvent(
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
ds_config.event_filter.AddEnabledEvent(
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index 2f8061f..1b14a82 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -69,7 +69,8 @@
base::nullopt,
{},
{},
- false /*symbolize_ksyms*/};
+ false /*symbolize_ksyms*/,
+ false /*preserve_ftrace_buffer*/};
}
constexpr uint64_t kNanoInSecond = 1000 * 1000 * 1000;
@@ -947,7 +948,8 @@
base::nullopt,
{},
{},
- false /* symbolize_ksyms*/};
+ false /* symbolize_ksyms*/,
+ false /*preserve_ftrace_buffer*/};
ds_config.event_filter.AddEnabledEvent(
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.cc b/src/traced/probes/ftrace/ftrace_config_muxer.cc
index ff807bc..82a0f11 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.cc
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.cc
@@ -571,14 +571,16 @@
PERFETTO_DCHECK(active_configs_.empty());
// If someone outside of perfetto is using ftrace give up now.
- if (is_ftrace_enabled && !IsOldAtrace()) {
+ if (!request.preserve_ftrace_buffer() && is_ftrace_enabled &&
+ !IsOldAtrace()) {
PERFETTO_ELOG("ftrace in use by non-Perfetto.");
return 0;
}
// Setup ftrace, without starting it. Setting buffers can be quite slow
// (up to hundreds of ms).
- SetupClock(request);
+ if (!request.preserve_ftrace_buffer())
+ SetupClock(request);
SetupBufferSize(request);
} else {
// Did someone turn ftrace off behind our back? If so give up.
@@ -709,7 +711,8 @@
std::forward_as_tuple(std::move(filter), std::move(syscall_filter),
compact_sched, std::move(ftrace_print_filter),
std::move(apps), std::move(categories),
- request.symbolize_ksyms()));
+ request.symbolize_ksyms(),
+ request.preserve_ftrace_buffer()));
return id;
}
@@ -720,7 +723,8 @@
}
if (active_configs_.empty()) {
- if (ftrace_->IsTracingEnabled() && !IsOldAtrace()) {
+ if (!ds_configs_.at(id).preserve_ftrace_buffer &&
+ ftrace_->IsTracingEnabled() && !IsOldAtrace()) {
// If someone outside of perfetto is using ftrace give up now.
PERFETTO_ELOG("ftrace in use by non-Perfetto.");
return false;
diff --git a/src/traced/probes/ftrace/ftrace_config_muxer.h b/src/traced/probes/ftrace/ftrace_config_muxer.h
index 5fe66ae..50a5e4f 100644
--- a/src/traced/probes/ftrace/ftrace_config_muxer.h
+++ b/src/traced/probes/ftrace/ftrace_config_muxer.h
@@ -47,14 +47,16 @@
base::Optional<FtracePrintFilterConfig> _print_filter,
std::vector<std::string> _atrace_apps,
std::vector<std::string> _atrace_categories,
- bool _symbolize_ksyms)
+ bool _symbolize_ksyms,
+ bool _preserve_ftrace_buffer)
: event_filter(std::move(_event_filter)),
syscall_filter(std::move(_syscall_filter)),
compact_sched(_compact_sched),
print_filter(std::move(_print_filter)),
atrace_apps(std::move(_atrace_apps)),
atrace_categories(std::move(_atrace_categories)),
- symbolize_ksyms(_symbolize_ksyms) {}
+ symbolize_ksyms(_symbolize_ksyms),
+ preserve_ftrace_buffer(_preserve_ftrace_buffer) {}
// The event filter allows to quickly check if a certain ftrace event with id
// x is enabled for this data source.
@@ -77,6 +79,9 @@
// When enabled will turn on the kallsyms symbolizer in CpuReader.
const bool symbolize_ksyms;
+
+ // Does not clear previous traces.
+ const bool preserve_ftrace_buffer;
};
// Ftrace is a bunch of globally modifiable persistent state.
diff --git a/src/traced/probes/ftrace/ftrace_controller.cc b/src/traced/probes/ftrace/ftrace_controller.cc
index 64ed5db..d7ad539 100644
--- a/src/traced/probes/ftrace/ftrace_controller.cc
+++ b/src/traced/probes/ftrace/ftrace_controller.cc
@@ -139,9 +139,10 @@
// static
std::unique_ptr<FtraceController> FtraceController::Create(
base::TaskRunner* runner,
- Observer* observer) {
+ Observer* observer,
+ bool preserve_ftrace_buffer) {
std::unique_ptr<FtraceProcfs> ftrace_procfs =
- FtraceProcfs::CreateGuessingMountPoint();
+ FtraceProcfs::CreateGuessingMountPoint("", preserve_ftrace_buffer);
if (!ftrace_procfs)
return nullptr;
@@ -172,16 +173,17 @@
std::unique_ptr<FtraceConfigMuxer> model =
std::unique_ptr<FtraceConfigMuxer>(new FtraceConfigMuxer(
ftrace_procfs.get(), table.get(), std::move(syscalls), vendor_evts));
- return std::unique_ptr<FtraceController>(
- new FtraceController(std::move(ftrace_procfs), std::move(table),
- std::move(model), runner, observer));
+ return std::unique_ptr<FtraceController>(new FtraceController(
+ std::move(ftrace_procfs), std::move(table), std::move(model), runner,
+ observer, preserve_ftrace_buffer));
}
FtraceController::FtraceController(std::unique_ptr<FtraceProcfs> ftrace_procfs,
std::unique_ptr<ProtoTranslationTable> table,
std::unique_ptr<FtraceConfigMuxer> model,
base::TaskRunner* task_runner,
- Observer* observer)
+ Observer* observer,
+ bool preserve_ftrace_buffer)
: task_runner_(task_runner),
observer_(observer),
symbolizer_(new LazyKernelSymbolizer()),
@@ -189,6 +191,7 @@
table_(std::move(table)),
ftrace_config_muxer_(std::move(model)),
ftrace_clock_snapshot_(new FtraceClockSnapshot()),
+ preserve_ftrace_buffer_(preserve_ftrace_buffer),
weak_factory_(this) {}
FtraceController::~FtraceController() {
diff --git a/src/traced/probes/ftrace/ftrace_controller.h b/src/traced/probes/ftrace/ftrace_controller.h
index e27f465..9a8ec2b 100644
--- a/src/traced/probes/ftrace/ftrace_controller.h
+++ b/src/traced/probes/ftrace/ftrace_controller.h
@@ -72,7 +72,9 @@
};
// The passed Observer must outlive the returned FtraceController instance.
- static std::unique_ptr<FtraceController> Create(base::TaskRunner*, Observer*);
+ static std::unique_ptr<FtraceController> Create(base::TaskRunner*,
+ Observer*,
+ bool preserve_ftrace_buffer);
virtual ~FtraceController();
void DisableAllEvents();
@@ -98,7 +100,8 @@
std::unique_ptr<ProtoTranslationTable>,
std::unique_ptr<FtraceConfigMuxer>,
base::TaskRunner*,
- Observer*);
+ Observer*,
+ bool);
// Protected and virtual for testing.
virtual uint64_t NowMs() const;
@@ -138,6 +141,7 @@
int generation_ = 0;
bool atrace_running_ = false;
bool retain_ksyms_on_stop_ = false;
+ bool preserve_ftrace_buffer_ = false;
std::vector<PerCpuState> per_cpu_; // empty if tracing isn't active
std::set<FtraceDataSource*> data_sources_;
std::set<FtraceDataSource*> started_data_sources_;
diff --git a/src/traced/probes/ftrace/ftrace_controller_unittest.cc b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
index b521274..a9ad430 100644
--- a/src/traced/probes/ftrace/ftrace_controller_unittest.cc
+++ b/src/traced/probes/ftrace/ftrace_controller_unittest.cc
@@ -175,7 +175,8 @@
std::move(table),
std::move(model),
runner.get(),
- /*observer=*/this),
+ /*observer=*/this,
+ false),
runner_(std::move(runner)),
procfs_(raw_procfs) {}
diff --git a/src/traced/probes/ftrace/ftrace_data_source.cc b/src/traced/probes/ftrace/ftrace_data_source.cc
index 32f945e..7c051fb 100644
--- a/src/traced/probes/ftrace/ftrace_data_source.cc
+++ b/src/traced/probes/ftrace/ftrace_data_source.cc
@@ -112,6 +112,13 @@
return;
DumpFtraceStats(&stats_before_);
setup_errors_ = FtraceSetupErrors(); // Dump only on START_OF_TRACE.
+
+ if (config_.preserve_ftrace_buffer()) {
+ auto stats_packet = writer_->NewTracePacket();
+ auto* stats = stats_packet->set_ftrace_stats();
+ stats->set_phase(protos::pbzero::FtraceStats::Phase::START_OF_TRACE);
+ stats->set_preserve_ftrace_buffer(true);
+ }
}
void FtraceDataSource::DumpFtraceStats(FtraceStats* stats) {
diff --git a/src/traced/probes/ftrace/ftrace_procfs.cc b/src/traced/probes/ftrace/ftrace_procfs.cc
index 425a3cb..aa0d31d 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.cc
+++ b/src/traced/probes/ftrace/ftrace_procfs.cc
@@ -83,7 +83,8 @@
// static
std::unique_ptr<FtraceProcfs> FtraceProcfs::CreateGuessingMountPoint(
- const std::string& instance_path) {
+ const std::string& instance_path,
+ bool preserve_ftrace_buffer) {
std::unique_ptr<FtraceProcfs> ftrace_procfs;
size_t index = 0;
while (!ftrace_procfs && kTracingPaths[index]) {
@@ -91,14 +92,16 @@
if (!instance_path.empty())
path += instance_path;
- ftrace_procfs = Create(path);
+ ftrace_procfs = Create(path, preserve_ftrace_buffer);
}
return ftrace_procfs;
}
// static
-std::unique_ptr<FtraceProcfs> FtraceProcfs::Create(const std::string& root) {
- if (!CheckRootPath(root)) {
+std::unique_ptr<FtraceProcfs> FtraceProcfs::Create(
+ const std::string& root,
+ bool preserve_ftrace_buffer) {
+ if (!preserve_ftrace_buffer && !CheckRootPath(root)) {
return nullptr;
}
return std::unique_ptr<FtraceProcfs>(new FtraceProcfs(root));
diff --git a/src/traced/probes/ftrace/ftrace_procfs.h b/src/traced/probes/ftrace/ftrace_procfs.h
index fb39fee..27411d1 100644
--- a/src/traced/probes/ftrace/ftrace_procfs.h
+++ b/src/traced/probes/ftrace/ftrace_procfs.h
@@ -34,9 +34,12 @@
// Takes an optional |instance_path| such as "instances/wifi/", in which case
// the returned object will be for that ftrace instance path.
static std::unique_ptr<FtraceProcfs> CreateGuessingMountPoint(
- const std::string& instance_path = "");
+ const std::string& instance_path = "",
+ bool preserve_ftrace_buffer = false);
- static std::unique_ptr<FtraceProcfs> Create(const std::string& root);
+ static std::unique_ptr<FtraceProcfs> Create(
+ const std::string& root,
+ bool preserve_ftrace_buffer = false);
static int g_kmesg_fd;
explicit FtraceProcfs(const std::string& root);
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index f78f9bd..2febdbd 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -125,9 +125,12 @@
if (ftrace_creation_failed_)
return nullptr;
+ FtraceConfig ftrace_config;
+ ftrace_config.ParseFromString(config.ftrace_config_raw());
// Lazily create on the first instance.
if (!ftrace_) {
- ftrace_ = FtraceController::Create(task_runner_, this);
+ ftrace_ = FtraceController::Create(task_runner_, this,
+ ftrace_config.preserve_ftrace_buffer());
if (!ftrace_) {
PERFETTO_ELOG("Failed to create FtraceController");
@@ -135,14 +138,14 @@
return nullptr;
}
- ftrace_->DisableAllEvents();
- ftrace_->ClearTrace();
+ if (!ftrace_config.preserve_ftrace_buffer()) {
+ ftrace_->DisableAllEvents();
+ ftrace_->ClearTrace();
+ }
}
PERFETTO_LOG("Ftrace setup (target_buf=%" PRIu32 ")", config.target_buffer());
const BufferID buffer_id = static_cast<BufferID>(config.target_buffer());
- FtraceConfig ftrace_config;
- ftrace_config.ParseFromString(config.ftrace_config_raw());
std::unique_ptr<FtraceDataSource> data_source(new FtraceDataSource(
ftrace_->GetWeakPtr(), session_id, std::move(ftrace_config),
endpoint_->CreateTraceWriter(buffer_id)));
diff --git a/src/tracing/core/metatrace_writer.cc b/src/tracing/core/metatrace_writer.cc
index f6acfa0..c270632 100644
--- a/src/tracing/core/metatrace_writer.cc
+++ b/src/tracing/core/metatrace_writer.cc
@@ -26,8 +26,10 @@
namespace perfetto {
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr char MetatraceWriter::kDataSourceName[];
+#endif
MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
diff --git a/src/tracing/core/shared_memory_abi.cc b/src/tracing/core/shared_memory_abi.cc
index 9461848..0c4694b 100644
--- a/src/tracing/core/shared_memory_abi.cc
+++ b/src/tracing/core/shared_memory_abi.cc
@@ -69,6 +69,7 @@
} // namespace
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr uint32_t SharedMemoryABI::kNumChunksForLayout[];
constexpr const char* SharedMemoryABI::kChunkStateStr[];
@@ -76,6 +77,7 @@
constexpr const size_t SharedMemoryABI::kMinPageSize;
constexpr const size_t SharedMemoryABI::kMaxPageSize;
constexpr const size_t SharedMemoryABI::kPacketSizeDropPacket;
+#endif
SharedMemoryABI::SharedMemoryABI() = default;
diff --git a/src/tracing/core/shared_memory_arbiter_impl.cc b/src/tracing/core/shared_memory_arbiter_impl.cc
index 7928676..f1b830a 100644
--- a/src/tracing/core/shared_memory_arbiter_impl.cc
+++ b/src/tracing/core/shared_memory_arbiter_impl.cc
@@ -52,8 +52,10 @@
SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
SharedMemoryABI::PageLayout::kPageDiv1;
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// static
constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
+#endif
// static
std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
diff --git a/src/tracing/core/trace_buffer.cc b/src/tracing/core/trace_buffer.cc
index 41633aa..c0527ad 100644
--- a/src/tracing/core/trace_buffer.cc
+++ b/src/tracing/core/trace_buffer.cc
@@ -42,8 +42,10 @@
SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
} // namespace.
+#if !PERFETTO_IS_AT_LEAST_CPP17()
constexpr size_t TraceBuffer::ChunkRecord::kMaxSize;
-constexpr size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
+#endif
+const size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
// static
std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index f910a90..da4e34c 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -312,10 +312,12 @@
} // namespace
+#if !PERFETTO_IS_AT_LEAST_CPP17()
// These constants instead are defined in the header because are used by tests.
constexpr size_t TracingServiceImpl::kMaxShmSize;
constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
constexpr uint8_t TracingServiceImpl::kSyncMarker[];
+#endif
std::string GetBugreportPath() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
diff --git a/src/tracing/core/virtual_destructors.cc b/src/tracing/core/virtual_destructors.cc
index 3bcedce..ad9522e 100644
--- a/src/tracing/core/virtual_destructors.cc
+++ b/src/tracing/core/virtual_destructors.cc
@@ -36,7 +36,9 @@
SharedMemory::Factory::~Factory() = default;
SharedMemoryArbiter::~SharedMemoryArbiter() = default;
+#if !PERFETTO_IS_AT_LEAST_CPP17()
constexpr size_t TracingService::kDefaultShmSize;
constexpr size_t TracingService::kDefaultShmPageSize;
+#endif
} // namespace perfetto
diff --git a/src/tracing/test/api_integrationtest_main.cc b/src/tracing/test/api_integrationtest_main.cc
index 49fb0d4..5073244 100644
--- a/src/tracing/test/api_integrationtest_main.cc
+++ b/src/tracing/test/api_integrationtest_main.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <gtest/gtest.h>
+#include "test/gtest_and_gmock.h"
#include "perfetto/tracing.h"
diff --git a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
index 1bc4017..5863d55 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_1.png.sha256
@@ -1 +1 @@
-9da477a6b9736f3e06a2940543ef54fb86ed21a9ec975d61851d99cb16004e59
\ No newline at end of file
+f3c0069c0ef9643552081835fd06c972b87448b7df5ac538a4d3e213a437bcb1
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256 b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
index d5dcb60..e70add7 100644
--- a/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
+++ b/test/data/ui-screenshots/ui-modal_dialog_show_dialog_2.png.sha256
@@ -1 +1 @@
-f8bcea9fc715ac226cd7a50201eac183603c22b881070265d2fb9fb015357434
\ No newline at end of file
+04b6ed7959eef3625b2d25d9daa68e7caea3f8ad4846234a45a6c264aebc8e47
\ No newline at end of file
diff --git a/tools/gen_amalgamated_sql_metrics.py b/tools/gen_amalgamated_sql.py
similarity index 81%
rename from tools/gen_amalgamated_sql_metrics.py
rename to tools/gen_amalgamated_sql.py
index 16f6aac..099bc92 100755
--- a/tools/gen_amalgamated_sql_metrics.py
+++ b/tools/gen_amalgamated_sql.py
@@ -21,7 +21,7 @@
# as a string constant to allow trace processor to exectue the metrics.
REPLACEMENT_HEADER = '''/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -45,13 +45,32 @@
#include <string.h>
'''
-NAMESPACE_BEGIN = '''
+STDLIB_NAMESPACE_BEGIN = '''
+namespace perfetto {
+namespace trace_processor {
+namespace stdlib {
+'''
+
+STDLIB_NAMESPACE_END = '''
+} // namespace stdlib
+} // namespace trace_processor
+} // namespace perfetto
+'''
+
+METRICS_NAMESPACE_BEGIN = '''
namespace perfetto {
namespace trace_processor {
namespace metrics {
namespace sql_metrics {
'''
+METRICS_NAMESPACE_END = '''
+} // namespace sql_metrics
+} // namespace metrics
+} // namespace trace_processor
+} // namespace perfetto
+'''
+
FILE_TO_SQL_STRUCT = '''
struct FileToSql {
const char* path;
@@ -59,12 +78,8 @@
};
'''
-NAMESPACE_END = '''
-} // namespace sql_metrics
-} // namespace metrics
-} // namespace trace_processor
-} // namsepace perfetto
-'''
+ROOT = '''
+const char kRootPath[] = '''
def filename_to_variable(filename):
@@ -73,11 +88,14 @@
def main():
parser = argparse.ArgumentParser()
+ parser.add_argument('--type', required=True)
parser.add_argument('--cpp_out', required=True)
parser.add_argument('sql_files', nargs='*')
args = parser.parse_args()
root_path = os.path.commonprefix([os.path.abspath(x) for x in args.sql_files])
+ if '.sql' in root_path:
+ root_path = root_path.rsplit('/', 1)[0]
# Extract the SQL output from each file.
sql_outputs = {}
@@ -89,7 +107,13 @@
with open(args.cpp_out, 'w+') as output:
output.write(REPLACEMENT_HEADER)
- output.write(NAMESPACE_BEGIN)
+ output.write(
+ METRICS_NAMESPACE_BEGIN) if args.type == 'METRICS' else output.write(
+ STDLIB_NAMESPACE_BEGIN)
+
+ if args.type == "LIB":
+ output.write(ROOT + f'''"{root_path.rsplit("stdlib/")[-1]}";
+ ''')
# Create the C++ variable for each SQL file.
for path, sql in sql_outputs.items():
@@ -122,7 +146,9 @@
output.write('\n {{"{}", {}}},\n'.format(path, variable))
output.write("};\n")
- output.write(NAMESPACE_END)
+ output.write(
+ METRICS_NAMESPACE_END) if args.type == 'METRICS' else output.write(
+ STDLIB_NAMESPACE_END)
return 0
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 2469958..0fc587c 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -771,10 +771,11 @@
bp_module_name = label_to_module_name(target.name)
module = Module('genrule', bp_module_name, target.name)
module.tool_files = [
- 'tools/gen_amalgamated_sql_metrics.py',
+ 'tools/gen_amalgamated_sql.py',
]
module.cmd = ' '.join([
- '$(location tools/gen_amalgamated_sql_metrics.py)',
+ '$(location tools/gen_amalgamated_sql.py)',
+ '--type=METRICS',
'--cpp_out=$(out)',
'$(in)',
])
@@ -784,6 +785,23 @@
blueprint.add_module(module)
return module
+def create_amalgamated_stdlib_module(blueprint, target):
+ bp_module_name = label_to_module_name(target.name)
+ module = Module('genrule', bp_module_name, target.name)
+ module.tool_files = [
+ 'tools/gen_amalgamated_sql.py',
+ ]
+ module.cmd = ' '.join([
+ '$(location tools/gen_amalgamated_sql.py)',
+ '--type=LIB',
+ '--cpp_out=$(out)',
+ '$(in)',
+ ])
+ module.genrule_headers.add(module.name)
+ module.out.update(target.outputs)
+ module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
+ blueprint.add_module(module)
+ return module
def create_cc_proto_descriptor_module(blueprint, target):
bp_module_name = label_to_module_name(target.name)
@@ -891,6 +909,8 @@
elif target.type == 'action':
if 'gen_amalgamated_sql_metrics' in target.name:
module = create_amalgamated_sql_metrics_module(blueprint, target)
+ elif 'gen_amalgamated_stdlib' in target.name:
+ module = create_amalgamated_stdlib_module(blueprint, target)
elif re.match('.*gen_cc_.*_descriptor$', name_without_toolchain):
module = create_cc_proto_descriptor_module(blueprint, target)
elif target.type == 'action' and \
diff --git a/tools/gen_bazel b/tools/gen_bazel
index 1c64257..e64307a 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -114,6 +114,9 @@
'//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics': [[
':cc_amalgamated_sql_metrics'
]],
+ '//src/trace_processor/stdlib:gen_amalgamated_stdlib': [[
+ ':cc_amalgamated_stdlib'
+ ]],
gn_utils.GEN_VERSION_TARGET: ['PERFETTO_CONFIG.deps.version_header'],
}
@@ -122,8 +125,18 @@
label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
label.srcs += [re.sub('^//', '', x) for x in sorted(target.inputs)]
label.outs += target.outputs
- label.cmd = r'$(location gen_amalgamated_sql_metrics_py) --cpp_out=$@ $(SRCS)'
- label.exec_tools += [':gen_amalgamated_sql_metrics_py']
+ label.cmd = (r'$(location gen_amalgamated_sql_py) '
+ r'--type=METRICS --cpp_out=$@ $(SRCS)')
+ label.exec_tools += [':gen_amalgamated_sql_py']
+ return [label]
+
+def gen_amalgamated_stdlib(target):
+ label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule')
+ label.srcs += [re.sub('^//', '', x) for x in sorted(target.inputs)]
+ label.outs += target.outputs
+ label.cmd = (r'$(location gen_amalgamated_sql_py) '
+ r'--type=LIB --cpp_out=$@ $(SRCS)')
+ label.exec_tools += [':gen_amalgamated_sql_py']
return [label]
@@ -152,6 +165,8 @@
gen_version_header,
'//src/trace_processor/metrics/sql:gen_amalgamated_sql_metrics':
gen_amalgamated_sql_metrics,
+ '//src/trace_processor/stdlib:gen_amalgamated_stdlib':
+ gen_amalgamated_stdlib,
}
# ------------------------------------------------------------------------------
diff --git a/tools/test_gen_amalgamated.py b/tools/test_gen_amalgamated.py
index aa99bc4..9eb17ad 100755
--- a/tools/test_gen_amalgamated.py
+++ b/tools/test_gen_amalgamated.py
@@ -52,7 +52,7 @@
def check_amalgamated_build():
args = [
- '-std=c++11', '-Werror', '-Wall', '-Wextra',
+ '-std=c++17', '-Werror', '-Wall', '-Wextra',
'-DPERFETTO_AMALGAMATED_SDK_TEST', '-I' + OUT_DIR,
OUT_DIR + '/perfetto.cc', 'test/client_api_example.cc', '-o',
OUT_DIR + '/test'
diff --git a/ui/src/common/query_result.ts b/ui/src/common/query_result.ts
index 347c4ed..bae847d 100644
--- a/ui/src/common/query_result.ts
+++ b/ui/src/common/query_result.ts
@@ -183,6 +183,12 @@
// have been fetched. The promise return value is always the object iself.
waitAllRows(): Promise<QueryResult>;
+ // Returns a promise that is resolved when either:
+ // - more rows are available
+ // - all rows are available
+ // The promise return value is always the object iself.
+ waitMoreRows(): Promise<QueryResult>;
+
// Can return an empty array if called before the first batch is resolved.
// This should be called only after having awaited for at least one batch.
columns(): string[];
@@ -194,10 +200,6 @@
// Returns the number of SQL statement that produced output rows. This number
// is <= statementCount().
statementWithOutputCount(): number;
-
- // TODO(primiano): next CLs will introduce a waitMoreRows() to allow tracks
- // to await until some more data (but not necessarily all) is available. For
- // now everything uses waitAllRows().
}
// Interface exposed to engine.ts to pump in the data as new row batches arrive.
@@ -248,6 +250,10 @@
// last result batch has been been retrieved.
private allRowsPromise?: Deferred<QueryResult>;
+ // Promise awaiting on waitMoreRows(). This resolved when the next
+ // batch is appended via appendResultBatch.
+ private moreRowsPromise?: Deferred<QueryResult>;
+
isComplete(): boolean {
return this._isComplete;
}
@@ -288,6 +294,20 @@
return this.allRowsPromise;
}
+ waitMoreRows(): Promise<QueryResult> {
+ if (this.moreRowsPromise !== undefined) {
+ return this.moreRowsPromise;
+ }
+
+ const moreRowsPromise = defer<QueryResult>();
+ if (this._isComplete) {
+ this.resolveOrReject(moreRowsPromise, this);
+ } else {
+ this.moreRowsPromise = moreRowsPromise;
+ }
+ return moreRowsPromise;
+ }
+
// --- WritableQueryResult implementation.
// Called by the engine when a new QueryResult is available. Note that a
@@ -369,6 +389,11 @@
} // switch (tag)
} // while (pos < end)
+ if (this.moreRowsPromise !== undefined) {
+ this.resolveOrReject(this.moreRowsPromise, this);
+ this.moreRowsPromise = undefined;
+ }
+
if (this._isComplete && this.allRowsPromise !== undefined) {
this.resolveOrReject(this.allRowsPromise, this);
}
@@ -768,6 +793,9 @@
waitAllRows() {
return this.impl.waitAllRows();
}
+ waitMoreRows() {
+ return this.impl.waitMoreRows();
+ }
isComplete() {
return this.impl.isComplete();
}
diff --git a/ui/src/common/query_result_unittest.ts b/ui/src/common/query_result_unittest.ts
index 5fad6fe..8f508e7 100644
--- a/ui/src/common/query_result_unittest.ts
+++ b/ui/src/common/query_result_unittest.ts
@@ -300,3 +300,45 @@
}
expect(() => qr.iter({x_3: NUM})).toThrowError(/\bx_3\b.*not found/);
});
+
+
+test('QueryResult.WaitMoreRows', async () => {
+ const batchA = QueryResultProto.CellsBatch.create({
+ cells: [T.CELL_VARINT],
+ varintCells: [42],
+ isLastBatch: false,
+ });
+ const resProtoA = QueryResultProto.create({
+ columnNames: ['a_int'],
+ batch: [batchA],
+ });
+
+ const qr = createQueryResult({query: 'Some query'});
+ qr.appendResultBatch(QueryResultProto.encode(resProtoA).finish());
+
+ const batchB = QueryResultProto.CellsBatch.create({
+ cells: [T.CELL_VARINT],
+ varintCells: [43],
+ isLastBatch: true,
+ });
+ const resProtoB = QueryResultProto.create({
+ columnNames: [],
+ batch: [batchB],
+ });
+
+ const waitPromise = qr.waitMoreRows();
+ const appendPromise = new Promise<void>((resolve, _) => {
+ setTimeout(() => {
+ qr.appendResultBatch(QueryResultProto.encode(resProtoB).finish());
+ resolve();
+ }, 0);
+ });
+
+ expect(qr.isComplete()).toBe(false);
+ expect(qr.numRows()).toBe(1);
+
+ await Promise.all([waitPromise, appendPromise]);
+
+ expect(qr.isComplete()).toBe(true);
+ expect(qr.numRows()).toBe(2);
+});
diff --git a/ui/src/frontend/help_modal.ts b/ui/src/frontend/help_modal.ts
index 7ed2880..3242b2c 100644
--- a/ui/src/frontend/help_modal.ts
+++ b/ui/src/frontend/help_modal.ts
@@ -48,6 +48,20 @@
m('td', 'Pan left/right'),
),
),
+ m('h2', 'Navigation (Dvorak)'),
+ m(
+ 'table',
+ m(
+ 'tr',
+ m('td', keycap(','), '/', keycap('o')),
+ m('td', 'Zoom in/out'),
+ ),
+ m(
+ 'tr',
+ m('td', keycap('a'), '/', keycap('e')),
+ m('td', 'Pan left/right'),
+ ),
+ ),
m('h2', 'Mouse Controls'),
m('table',
m('tr', m('td', 'Click'), m('td', 'Select event')),