Merge "Release canary to pick up a fix for b/227763167"
diff --git a/Android.bp b/Android.bp
index 5652bdb..b0d0881 100644
--- a/Android.bp
+++ b/Android.bp
@@ -23,7 +23,6 @@
":perfetto_include_perfetto_ext_ipc_ipc",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_tracing_core_core",
":perfetto_include_perfetto_tracing_core_forward_decls",
@@ -79,6 +78,7 @@
":perfetto_src_profiling_common_callstack_trie",
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
":perfetto_src_profiling_common_proc_utils",
":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
@@ -277,7 +277,6 @@
":perfetto_include_perfetto_ext_ipc_ipc",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_tracing_core_core",
":perfetto_include_perfetto_tracing_core_forward_decls",
@@ -333,6 +332,7 @@
":perfetto_src_profiling_common_callstack_trie",
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
":perfetto_src_profiling_common_proc_utils",
":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
@@ -1621,11 +1621,6 @@
name: "perfetto_include_perfetto_ext_tracing_ipc_ipc",
}
-// GN: //include/perfetto/profiling:normalize
-filegroup {
- name: "perfetto_include_perfetto_profiling_normalize",
-}
-
// GN: //include/perfetto/profiling:pprof_builder
filegroup {
name: "perfetto_include_perfetto_profiling_pprof_builder",
@@ -1689,7 +1684,6 @@
":perfetto_include_perfetto_ext_traced_traced",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_trace_processor_basic_types",
":perfetto_include_perfetto_trace_processor_storage",
@@ -1773,6 +1767,7 @@
":perfetto_src_profiling_common_callstack_trie",
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
":perfetto_src_profiling_common_proc_utils",
":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
@@ -7522,6 +7517,14 @@
],
}
+// GN: //src/profiling/common:proc_cmdline
+filegroup {
+ name: "perfetto_src_profiling_common_proc_cmdline",
+ srcs: [
+ "src/profiling/common/proc_cmdline.cc",
+ ],
+}
+
// GN: //src/profiling/common:proc_utils
filegroup {
name: "perfetto_src_profiling_common_proc_utils",
@@ -7551,6 +7554,7 @@
name: "perfetto_src_profiling_common_unittests",
srcs: [
"src/profiling/common/interner_unittest.cc",
+ "src/profiling/common/proc_cmdline_unittest.cc",
"src/profiling/common/proc_utils_unittest.cc",
"src/profiling/common/producer_support_unittest.cc",
"src/profiling/common/profiler_guardrails_unittest.cc",
@@ -9727,7 +9731,6 @@
":perfetto_include_perfetto_ext_traced_traced",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_test_test_support",
":perfetto_include_perfetto_trace_processor_basic_types",
@@ -9850,6 +9853,7 @@
":perfetto_src_profiling_common_callstack_trie",
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
":perfetto_src_profiling_common_proc_utils",
":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
@@ -10466,7 +10470,6 @@
":perfetto_include_perfetto_ext_ipc_ipc",
":perfetto_include_perfetto_ext_tracing_core_core",
":perfetto_include_perfetto_ext_tracing_ipc_ipc",
- ":perfetto_include_perfetto_profiling_normalize",
":perfetto_include_perfetto_protozero_protozero",
":perfetto_include_perfetto_tracing_core_core",
":perfetto_include_perfetto_tracing_core_forward_decls",
@@ -10527,6 +10530,7 @@
":perfetto_src_profiling_common_callstack_trie",
":perfetto_src_profiling_common_interner",
":perfetto_src_profiling_common_interning_output",
+ ":perfetto_src_profiling_common_proc_cmdline",
":perfetto_src_profiling_common_proc_utils",
":perfetto_src_profiling_common_producer_support",
":perfetto_src_profiling_common_profiler_guardrails",
diff --git a/include/perfetto/profiling/BUILD.gn b/include/perfetto/profiling/BUILD.gn
index e7f9ddf..1fd2092 100644
--- a/include/perfetto/profiling/BUILD.gn
+++ b/include/perfetto/profiling/BUILD.gn
@@ -15,7 +15,3 @@
source_set("pprof_builder") {
sources = [ "pprof_builder.h" ]
}
-
-source_set("normalize") {
- sources = [ "normalize.h" ]
-}
diff --git a/include/perfetto/profiling/normalize.h b/include/perfetto/profiling/normalize.h
deleted file mode 100644
index 7b7da1d..0000000
--- a/include/perfetto/profiling/normalize.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
-#define INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
-
-// Header only code that gets used in other projects.
-// This is currently used in
-// * ART
-// * Bionic
-// * Heapprofd
-//
-// DO NOT USE THE STL HERE. This gets used in parts of Bionic that do not
-// use the STL.
-
-#include <string.h>
-
-namespace perfetto {
-namespace profiling {
-
-// Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
-// Returns new size of string (from new beginning).
-// Modifies string in *cmdline_ptr.
-static ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
- char* cmdline = *cmdline_ptr;
- char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
- if (first_arg == nullptr) {
- errno = EOVERFLOW;
- return -1;
- }
- // For consistency with what we do with Java app cmdlines, trim everything
- // after the @ sign of the first arg.
- char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
- if (first_at != nullptr && first_at < first_arg) {
- *first_at = '\0';
- first_arg = first_at;
- }
- char* start = static_cast<char*>(
- memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
- if (start == nullptr) {
- start = cmdline;
- } else {
- // Skip the /.
- start++;
- }
- *cmdline_ptr = start;
- return first_arg - start;
-}
-
-} // namespace profiling
-} // namespace perfetto
-
-#endif // INCLUDE_PERFETTO_PROFILING_NORMALIZE_H_
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 0e0a58d..b3fb91f 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -858,7 +858,7 @@
// Begin of protos/perfetto/config/profiling/java_hprof_config.proto
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -876,12 +876,27 @@
optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
@@ -1184,18 +1199,34 @@
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
diff --git a/protos/perfetto/config/profiling/java_hprof_config.proto b/protos/perfetto/config/profiling/java_hprof_config.proto
index 9245ee6..c161396 100644
--- a/protos/perfetto/config/profiling/java_hprof_config.proto
+++ b/protos/perfetto/config/profiling/java_hprof_config.proto
@@ -18,7 +18,7 @@
package perfetto.protos;
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -36,12 +36,27 @@
optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
diff --git a/protos/perfetto/config/profiling/perf_event_config.proto b/protos/perfetto/config/profiling/perf_event_config.proto
index a936b5b..a440464 100644
--- a/protos/perfetto/config/profiling/perf_event_config.proto
+++ b/protos/perfetto/config/profiling/perf_event_config.proto
@@ -148,18 +148,34 @@
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 8dafad0..d683c97 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -858,7 +858,7 @@
// Begin of protos/perfetto/config/profiling/java_hprof_config.proto
-// Configuration for go/heapprofd.
+// Configuration for managed app heap graph snapshots.
message JavaHprofConfig {
// If dump_interval_ms != 0, the following configuration is used.
message ContinuousDumpConfig {
@@ -876,12 +876,27 @@
optional bool scan_pids_only_on_start = 3;
}
- // This input is normalized in the following way: if it contains slashes,
- // everything up to the last slash is discarded. If it contains "@",
- // everything after the first @ is discared.
- // E.g. /system/bin/surfaceflinger@1.0 normalizes to surfaceflinger.
- // This transformation is also applied to the processes' command lines when
- // matching.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string process_cmdline = 1;
// For watermark based triggering or local debugging.
@@ -1184,18 +1199,34 @@
// process.
repeated int32 target_pid = 1;
- // Command line allowlist, matched against the
- // /proc/<pid>/cmdline (not the comm string), with both sides being
- // "normalized". Normalization is as follows: (1) trim everything beyond the
- // first null or "@" byte; (2) if the string contains forward slashes, trim
- // everything up to and including the last one.
+ // Command line allowlist, matched against the /proc/<pid>/cmdline (not the
+ // comm string). The semantics of this field were changed since its original
+ // introduction.
+ //
+ // On Android T+ (13+), this field can specify a single wildcard (*), and
+ // the profiler will attempt to match it in two possible ways:
+ // * if the pattern starts with a '/', then it is matched against the first
+ // segment of the cmdline (i.e. argv0). For example "/bin/e*" would match
+ // "/bin/echo".
+ // * otherwise the pattern is matched against the part of argv0
+ // corresponding to the binary name (this is unrelated to /proc/pid/exe).
+ // For example "echo" would match "/bin/echo".
+ //
+ // On Android S (12) and below, both this pattern and /proc/pid/cmdline get
+ // normalized prior to an exact string comparison. Normalization is as
+ // follows: (1) trim everything beyond the first null or "@" byte; (2) if
+ // the string contains forward slashes, trim everything up to and including
+ // the last one.
+ //
+ // Implementation note: in either case, at most 511 characters of cmdline
+ // are considered.
repeated string target_cmdline = 2;
// List of excluded pids.
repeated int32 exclude_pid = 3;
- // List of excluded cmdlines. Normalized in the same way as
- // |target_cmdline|.
+ // List of excluded cmdlines. See description of |target_cmdline| for how
+ // this is handled.
repeated string exclude_cmdline = 4;
// Number of additional command lines to sample. Only those which are
diff --git a/python/perfetto/experimental/slice_breakdown/breakdown.py b/python/perfetto/experimental/slice_breakdown/breakdown.py
index 85b21d2..9eb99de 100644
--- a/python/perfetto/experimental/slice_breakdown/breakdown.py
+++ b/python/perfetto/experimental/slice_breakdown/breakdown.py
@@ -13,8 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from perfetto.trace_processor.api import TraceProcessor
+from perfetto.trace_processor.api import TraceProcessorException
-def compute_breakdown(tp, start_ts=None, end_ts=None, process_name=None):
+
+def compute_breakdown(tp: TraceProcessor,
+ start_ts=None,
+ end_ts=None,
+ process_name=None):
"""For each userspace slice in the trace processor instance |tp|, computes
the self-time of that slice grouping by process name, thread name
and thread state.
@@ -149,7 +155,9 @@
return breakdown
-def compute_breakdown_for_startup(tp, package_name=None, process_name=None):
+def compute_breakdown_for_startup(tp: TraceProcessor,
+ package_name=None,
+ process_name=None):
"""Computes the slice breakdown (like |compute_breakdown|) but only
considering slices which happened during an app startup
@@ -176,9 +184,9 @@
{}
'''.format(filter)).as_pandas_dataframe()
if len(launches) == 0:
- raise Exception("Didn't find startup in trace")
+ raise TraceProcessorException("Didn't find startup in trace")
if len(launches) > 1:
- raise Exception("Found multiple startups in trace")
+ raise TraceProcessorException("Found multiple startups in trace")
start = launches['ts'][0]
end = launches['ts_end'][0]
diff --git a/src/profiling/common/BUILD.gn b/src/profiling/common/BUILD.gn
index 583edc6..1fcc6fb 100644
--- a/src/profiling/common/BUILD.gn
+++ b/src/profiling/common/BUILD.gn
@@ -66,8 +66,8 @@
source_set("proc_utils") {
deps = [
+ ":proc_cmdline",
"../../../gn:default_deps",
- "../../../include/perfetto/profiling:normalize",
"../../base",
]
sources = [
@@ -76,6 +76,17 @@
]
}
+source_set("proc_cmdline") {
+ deps = [
+ "../../../gn:default_deps",
+ "../../base",
+ ]
+ sources = [
+ "proc_cmdline.cc",
+ "proc_cmdline.h",
+ ]
+}
+
source_set("producer_support") {
deps = [
"../../../gn:default_deps",
@@ -106,18 +117,19 @@
testonly = true
deps = [
":interner",
+ ":proc_cmdline",
":proc_utils",
":producer_support",
":profiler_guardrails",
"../../../gn:default_deps",
"../../../gn:gtest_and_gmock",
- "../../../include/perfetto/profiling:normalize",
"../../base",
"../../base:test_support",
"../../tracing/core",
]
sources = [
"interner_unittest.cc",
+ "proc_cmdline_unittest.cc",
"proc_utils_unittest.cc",
"producer_support_unittest.cc",
"profiler_guardrails_unittest.cc",
diff --git a/src/profiling/common/proc_cmdline.cc b/src/profiling/common/proc_cmdline.cc
new file mode 100644
index 0000000..a6f7d93
--- /dev/null
+++ b/src/profiling/common/proc_cmdline.cc
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+#include "src/profiling/common/proc_cmdline.h"
+
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "perfetto/ext/base/file_utils.h"
+
+namespace perfetto {
+namespace profiling {
+namespace glob_aware {
+
+// Edge cases: the raw cmdline as read out of the kernel can have several
+// shapes, the process can rewrite the contents to be arbitrary, and overly long
+// cmdlines can be truncated as we use a 511 byte limit. Some examples to
+// consider for the implementation:
+// * "echo\0hello\0"
+// * "/bin/top\0\0\0\0\0\0\0"
+// * "arbitrary string as rewritten by the process\0"
+// * "some_bugged_kernels_forget_final_nul_terminator"
+//
+// The approach when performing the read->derive->match is to minimize early
+// return codepaths for the caller. So even if we read a non-conforming cmdline
+// (e.g. just a single nul byte), it can still be fed through FindBinaryName and
+// MatchGlobPattern. It'll just make the intermediate strings be empty (so
+// starting with a nul byte, but never nullptr).
+//
+// NB: bionic/libc/bionic/malloc_heapprofd will require a parallel
+// implementation of these functions (to avoid a bionic->perfetto dependency).
+// Keep them as STL-free as possible to allow for both implementations to be
+// close to verbatim copies.
+
+// TODO(rsavitski): consider changing to Optional<> return type.
+bool ReadProcCmdlineForPID(pid_t pid, std::string* cmdline_out) {
+ std::string filename = "/proc/" + std::to_string(pid) + "/cmdline";
+ base::ScopedFile fd(base::OpenFile(filename, O_RDONLY));
+ if (!fd) {
+ PERFETTO_DPLOG("Failed to open %s", filename.c_str());
+ return false;
+ }
+
+ // buf is 511 bytes to match an implementation that adds a null terminator to
+ // the back of a 512 byte buffer.
+ char buf[511];
+ ssize_t rd = PERFETTO_EINTR(read(*fd, buf, sizeof(buf)));
+ if (rd < 0) {
+ PERFETTO_DPLOG("Failed to read %s", filename.c_str());
+ return false;
+ }
+
+ cmdline_out->assign(buf, static_cast<size_t>(rd));
+ return true;
+}
+
+// Returns a pointer into |cmdline| corresponding to the argv0 without any
+// leading directories if the binary path is absolute. |cmdline_len| corresponds
+// to the length of the cmdline string as read out of procfs as a C string -
+// length doesn't include the final nul terminator, but it must be present at
+// cmdline[cmdline_len]. Note that normally the string itself will contain nul
+// bytes, as that's what the kernel uses to separate arguments.
+//
+// Function output examples:
+// * /system/bin/adb\0--flag -> adb
+// * adb -> adb
+// * com.example.app -> com.example.app
+const char* FindBinaryName(const char* cmdline, size_t cmdline_len) {
+ // Find the first nul byte that signifies the end of argv0. We might not find
+ // one if the process rewrote its cmdline without nul separators, and/or the
+ // cmdline didn't fully fit into our read buffer. In such cases, proceed with
+ // the full string to do best-effort matching.
+ const char* argv0_end =
+ static_cast<const char*>(memchr(cmdline, '\0', cmdline_len));
+ if (argv0_end == nullptr) {
+ argv0_end = cmdline + cmdline_len; // set to final nul terminator
+ }
+ // Find the last path separator of argv0, if it exists.
+ const char* name_start = static_cast<const char*>(
+ memrchr(cmdline, '/', static_cast<size_t>(argv0_end - cmdline)));
+ if (name_start == nullptr) {
+ name_start = cmdline;
+ } else {
+ name_start++; // skip the separator
+ }
+ return name_start;
+}
+
+// All inputs must be non-nullptr, but can start with a nul byte.
+bool MatchGlobPattern(const char* pattern,
+ const char* cmdline,
+ const char* binname) {
+ if (pattern[0] == '/') {
+ return fnmatch(pattern, cmdline, FNM_NOESCAPE) == 0;
+ }
+ return fnmatch(pattern, binname, FNM_NOESCAPE) == 0;
+}
+
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/common/proc_cmdline.h b/src/profiling/common/proc_cmdline.h
new file mode 100644
index 0000000..1d01f93
--- /dev/null
+++ b/src/profiling/common/proc_cmdline.h
@@ -0,0 +1,56 @@
+/*
+ * 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_PROFILING_COMMON_PROC_CMDLINE_H_
+#define SRC_PROFILING_COMMON_PROC_CMDLINE_H_
+
+#include <sys/types.h>
+
+#include <string>
+
+namespace perfetto {
+namespace profiling {
+
+// TODO(rsavitski): these functions are a reimplementation of those found in
+// proc_utils, but with a change in semantics that we intend for all profilers.
+// Eventually this should become the single canonical file dealing with proc
+// cmdlines. The transition will start with traced_perf and perfetto_hprof, and
+// heapprofd will follow later.
+namespace glob_aware {
+
+// These functions let the profilers read a /proc/pid/cmdline, find the
+// substrings corresponding to the argv0 as well as the binary name (e.g.
+// "/bin/echo" and "echo" respectively), and then match it against a set of glob
+// patterns.
+//
+// Example usage:
+// std::string cmdline;
+// bool success = ReadProcCmdlineForPID(42, &cmdline);
+// if (!success) return false;
+// const char* binname = FindBinaryName(cmdline.c_str(), cmdline.size());
+// return MatchGlobPattern("test*", cmdline.c_str(), binname);
+
+bool ReadProcCmdlineForPID(pid_t pid, std::string* cmdline_out);
+const char* FindBinaryName(const char* cmdline, size_t cmdline_len);
+bool MatchGlobPattern(const char* pattern,
+ const char* cmdline,
+ const char* binname);
+
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
+
+#endif // SRC_PROFILING_COMMON_PROC_CMDLINE_H_
diff --git a/src/profiling/common/proc_cmdline_unittest.cc b/src/profiling/common/proc_cmdline_unittest.cc
new file mode 100644
index 0000000..dc23594
--- /dev/null
+++ b/src/profiling/common/proc_cmdline_unittest.cc
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+#include "src/profiling/common/proc_cmdline.h"
+
+#include <string>
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace profiling {
+namespace glob_aware {
+namespace {
+
+TEST(ProcCmdlineTest, FindBinaryNameBinNameOnly) {
+ char cmdline[] = "surfaceflinger";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameWithArg) {
+ char cmdline[] = "surfaceflinger\0--flag";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameFullPathAndArgs) {
+ char cmdline[] = "/system/bin/surfaceflinger\0--flag\0--flag2";
+ EXPECT_STREQ("surfaceflinger", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameSpecialCharsInName) {
+ {
+ char cmdline[] = "android.hardware.graphics.composer@2.2-service";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "com.google.android.googlequicksearchbox:search";
+ EXPECT_EQ(cmdline, FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ // chrome rewrites cmdline with spaces instead of nul bytes, parsing will
+ // therefore treat everything as argv0.
+ char cmdline[] =
+ "/opt/google/chrome/chrome --type=renderer --enable-crashpad";
+ EXPECT_STREQ("chrome --type=renderer --enable-crashpad",
+ FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+}
+
+TEST(ProcCmdlineTest, FindBinaryNameEdgeCases) {
+ {
+ char cmdline[] = "";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "\0foo";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "/foo/";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "/";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+ {
+ char cmdline[] = "foo/\0";
+ EXPECT_STREQ("", FindBinaryName(cmdline, sizeof(cmdline) - 1));
+ }
+}
+
+TEST(ProcCmdlineTest, FindAndMatchAbsolutePath) {
+ char cmdline[] = "/system/bin/surfaceflinger\0--flag\0--flag2";
+ const char* binname = FindBinaryName(cmdline, sizeof(cmdline) - 1);
+ ASSERT_TRUE(binname != nullptr);
+
+ EXPECT_TRUE(MatchGlobPattern("/system/bin/surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("/*/surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("surfaceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("???faceflinger", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("*", cmdline, binname));
+
+ EXPECT_FALSE(MatchGlobPattern("/system", cmdline, binname));
+ EXPECT_FALSE(MatchGlobPattern("bin/surfaceflinger", cmdline, binname));
+ EXPECT_FALSE(
+ MatchGlobPattern("?system/bin/surfaceflinger", cmdline, binname));
+ EXPECT_FALSE(MatchGlobPattern("*/surfaceflinger", cmdline, binname));
+}
+
+TEST(ProcCmdlineTest, FindAndMatchRelativePath) {
+ char cmdline[] = "./top";
+ const char* binname = FindBinaryName(cmdline, sizeof(cmdline) - 1);
+ ASSERT_TRUE(binname != nullptr);
+
+ EXPECT_TRUE(MatchGlobPattern("top", cmdline, binname));
+ EXPECT_TRUE(MatchGlobPattern("*", cmdline, binname));
+
+ EXPECT_FALSE(MatchGlobPattern("./top", cmdline, binname));
+}
+
+} // namespace
+} // namespace glob_aware
+} // namespace profiling
+} // namespace perfetto
diff --git a/src/profiling/common/proc_utils.cc b/src/profiling/common/proc_utils.cc
index 3ec1e55..4188b2a 100644
--- a/src/profiling/common/proc_utils.cc
+++ b/src/profiling/common/proc_utils.cc
@@ -24,7 +24,7 @@
#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/string_utils.h"
-#include "perfetto/profiling/normalize.h"
+#include "src/profiling/common/proc_cmdline.h"
namespace perfetto {
namespace profiling {
@@ -47,6 +47,105 @@
}
} // namespace
+base::Optional<std::string> ReadStatus(pid_t pid) {
+ std::string path = "/proc/" + std::to_string(pid) + "/status";
+ std::string status;
+ bool read_proc = base::ReadFile(path, &status);
+ if (!read_proc) {
+ PERFETTO_ELOG("Failed to read %s", path.c_str());
+ return base::nullopt;
+ }
+ return base::Optional<std::string>(status);
+}
+
+base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
+ auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
+ auto swap = ParseProcStatusSize(status, "VmSwap:");
+ if (anon_rss.has_value() && swap.has_value()) {
+ return *anon_rss + *swap;
+ }
+ return base::nullopt;
+}
+
+void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
+ for (auto it = pids->begin(); it != pids->end();) {
+ const pid_t pid = *it;
+
+ base::Optional<std::string> status = ReadStatus(pid);
+ base::Optional<uint32_t> rss_and_swap;
+ if (status)
+ rss_and_swap = GetRssAnonAndSwap(*status);
+
+ if (rss_and_swap && rss_and_swap < min_size_kb) {
+ PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
+ ")",
+ pid, *rss_and_swap, min_size_kb);
+ it = pids->erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+base::Optional<Uids> GetUids(const std::string& status) {
+ auto entry_idx = status.find("Uid:");
+ if (entry_idx == std::string::npos)
+ return base::nullopt;
+
+ Uids uids;
+ const char* str = &status[entry_idx + 4];
+ char* endptr;
+
+ uids.real = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.effective = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.saved_set = strtoull(str, &endptr, 10);
+ if (*endptr != ' ' && *endptr != '\t')
+ return base::nullopt;
+
+ str = endptr;
+ uids.filesystem = strtoull(str, &endptr, 10);
+ if (*endptr != '\n' && *endptr != '\0')
+ return base::nullopt;
+ return uids;
+}
+
+// Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
+// Returns new size of string (from new beginning).
+// Modifies string in *cmdline_ptr.
+ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
+ char* cmdline = *cmdline_ptr;
+ char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
+ if (first_arg == nullptr) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ // For consistency with what we do with Java app cmdlines, trim everything
+ // after the @ sign of the first arg.
+ char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
+ if (first_at != nullptr && first_at < first_arg) {
+ *first_at = '\0';
+ first_arg = first_at;
+ }
+ char* start = static_cast<char*>(
+ memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
+ if (start == nullptr) {
+ start = cmdline;
+ } else {
+ // Skip the /.
+ start++;
+ }
+ *cmdline_ptr = start;
+ return first_arg - start;
+}
+
base::Optional<std::vector<std::string>> NormalizeCmdlines(
const std::vector<std::string>& cmdlines) {
std::vector<std::string> normalized_cmdlines;
@@ -142,75 +241,27 @@
});
}
-base::Optional<std::string> ReadStatus(pid_t pid) {
- std::string path = "/proc/" + std::to_string(pid) + "/status";
- std::string status;
- bool read_proc = base::ReadFile(path, &status);
- if (!read_proc) {
- PERFETTO_ELOG("Failed to read %s", path.c_str());
- return base::nullopt;
- }
- return base::Optional<std::string>(status);
-}
+namespace glob_aware {
+void FindPidsForCmdlinePatterns(const std::vector<std::string>& patterns,
+ std::set<pid_t>* pids) {
+ ForEachPid([&patterns, pids](pid_t pid) {
+ if (pid == getpid())
+ return;
+ std::string cmdline;
+ if (!glob_aware::ReadProcCmdlineForPID(pid, &cmdline))
+ return;
+ const char* binname =
+ glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());
-base::Optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
- auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
- auto swap = ParseProcStatusSize(status, "VmSwap:");
- if (anon_rss.has_value() && swap.has_value()) {
- return *anon_rss + *swap;
- }
- return base::nullopt;
-}
-
-void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
- for (auto it = pids->begin(); it != pids->end();) {
- const pid_t pid = *it;
-
- base::Optional<std::string> status = ReadStatus(pid);
- base::Optional<uint32_t> rss_and_swap;
- if (status)
- rss_and_swap = GetRssAnonAndSwap(*status);
-
- if (rss_and_swap && rss_and_swap < min_size_kb) {
- PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
- ")",
- pid, *rss_and_swap, min_size_kb);
- it = pids->erase(it);
- } else {
- ++it;
+ for (const std::string& pattern : patterns) {
+ if (glob_aware::MatchGlobPattern(pattern.c_str(), cmdline.c_str(),
+ binname)) {
+ pids->insert(pid);
+ }
}
- }
+ });
}
-
-base::Optional<Uids> GetUids(const std::string& status) {
- auto entry_idx = status.find("Uid:");
- if (entry_idx == std::string::npos)
- return base::nullopt;
-
- Uids uids;
- const char* str = &status[entry_idx + 4];
- char* endptr;
-
- uids.real = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.effective = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.saved_set = strtoull(str, &endptr, 10);
- if (*endptr != ' ' && *endptr != '\t')
- return base::nullopt;
-
- str = endptr;
- uids.filesystem = strtoull(str, &endptr, 10);
- if (*endptr != '\n' && *endptr != '\0')
- return base::nullopt;
- return uids;
-}
+} // namespace glob_aware
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils.h b/src/profiling/common/proc_utils.h
index 6376478..ccbf633 100644
--- a/src/profiling/common/proc_utils.h
+++ b/src/profiling/common/proc_utils.h
@@ -53,14 +53,6 @@
}
}
-base::Optional<std::vector<std::string>> NormalizeCmdlines(
- const std::vector<std::string>& cmdlines);
-
-void FindAllProfilablePids(std::set<pid_t>* pids);
-void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
- std::set<pid_t>* pids);
-bool GetCmdlineForPID(pid_t pid, std::string* name);
-
base::Optional<std::string> ReadStatus(pid_t pid);
base::Optional<uint32_t> GetRssAnonAndSwap(const std::string&);
// Filters the list of pids (in-place), keeping only the
@@ -69,6 +61,24 @@
base::Optional<Uids> GetUids(const std::string&);
+void FindAllProfilablePids(std::set<pid_t>* pids);
+
+// TODO(rsavitski): we're changing how the profilers treat proc cmdlines, the
+// newer semantics are implemented in proc_cmdline.h. Wrappers around those
+// implementations are placed in the "glob_aware" namespace here, until we
+// migrate to one implementation for all profilers.
+ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size);
+base::Optional<std::vector<std::string>> NormalizeCmdlines(
+ const std::vector<std::string>& cmdlines);
+void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
+ std::set<pid_t>* pids);
+bool GetCmdlineForPID(pid_t pid, std::string* name);
+
+namespace glob_aware {
+void FindPidsForCmdlinePatterns(const std::vector<std::string>& cmdlines,
+ std::set<pid_t>* pids);
+} // namespace glob_aware
+
} // namespace profiling
} // namespace perfetto
diff --git a/src/profiling/common/proc_utils_unittest.cc b/src/profiling/common/proc_utils_unittest.cc
index cec73d8..36a7720 100644
--- a/src/profiling/common/proc_utils_unittest.cc
+++ b/src/profiling/common/proc_utils_unittest.cc
@@ -16,7 +16,6 @@
#include "src/profiling/common/proc_utils.h"
#include "perfetto/ext/base/optional.h"
-#include "perfetto/profiling/normalize.h"
#include "perfetto/ext/base/utils.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 34c6263..a4c7777 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -256,6 +256,7 @@
"../common:callstack_trie",
"../common:interner",
"../common:interning_output",
+ "../common:proc_cmdline",
"../common:proc_utils",
"../common:producer_support",
"../common:profiler_guardrails",
diff --git a/src/profiling/memory/java_hprof_producer.cc b/src/profiling/memory/java_hprof_producer.cc
index 6c68995..81a9c27 100644
--- a/src/profiling/memory/java_hprof_producer.cc
+++ b/src/profiling/memory/java_hprof_producer.cc
@@ -21,6 +21,7 @@
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
+#include "src/profiling/common/proc_cmdline.h"
#include "src/profiling/common/proc_utils.h"
#include "src/profiling/common/producer_support.h"
@@ -58,10 +59,10 @@
JavaHprofProducer::DataSource::DataSource(
DataSourceConfig ds_config,
JavaHprofConfig config,
- std::vector<std::string> normalized_cmdlines)
- : ds_config_(ds_config),
- config_(config),
- normalized_cmdlines_(normalized_cmdlines) {}
+ std::vector<std::string> target_cmdlines)
+ : ds_config_(std::move(ds_config)),
+ config_(std::move(config)),
+ target_cmdlines_(std::move(target_cmdlines)) {}
void JavaHprofProducer::DataSource::SendSignal() const {
for (pid_t pid : pids_) {
@@ -97,9 +98,9 @@
void JavaHprofProducer::DataSource::CollectPids() {
pids_.clear();
for (uint64_t pid : config_.pid()) {
- pids_.emplace(static_cast<pid_t>(pid));
+ pids_.insert(static_cast<pid_t>(pid));
}
- FindPidsForCmdlines(normalized_cmdlines_, &pids_);
+ glob_aware::FindPidsForCmdlinePatterns(target_cmdlines_, &pids_);
if (config_.min_anonymous_memory_kb() > 0)
RemoveUnderAnonThreshold(config_.min_anonymous_memory_kb(), &pids_);
}
@@ -122,13 +123,8 @@
}
JavaHprofConfig config;
config.ParseFromString(ds_config.java_hprof_config_raw());
- base::Optional<std::vector<std::string>> normalized_cmdlines =
- NormalizeCmdlines(config.process_cmdline());
- if (!normalized_cmdlines.has_value()) {
- PERFETTO_ELOG("Rejecting data source due to invalid cmdline in config.");
- return;
- }
- DataSource ds(ds_config, std::move(config), std::move(*normalized_cmdlines));
+ std::vector<std::string> cmdline_patterns = config.process_cmdline();
+ DataSource ds(ds_config, std::move(config), std::move(cmdline_patterns));
ds.CollectPids();
data_sources_.emplace(id, ds);
}
diff --git a/src/profiling/memory/java_hprof_producer.h b/src/profiling/memory/java_hprof_producer.h
index 056c60a..4355d96 100644
--- a/src/profiling/memory/java_hprof_producer.h
+++ b/src/profiling/memory/java_hprof_producer.h
@@ -73,7 +73,7 @@
public:
DataSource(DataSourceConfig ds_config,
JavaHprofConfig config,
- std::vector<std::string> normalized_cmdlines);
+ std::vector<std::string> target_cmdlines);
void CollectPids();
void SendSignal() const;
@@ -83,7 +83,7 @@
private:
DataSourceConfig ds_config_;
JavaHprofConfig config_;
- std::vector<std::string> normalized_cmdlines_;
+ std::vector<std::string> target_cmdlines_;
std::set<pid_t> pids_;
};
diff --git a/src/profiling/perf/BUILD.gn b/src/profiling/perf/BUILD.gn
index 899e09c..341bd3a 100644
--- a/src/profiling/perf/BUILD.gn
+++ b/src/profiling/perf/BUILD.gn
@@ -51,7 +51,6 @@
deps = [
":proc_descriptors",
"../../../gn:default_deps",
- "../../../include/perfetto/profiling:normalize",
"../../../protos/perfetto/common:cpp",
"../../../protos/perfetto/common:zero",
"../../../protos/perfetto/config:cpp",
@@ -65,7 +64,7 @@
"../common:callstack_trie",
"../common:interner",
"../common:interning_output",
- "../common:proc_utils",
+ "../common:proc_cmdline",
"../common:producer_support",
"../common:profiler_guardrails",
]
diff --git a/src/profiling/perf/event_config.cc b/src/profiling/perf/event_config.cc
index 3759533..8506a1c 100644
--- a/src/profiling/perf/event_config.cc
+++ b/src/profiling/perf/event_config.cc
@@ -25,7 +25,6 @@
#include "perfetto/base/flat_set.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/ext/base/utils.h"
-#include "perfetto/profiling/normalize.h"
#include "src/profiling/perf/regs_parsing.h"
#include "protos/perfetto/common/perf_events.gen.h"
@@ -40,23 +39,6 @@
constexpr uint32_t kDefaultReadTickPeriodMs = 100;
constexpr uint32_t kDefaultRemoteDescriptorTimeoutMs = 100;
-base::Optional<std::string> Normalize(const std::string& src) {
- // Construct a null-terminated string that will be mutated by the normalizer.
- std::vector<char> base(src.size() + 1);
- memcpy(base.data(), src.data(), src.size());
- base[src.size()] = '\0';
-
- char* new_start = base.data();
- ssize_t new_sz = NormalizeCmdLine(&new_start, base.size());
- if (new_sz < 0) {
- PERFETTO_ELOG("Failed to normalize config cmdline [%s], aborting",
- base.data());
- return base::nullopt;
- }
- return base::make_optional<std::string>(new_start,
- static_cast<size_t>(new_sz));
-}
-
// Acceptable forms: "sched/sched_switch" or "sched:sched_switch".
std::pair<std::string, std::string> SplitTracepointString(
const std::string& input) {
@@ -100,40 +82,29 @@
return base::make_optional(tracepoint_id);
}
-// Returns |base::nullopt| if any of the input cmdlines couldn't be normalized.
// |T| is either gen::PerfEventConfig or gen::PerfEventConfig::Scope.
+// Note: the semantics of target_cmdline and exclude_cmdline were changed since
+// their original introduction. They used to be put through a canonicalization
+// function that simplified them to the binary name alone. We no longer do this,
+// regardless of whether we're parsing an old-style config. The overall outcome
+// shouldn't change for almost all existing uses.
template <typename T>
-base::Optional<TargetFilter> ParseTargetFilter(const T& cfg) {
+TargetFilter ParseTargetFilter(const T& cfg) {
TargetFilter filter;
for (const auto& str : cfg.target_cmdline()) {
- base::Optional<std::string> opt = Normalize(str);
- if (!opt.has_value()) {
- PERFETTO_ELOG("Failure normalizing cmdline: [%s]", str.c_str());
- return base::nullopt;
- }
- filter.cmdlines.insert(std::move(opt.value()));
+ filter.cmdlines.push_back(str);
}
-
for (const auto& str : cfg.exclude_cmdline()) {
- base::Optional<std::string> opt = Normalize(str);
- if (!opt.has_value()) {
- PERFETTO_ELOG("Failure normalizing cmdline: [%s]", str.c_str());
- return base::nullopt;
- }
- filter.exclude_cmdlines.insert(std::move(opt.value()));
+ filter.exclude_cmdlines.push_back(str);
}
-
for (const int32_t pid : cfg.target_pid()) {
filter.pids.insert(pid);
}
-
for (const int32_t pid : cfg.exclude_pid()) {
filter.exclude_pids.insert(pid);
}
-
filter.additional_cmdline_count = cfg.additional_cmdline_count();
-
- return base::make_optional(std::move(filter));
+ return filter;
}
constexpr bool IsPowerOfTwo(size_t v) {
@@ -389,14 +360,10 @@
sample_callstacks = true;
// Process scoping.
- auto maybe_filter =
+ target_filter =
pb_config.callstack_sampling().has_scope()
? ParseTargetFilter(pb_config.callstack_sampling().scope())
: ParseTargetFilter(pb_config); // backwards compatibility
- if (!maybe_filter.has_value())
- return base::nullopt;
-
- target_filter = std::move(maybe_filter.value());
// Inclusion of kernel callchains.
kernel_frames = pb_config.callstack_sampling().kernel_frames() ||
diff --git a/src/profiling/perf/event_config.h b/src/profiling/perf/event_config.h
index 782b05d..cb84168 100644
--- a/src/profiling/perf/event_config.h
+++ b/src/profiling/perf/event_config.h
@@ -44,8 +44,8 @@
// Parsed allow/deny-list for filtering samples.
// An empty filter set means that all targets are allowed.
struct TargetFilter {
- base::FlatSet<std::string> cmdlines;
- base::FlatSet<std::string> exclude_cmdlines;
+ std::vector<std::string> cmdlines;
+ std::vector<std::string> exclude_cmdlines;
base::FlatSet<pid_t> pids;
base::FlatSet<pid_t> exclude_pids;
uint32_t additional_cmdline_count = 0;
diff --git a/src/profiling/perf/perf_producer.cc b/src/profiling/perf/perf_producer.cc
index d49c558..22c4a6d 100644
--- a/src/profiling/perf/perf_producer.cc
+++ b/src/profiling/perf/perf_producer.cc
@@ -36,7 +36,7 @@
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "src/profiling/common/callstack_trie.h"
-#include "src/profiling/common/proc_utils.h"
+#include "src/profiling/common/proc_cmdline.h"
#include "src/profiling/common/producer_support.h"
#include "src/profiling/common/profiler_guardrails.h"
#include "src/profiling/common/unwind_support.h"
@@ -180,14 +180,27 @@
base::FlatSet<std::string>* additional_cmdlines,
const TargetFilter& filter) {
PERFETTO_CHECK(additional_cmdlines);
+
std::string cmdline;
- bool have_cmdline = GetCmdlineForPID(pid, &cmdline); // normalized form
- if (!have_cmdline) {
- PERFETTO_DLOG("Failed to look up cmdline for pid [%d]",
- static_cast<int>(pid));
+ bool have_cmdline = glob_aware::ReadProcCmdlineForPID(pid, &cmdline);
+
+ const char* binname = "";
+ if (have_cmdline) {
+ binname = glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());
}
- if (have_cmdline && filter.exclude_cmdlines.count(cmdline)) {
+ auto has_matching_pattern = [](const std::vector<std::string>& patterns,
+ const char* cmd, const char* name) {
+ for (const std::string& pattern : patterns) {
+ if (glob_aware::MatchGlobPattern(pattern.c_str(), cmd, name)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ if (have_cmdline &&
+ has_matching_pattern(filter.exclude_cmdlines, cmdline.c_str(), binname)) {
PERFETTO_DLOG("Explicitly rejecting samples for pid [%d] due to cmdline",
static_cast<int>(pid));
return true;
@@ -198,20 +211,21 @@
return true;
}
- if (have_cmdline && filter.cmdlines.count(cmdline)) {
+ if (have_cmdline &&
+ has_matching_pattern(filter.cmdlines, cmdline.c_str(), binname)) {
return false;
}
if (filter.pids.count(pid)) {
return false;
}
+
+ // Empty allow filter means keep everything that isn't explicitly excluded.
if (filter.cmdlines.empty() && filter.pids.empty() &&
!filter.additional_cmdline_count) {
- // If no filters are set allow everything.
return false;
}
- // If we didn't read the command line that's a good prediction we will not be
- // able to profile either.
+ // Config option that allows to profile just the N first seen cmdlines.
if (have_cmdline) {
if (additional_cmdlines->count(cmdline)) {
return false;
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index 16e8e3d..4f03344 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -282,22 +282,28 @@
return pages_read;
for (FtraceDataSource* data_source : started_data_sources) {
- bool pages_parsed_ok = ProcessPagesForDataSource(
+ size_t pages_parsed_ok = ProcessPagesForDataSource(
data_source->trace_writer(), data_source->mutable_metadata(), cpu_,
data_source->parsing_config(), parsing_buf, pages_read, table_,
symbolizer_, ftrace_clock_snapshot_, ftrace_clock_);
- // If this CHECK fires, it means that we did not know how to parse the
- // kernel binary format. This is a bug in either perfetto or the kernel, and
- // must be investigated. Hence we CHECK instead of recording a bit
- // in the ftrace stats proto, which is easier to overlook.
- PERFETTO_CHECK(pages_parsed_ok);
+ // If this happens, it means that we did not know how to parse the kernel
+ // binary format. This is a bug in either perfetto or the kernel, and must
+ // be investigated. Hence we abort instead of recording a bit in the ftrace
+ // stats proto, which is easier to overlook.
+ if (pages_parsed_ok != pages_read) {
+ const size_t first_bad_page_idx = pages_parsed_ok;
+ const uint8_t* curr_page =
+ parsing_buf + (first_bad_page_idx * base::kPageSize);
+ LogInvalidPage(curr_page, base::kPageSize);
+ PERFETTO_FATAL("Failed to parse ftrace page");
+ }
}
return pages_read;
}
// static
-bool CpuReader::ProcessPagesForDataSource(
+size_t CpuReader::ProcessPagesForDataSource(
TraceWriter* trace_writer,
FtraceMetadata* metadata,
size_t cpu,
@@ -405,7 +411,7 @@
bundle->set_lost_events(true);
};
- bool pages_parsed_ok = true;
+ size_t correctly_parsed_pages = pages_read;
start_new_packet(/*lost_events=*/false);
for (size_t i = 0; i < pages_read; i++) {
const uint8_t* curr_page = parsing_buf + (i * base::kPageSize);
@@ -417,9 +423,7 @@
if (!page_header.has_value() || page_header->size == 0 ||
parse_pos >= curr_page_end ||
parse_pos + page_header->size > curr_page_end) {
- LogInvalidPage(curr_page, base::kPageSize);
- PERFETTO_DFATAL("invalid page header");
- return false;
+ return i;
}
// Start a new bundle if either:
@@ -442,14 +446,16 @@
&compact_sched, bundle, metadata);
if (evt_size != page_header->size) {
- pages_parsed_ok = false;
- LogInvalidPage(curr_page, base::kPageSize);
- PERFETTO_DFATAL("could not parse ftrace page");
+ // TODO(ddiproietto,rsavitski): Consider returning early here instead, to
+ // improve readability.
+ if (correctly_parsed_pages == pages_read) {
+ correctly_parsed_pages = i;
+ }
}
}
finalize_cur_packet();
- return pages_parsed_ok;
+ return correctly_parsed_pages;
}
// A page header consists of:
diff --git a/src/traced/probes/ftrace/cpu_reader.h b/src/traced/probes/ftrace/cpu_reader.h
index 3f1eae7..414da31 100644
--- a/src/traced/probes/ftrace/cpu_reader.h
+++ b/src/traced/probes/ftrace/cpu_reader.h
@@ -234,17 +234,22 @@
// Parses & encodes the given range of contiguous tracing pages. Called by
// |ReadAndProcessBatch| for each active data source.
//
+ // Returns the number of correctly processed pages. If the return value is
+ // equal to |pages_read|, there was no error. Otherwise, the return value
+ // points to the first page that contains an error.
+ //
// public and static for testing
- static bool ProcessPagesForDataSource(TraceWriter* trace_writer,
- FtraceMetadata* metadata,
- size_t cpu,
- const FtraceDataSourceConfig* ds_config,
- const uint8_t* parsing_buf,
- const size_t pages_read,
- const ProtoTranslationTable* table,
- LazyKernelSymbolizer* symbolizer,
- const FtraceClockSnapshot*,
- protos::pbzero::FtraceClock);
+ static size_t ProcessPagesForDataSource(
+ TraceWriter* trace_writer,
+ FtraceMetadata* metadata,
+ size_t cpu,
+ const FtraceDataSourceConfig* ds_config,
+ const uint8_t* parsing_buf,
+ const size_t pages_read,
+ const ProtoTranslationTable* table,
+ LazyKernelSymbolizer* symbolizer,
+ const FtraceClockSnapshot*,
+ protos::pbzero::FtraceClock);
void set_ftrace_clock(protos::pbzero::FtraceClock clock) {
ftrace_clock_ = clock;
diff --git a/src/traced/probes/ftrace/cpu_reader_unittest.cc b/src/traced/probes/ftrace/cpu_reader_unittest.cc
index c918af8..44062e7 100644
--- a/src/traced/probes/ftrace/cpu_reader_unittest.cc
+++ b/src/traced/probes/ftrace/cpu_reader_unittest.cc
@@ -641,7 +641,6 @@
EXPECT_EQ(event.print().buf(), "");
}
-
TEST(CpuReaderTest, FilterByEvent) {
const ExamplePage* test_case = &g_single_print;
@@ -1244,6 +1243,17 @@
00000050: 0000 0000 950e 0000 7800 0000 0000 0000 ................
)";
+// Page with invalid data.
+static char g_invalid_page[] =
+ R"(
+ 00000000: 2b16 c3be 90b6 0300 4b00 0000 0000 0000 ................
+ 00000010: 1e00 0000 0000 0000 1000 0000 2f00 0103 ................
+ 00000020: 0300 0000 6b73 6f66 7469 7271 642f 3000 ................
+ 00000030: 0000 0000 0300 0000 7800 0000 0100 0000 ................
+ 00000040: 0000 0000 736c 6565 7000 722f 3000 0000 ................
+ 00000050: 0000 0000 950e 0000 7800 0000 0000 0000 ................
+ )";
+
TEST(CpuReaderTest, NewPacketOnLostEvents) {
auto page_ok = PageFromXxd(g_switch_page);
auto page_loss = PageFromXxd(g_switch_page_lost_events);
@@ -1269,11 +1279,13 @@
table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
TraceWriterForTesting trace_writer;
- CpuReader::ProcessPagesForDataSource(
+ size_t processed_pages = CpuReader::ProcessPagesForDataSource(
&trace_writer, &metadata, /*cpu=*/1, &ds_config, buf.get(), kTestPages,
table, /*symbolizer=*/nullptr, /*ftrace_clock_snapshot=*/nullptr,
protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
+ ASSERT_EQ(processed_pages, kTestPages);
+
// Each packet should contain the parsed contents of a contiguous run of pages
// without data loss.
// So we should get three packets (each page has 1 event):
@@ -1291,6 +1303,39 @@
EXPECT_EQ(4u, packets[2].ftrace_events().event().size());
}
+TEST(CpuReaderTest, ProcessPagesForDataSourceError) {
+ auto page_ok = PageFromXxd(g_switch_page);
+ auto page_err = PageFromXxd(g_invalid_page);
+
+ std::vector<const void*> test_page_order = {
+ page_ok.get(), page_ok.get(), page_ok.get(), page_err.get(),
+ page_ok.get(), page_ok.get(), page_err.get(), page_ok.get()};
+
+ // Prepare a buffer with 8 contiguous pages, with the above contents.
+ static constexpr size_t kTestPages = 8;
+
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[base::kPageSize * kTestPages]());
+ for (size_t i = 0; i < kTestPages; i++) {
+ void* dest = buf.get() + (i * base::kPageSize);
+ memcpy(dest, static_cast<const void*>(test_page_order[i]), base::kPageSize);
+ }
+
+ BundleProvider bundle_provider(base::kPageSize);
+ ProtoTranslationTable* table = GetTable("synthetic");
+ FtraceMetadata metadata{};
+ FtraceDataSourceConfig ds_config = EmptyConfig();
+ ds_config.event_filter.AddEnabledEvent(
+ table->EventToFtraceId(GroupAndName("sched", "sched_switch")));
+
+ TraceWriterForTesting trace_writer;
+ size_t processed_pages = CpuReader::ProcessPagesForDataSource(
+ &trace_writer, &metadata, /*cpu=*/1, &ds_config, buf.get(), kTestPages,
+ table, /*symbolizer=*/nullptr, /*ftrace_clock_snapshot=*/nullptr,
+ protos::pbzero::FTRACE_CLOCK_UNSPECIFIED);
+
+ EXPECT_EQ(processed_pages, 3u);
+}
+
// Page containing an absolute timestamp (RINGBUF_TYPE_TIME_STAMP).
static char g_abs_timestamp[] =
R"(
diff --git a/tools/cpu_profile b/tools/cpu_profile
index 2bce7b0..9dbeb44 100755
--- a/tools/cpu_profile
+++ b/tools/cpu_profile
@@ -439,7 +439,7 @@
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'trace_to_text',
@@ -448,11 +448,11 @@
'file_name':
'trace_to_text',
'file_size':
- 6972736,
+ 6525752,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/mac-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
'sha256':
- 'cd963e3f63b23977302fcbcb19a9fe64e98aeb2f419ce4212cfafa4e52b8faec',
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
'platform':
'darwin',
'machine': ['x86_64']
@@ -464,11 +464,11 @@
'file_name':
'trace_to_text.exe',
'file_size':
- 6685696,
+ 5925888,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/windows-amd64/trace_to_text.exe',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
'sha256':
- 'bc951b12148338ff151f33af87e79926d18b7ea3180419a7e6c6c150b604fe25',
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
'platform':
'win32',
'machine': ['amd64']
@@ -480,11 +480,11 @@
'file_name':
'trace_to_text',
'file_size':
- 7539312,
+ 6939560,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
'sha256':
- 'e40fbf44fca2673be1e6aedbc3159ce3cd4f6f33911f9dd1298471bd5b4a05ab',
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
'platform':
'linux',
'machine': ['x86_64']
diff --git a/tools/heap_profile b/tools/heap_profile
index 4539dc1..65a3213 100755
--- a/tools/heap_profile
+++ b/tools/heap_profile
@@ -576,7 +576,7 @@
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'trace_to_text',
@@ -585,11 +585,11 @@
'file_name':
'trace_to_text',
'file_size':
- 6972736,
+ 6525752,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/mac-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
'sha256':
- 'cd963e3f63b23977302fcbcb19a9fe64e98aeb2f419ce4212cfafa4e52b8faec',
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
'platform':
'darwin',
'machine': ['x86_64']
@@ -597,15 +597,31 @@
'tool':
'trace_to_text',
'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 5661424,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_to_text',
+ 'sha256':
+ 'fbb6d256c96cdc296f2faec2965d16a1527c4900e66a33aca979ff1c336a9f2f',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
'windows-amd64',
'file_name':
'trace_to_text.exe',
'file_size':
- 6685696,
+ 5925888,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/windows-amd64/trace_to_text.exe',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
'sha256':
- 'bc951b12148338ff151f33af87e79926d18b7ea3180419a7e6c6c150b604fe25',
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
'platform':
'win32',
'machine': ['amd64']
@@ -617,11 +633,11 @@
'file_name':
'trace_to_text',
'file_size':
- 7539312,
+ 6939560,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
'sha256':
- 'e40fbf44fca2673be1e6aedbc3159ce3cd4f6f33911f9dd1298471bd5b4a05ab',
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
'platform':
'linux',
'machine': ['x86_64']
diff --git a/tools/record_android_trace b/tools/record_android_trace
index 1134a06..f2931ed 100755
--- a/tools/record_android_trace
+++ b/tools/record_android_trace
@@ -404,7 +404,7 @@
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'tracebox',
@@ -413,11 +413,11 @@
'file_name':
'tracebox',
'file_size':
- 1046604,
+ 1067004,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/android-arm/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-arm/tracebox',
'sha256':
- 'a6ab413ef1aecbe93a73d9e3c9d6f00eb06b4c9886c0627a979a9acbf071a4a3'
+ '6fff40fc02d154b187187fe70069cc93bde00d3be5b3582ba6120b0cfa83d379'
}, {
'tool':
'tracebox',
@@ -426,11 +426,11 @@
'file_name':
'tracebox',
'file_size':
- 1588032,
+ 1620704,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/android-arm64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-arm64/tracebox',
'sha256':
- 'a0da06d2df7106712f90a5475ab8ef994ae844f4fee7bf4f38aaacc8260062cd'
+ 'd482c86eccd7dc0ff4f57bd5d841d90e97ca5e31b881fcea442d4ad03ecfd4f4'
}, {
'tool':
'tracebox',
@@ -439,11 +439,11 @@
'file_name':
'tracebox',
'file_size':
- 1615908,
+ 1644500,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/android-x86/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-x86/tracebox',
'sha256':
- 'a56591c10f29c00b425ade21d1c61086584166fb00236b9744e3cb06b777fbc8'
+ '48de1d10959b6130d2d6d68ae3ba0d8bb3f3aa6fe526d77ea9abad058a631d8f'
}, {
'tool':
'tracebox',
@@ -452,11 +452,11 @@
'file_name':
'tracebox',
'file_size':
- 1841984,
+ 1870560,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/android-x64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/android-x64/tracebox',
'sha256':
- '21db734c29f96436685c2a65086e231e03425e35bfdb6fd25a4af729c55c6619'
+ '333c17912a143300ca6afa3b27d93497821615028e612e5d6132889427c10599'
}]
diff --git a/tools/trace_processor b/tools/trace_processor
index 8bbab28..10c7836 100755
--- a/tools/trace_processor
+++ b/tools/trace_processor
@@ -27,7 +27,7 @@
TOOL_NAME = 'trace_processor_shell'
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'trace_processor_shell',
@@ -36,11 +36,11 @@
'file_name':
'trace_processor_shell',
'file_size':
- 6940768,
+ 7302832,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/mac-amd64/trace_processor_shell',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_processor_shell',
'sha256':
- '2d553933fdaba7080ff207094c0ed514a2f5573e525a653417b656b9c9c90e16',
+ 'edc841a7f6769959f3b03f1e93dcd263d30864dc3e1fc4e3fcdbe4e44e19b02a',
'platform':
'darwin',
'machine': ['x86_64']
@@ -48,15 +48,31 @@
'tool':
'trace_processor_shell',
'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_processor_shell',
+ 'file_size':
+ 6393768,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_processor_shell',
+ 'sha256':
+ '9f768e35d85501d18f09b0313c037a34f3306663d504f31e4874b1b3b20a00d6',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_processor_shell',
+ 'arch':
'windows-amd64',
'file_name':
'trace_processor_shell.exe',
'file_size':
- 6681600,
+ 6942720,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/windows-amd64/trace_processor_shell.exe',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_processor_shell.exe',
'sha256':
- '1f4cb1a8a1726ebbada1f928c7d856a04fd57994077cead0b65c7b32225ba48b',
+ 'c7118d820f720ca99acc9ef736f553cb0ba01d034e8f61b83f44d857f76058ce',
'platform':
'win32',
'machine': ['amd64']
@@ -68,11 +84,11 @@
'file_name':
'trace_processor_shell',
'file_size':
- 7520208,
+ 7824920,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/trace_processor_shell',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_processor_shell',
'sha256':
- '232acef777f0b0206d023bf705d1abfd64503a7762e50e813c693dd8bafd91bd',
+ '77ec0f9dbec36079d83f2843372446c354d04e7971c1f159c465d4e8e78a3d4d',
'platform':
'linux',
'machine': ['x86_64']
@@ -84,11 +100,11 @@
'file_name':
'trace_processor_shell',
'file_size':
- 4887472,
+ 5076040,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-arm/trace_processor_shell',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm/trace_processor_shell',
'sha256':
- 'b03ae322ed90ee7746f5cb33c9a92a82cec34540f3fb1997b343d8cad18db158',
+ '7290ef3bda83736d0076e49bab5524294906bc8d1785ccef876ba8bd490e62b9',
'platform':
'linux',
'machine': ['armv6l', 'armv7l', 'armv8l']
@@ -100,11 +116,11 @@
'file_name':
'trace_processor_shell',
'file_size':
- 6765656,
+ 7055416,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-arm64/trace_processor_shell',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm64/trace_processor_shell',
'sha256':
- '222240d00ca2ae3eac6908df275ca79e2b72ff6a0c934594d2744a2399a58dcc',
+ 'b3d91b69a4152419bc3de2df3aeaef400d829e4a87e5c5cb985af0b56f319279',
'platform':
'linux',
'machine': ['aarch64']
diff --git a/tools/tracebox b/tools/tracebox
index e7b1253..8dc234e 100755
--- a/tools/tracebox
+++ b/tools/tracebox
@@ -27,7 +27,7 @@
TOOL_NAME = 'tracebox'
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'tracebox',
@@ -36,11 +36,11 @@
'file_name':
'tracebox',
'file_size':
- 1332696,
+ 1382584,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/mac-amd64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/tracebox',
'sha256':
- 'be14a9040e8d0143d5b0838560cf20afb0be2d1971f6df4c79d7b4c46aa5852e',
+ '2b5eecebd92810d6f88598904fc52db4930f5f234bcb749c839eb25ebaf42a8c',
'platform':
'darwin',
'machine': ['x86_64']
@@ -48,15 +48,31 @@
'tool':
'tracebox',
'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'tracebox',
+ 'file_size':
+ 1275896,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/tracebox',
+ 'sha256':
+ '51049ce25a123b8990658bddbb52f5984e80c8c4e2eb06780f22534218cdbd1d',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'tracebox',
+ 'arch':
'linux-amd64',
'file_name':
'tracebox',
'file_size':
- 1756264,
+ 1786784,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/tracebox',
'sha256':
- '2fde750c982826f6a7c3e49b2d6ee7ec72c956170b4bba07e2989f2b81f26269',
+ '0df104d808715733cf717d5f2808e48e57bf20a851b49e1e579c516a34f4f9f9',
'platform':
'linux',
'machine': ['x86_64']
@@ -68,11 +84,11 @@
'file_name':
'tracebox',
'file_size':
- 1756264,
+ 1786784,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/tracebox',
'sha256':
- '2fde750c982826f6a7c3e49b2d6ee7ec72c956170b4bba07e2989f2b81f26269',
+ '0df104d808715733cf717d5f2808e48e57bf20a851b49e1e579c516a34f4f9f9',
'platform':
'linux',
'machine': ['x86_64']
@@ -84,11 +100,11 @@
'file_name':
'tracebox',
'file_size':
- 1012940,
+ 1032796,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-arm/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm/tracebox',
'sha256':
- 'a6f964b1b155c309fda0fb0b765f9fbf3d030d8c4bd6f9f03dad173ee689668e',
+ '4db159c84073f95e5f704137bff4c97aa32a714a9c93ba77f99eeedf9f3fc714',
'platform':
'linux',
'machine': ['armv6l', 'armv7l', 'armv8l']
@@ -100,11 +116,11 @@
'file_name':
'tracebox',
'file_size':
- 1635160,
+ 1663696,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-arm64/tracebox',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-arm64/tracebox',
'sha256':
- 'ed998b18606a6cffb490336990220e6290faa4544e52a5c77273f69507f80e89',
+ '75b7d877808a927962d15f8d5659ccce082e07797305cc739809aef98853bfce',
'platform':
'linux',
'machine': ['aarch64']
diff --git a/tools/traceconv b/tools/traceconv
index 663ad5a..ea13c77 100755
--- a/tools/traceconv
+++ b/tools/traceconv
@@ -27,7 +27,7 @@
TOOL_NAME = 'trace_to_text'
# BEGIN_SECTION_GENERATED_BY(roll-prebuilts)
-# Revision: v24.1
+# Revision: v25.0
PERFETTO_PREBUILT_MANIFEST = [{
'tool':
'trace_to_text',
@@ -36,11 +36,11 @@
'file_name':
'trace_to_text',
'file_size':
- 6972736,
+ 6525752,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/mac-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-amd64/trace_to_text',
'sha256':
- 'cd963e3f63b23977302fcbcb19a9fe64e98aeb2f419ce4212cfafa4e52b8faec',
+ '64ccf6bac87825145691c6533412e514891f82300d68ff7ce69e8d2ca69aaf62',
'platform':
'darwin',
'machine': ['x86_64']
@@ -48,15 +48,31 @@
'tool':
'trace_to_text',
'arch':
+ 'mac-arm64',
+ 'file_name':
+ 'trace_to_text',
+ 'file_size':
+ 5661424,
+ 'url':
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/mac-arm64/trace_to_text',
+ 'sha256':
+ 'fbb6d256c96cdc296f2faec2965d16a1527c4900e66a33aca979ff1c336a9f2f',
+ 'platform':
+ 'darwin',
+ 'machine': ['arm64']
+}, {
+ 'tool':
+ 'trace_to_text',
+ 'arch':
'linux-amd64',
'file_name':
'trace_to_text',
'file_size':
- 7539312,
+ 6939560,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/linux-amd64/trace_to_text',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/linux-amd64/trace_to_text',
'sha256':
- 'e40fbf44fca2673be1e6aedbc3159ce3cd4f6f33911f9dd1298471bd5b4a05ab',
+ '109f4ff3bbd47633b0c08a338f1230e69d529ddf1584656ed45d8a59acaaabeb',
'platform':
'linux',
'machine': ['x86_64']
@@ -68,11 +84,11 @@
'file_name':
'trace_to_text.exe',
'file_size':
- 6685696,
+ 5925888,
'url':
- 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v24.1/windows-amd64/trace_to_text.exe',
+ 'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v25.0/windows-amd64/trace_to_text.exe',
'sha256':
- 'bc951b12148338ff151f33af87e79926d18b7ea3180419a7e6c6c150b604fe25',
+ '29e50ec4d8e28c7c322ba13273afcce80c63fe7d9f182b83af0e2077b4d2b952',
'platform':
'win32',
'machine': ['amd64']