Merge "stdlib: OOM score" into main
diff --git a/bazel/proto_gen.bzl b/bazel/proto_gen.bzl
index c5fd127..e237ebc 100644
--- a/bazel/proto_gen.bzl
+++ b/bazel/proto_gen.bzl
@@ -46,13 +46,17 @@
strip_base_path = ctx.label.package + "/"
elif ctx.label.workspace_root:
# This path is hit when proto targets are built as @perfetto//:xxx
- # instead of //:xxx. This happens in embedder builds. In this case,
- # workspace_root == "external/perfetto" and we need to rebase the paths
- # passed to protoc.
+ # instead of //:xxx. This happens in embedder builds.
proto_path = ctx.label.workspace_root
- out_dir += "/" + ctx.label.workspace_root
+
+ # We could be using the sibling repository layout, in which case we do nothing.
+ if not ctx.label.workspace_root.startswith("../"):
+ # workspace_root == "external/perfetto" and we need to rebase the paths
+ # passed to protoc.
+ out_dir += "/" + ctx.label.workspace_root
strip_base_path = ctx.label.workspace_root + "/"
+
out_files = []
suffix = ctx.attr.suffix
for src in proto_src:
diff --git a/docs/reference/perfetto-cli.md b/docs/reference/perfetto-cli.md
index 195ceb1..377502e 100644
--- a/docs/reference/perfetto-cli.md
+++ b/docs/reference/perfetto-cli.md
@@ -124,7 +124,7 @@
: Specifies the path to a configuration file. In normal mode, some
configurations may be encoded in a configuration protocol buffer.
This file must comply with the protocol buffer schema defined in AOSP
- [`trace_config.proto`](/protos/perfetto/config/data_source_config.proto).
+ [`trace_config.proto`](/protos/perfetto/config/trace_config.proto).
You select and configure the data sources using the DataSourceConfig member
of the TraceConfig, as defined in AOSP
[`data_source_config.proto`](/protos/perfetto/config/data_source_config.proto).
diff --git a/gn/standalone/protoc.py b/gn/standalone/protoc.py
index 52e156e..bd8913f 100644
--- a/gn/standalone/protoc.py
+++ b/gn/standalone/protoc.py
@@ -16,45 +16,9 @@
This script exists to work-around the bad depfile generation by protoc when
generating descriptors."""
-from __future__ import print_function
-import argparse
-import os
import sys
import subprocess
-import tempfile
-import uuid
-
-from codecs import open
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--descriptor_set_out', default=None)
- parser.add_argument('--dependency_out', default=None)
- parser.add_argument('protoc')
- args, remaining = parser.parse_known_args()
-
- if args.dependency_out and args.descriptor_set_out:
- tmp_path = os.path.join(tempfile.gettempdir(), str(uuid.uuid4()))
- custom = [
- '--descriptor_set_out', args.descriptor_set_out, '--dependency_out',
- tmp_path
- ]
- try:
- cmd = [args.protoc] + custom + remaining
- subprocess.check_call(cmd)
- with open(tmp_path, 'rb') as tmp_rd:
- dependency_data = tmp_rd.read().decode('utf-8')
- finally:
- if os.path.exists(tmp_path):
- os.unlink(tmp_path)
-
- with open(args.dependency_out, 'w', encoding='utf-8') as f:
- f.write(args.descriptor_set_out + ":")
- f.write(dependency_data)
- else:
- subprocess.check_call(sys.argv[1:])
if __name__ == '__main__':
- sys.exit(main())
+ sys.exit(subprocess.call(sys.argv[1:]))
diff --git a/include/perfetto/ext/base/getopt.h b/include/perfetto/ext/base/getopt.h
index bf993fc..abf8cca 100644
--- a/include/perfetto/ext/base/getopt.h
+++ b/include/perfetto/ext/base/getopt.h
@@ -45,7 +45,7 @@
::perfetto::base::getopt_compat::required_argument;
#else
-#include <getopt.h>
+#include <getopt.h> // IWYU pragma: export
#endif
#endif // INCLUDE_PERFETTO_EXT_BASE_GETOPT_H_
diff --git a/protos/perfetto/common/observable_events.proto b/protos/perfetto/common/observable_events.proto
index 85767a6..b841a0b 100644
--- a/protos/perfetto/common/observable_events.proto
+++ b/protos/perfetto/common/observable_events.proto
@@ -63,6 +63,9 @@
// consumer has no idea of what is the TSID of its own tracing session and
// there is no other good way to plumb it.
optional int64 tracing_session_id = 1;
+
+ // The trigger name of the CLONE_SNAPSHOT trigger which was hit.
+ optional string trigger_name = 2;
}
repeated DataSourceInstanceStateChange instance_state_changes = 1;
diff --git a/protos/perfetto/trace/android/BUILD.gn b/protos/perfetto/trace/android/BUILD.gn
index 900a64b..90234da 100644
--- a/protos/perfetto/trace/android/BUILD.gn
+++ b/protos/perfetto/trace/android/BUILD.gn
@@ -15,7 +15,10 @@
import("../../../../gn/proto_library.gni")
perfetto_proto_library("@TYPE@") {
- deps = [ "../../common:@TYPE@", ":winscope_regular_@TYPE@" ]
+ deps = [
+ ":winscope_regular_@TYPE@",
+ "../../common:@TYPE@",
+ ]
sources = [
"android_game_intervention_list.proto",
@@ -44,8 +47,8 @@
# Winscope messages added to TracePacket directly
perfetto_proto_library("winscope_regular_@TYPE@") {
deps = [
- "../../common:@TYPE@",
":winscope_common_@TYPE@",
+ "../../common:@TYPE@",
]
sources = [
"protolog.proto",
@@ -64,19 +67,19 @@
]
public_deps = [ ":winscope_common_@TYPE@" ]
sources = [
- "inputmethodeditor.proto",
"graphics/pixelformat.proto",
+ "inputmethodeditor.proto",
"inputmethodservice/inputmethodservice.proto",
"inputmethodservice/softinputwindow.proto",
"server/inputmethod/inputmethodmanagerservice.proto",
"typedef.proto",
- "view/inputmethod/editorinfo.proto",
- "view/inputmethod/inputconnection.proto",
- "view/inputmethod/inputmethodmanager.proto",
"view/display.proto",
"view/displaycutout.proto",
"view/imefocuscontroller.proto",
"view/imeinsetssourceconsumer.proto",
+ "view/inputmethod/editorinfo.proto",
+ "view/inputmethod/inputconnection.proto",
+ "view/inputmethod/inputmethodmanager.proto",
"view/insetsanimationcontrolimpl.proto",
"view/insetscontroller.proto",
"view/insetssource.proto",
@@ -95,8 +98,8 @@
proto_generators = [ "descriptor" ]
generate_descriptor = "winscope.descriptor"
deps = [
- ":winscope_regular_source_set",
":winscope_extensions_source_set",
+ ":winscope_regular_source_set",
]
sources = [ "winscope.proto" ]
import_dirs = [ "${perfetto_protobuf_src_dir}" ]
diff --git a/src/android_internal/statsd_logging.cc b/src/android_internal/statsd_logging.cc
index a164adf..09b55a2 100644
--- a/src/android_internal/statsd_logging.cc
+++ b/src/android_internal/statsd_logging.cc
@@ -16,12 +16,11 @@
#include "src/android_internal/statsd_logging.h"
-#include <string.h>
+#include <cstdint>
#include <statslog_perfetto.h>
-namespace perfetto {
-namespace android_internal {
+namespace perfetto::android_internal {
void StatsdLogUploadEvent(PerfettoStatsdAtom atom,
int64_t uuid_lsb,
@@ -35,5 +34,4 @@
stats_write(PERFETTO_TRIGGER, static_cast<int32_t>(atom), trigger_name);
}
-} // namespace android_internal
-} // namespace perfetto
+} // namespace perfetto::android_internal
diff --git a/src/android_stats/perfetto_atoms.h b/src/android_stats/perfetto_atoms.h
index 1981a77..6352042 100644
--- a/src/android_stats/perfetto_atoms.h
+++ b/src/android_stats/perfetto_atoms.h
@@ -27,6 +27,8 @@
// Checkpoints inside perfetto_cmd before tracing is finished.
kTraceBegin = 1,
kBackgroundTraceBegin = 2,
+ kCloneTraceBegin = 55,
+ kCloneTriggerTraceBegin = 56,
kOnConnect = 3,
// Guardrails inside perfetto_cmd before tracing is finished.
@@ -105,7 +107,7 @@
// longer supports uploading traces using Dropbox.
// reserved 5, 6, 7;
- // Contained status of guardrail state initalization and upload limit in
+ // Contained status of guardrail state initialization and upload limit in
// perfetto_cmd. Removed as perfetto no longer manages stateful guardrails
// reserved 44, 45, 46;
};
diff --git a/src/android_stats/statsd_logging_helper.cc b/src/android_stats/statsd_logging_helper.cc
index c943027..1f5011a 100644
--- a/src/android_stats/statsd_logging_helper.cc
+++ b/src/android_stats/statsd_logging_helper.cc
@@ -16,10 +16,12 @@
#include "src/android_stats/statsd_logging_helper.h"
+#include <cstdint>
#include <string>
+#include <vector>
#include "perfetto/base/build_config.h"
-#include "perfetto/base/compiler.h"
+#include "src/android_stats/perfetto_atoms.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
@@ -27,8 +29,7 @@
#include "src/android_internal/statsd_logging.h" // nogncheck
#endif
-namespace perfetto {
-namespace android_stats {
+namespace perfetto::android_stats {
// Make sure we don't accidentally log on non-Android tree build. Note that even
// removing this ifdef still doesn't make uploads work on OS_ANDROID.
@@ -75,5 +76,4 @@
const std::vector<std::string>&) {}
#endif
-} // namespace android_stats
-} // namespace perfetto
+} // namespace perfetto::android_stats
diff --git a/src/android_stats/statsd_logging_helper.h b/src/android_stats/statsd_logging_helper.h
index 5f0911f..0ba2d65 100644
--- a/src/android_stats/statsd_logging_helper.h
+++ b/src/android_stats/statsd_logging_helper.h
@@ -18,6 +18,7 @@
#define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
#include <stdint.h>
+#include <optional>
#include <string>
#include <vector>
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 2ccd24e..e11a485 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -16,46 +16,47 @@
#include "src/perfetto_cmd/perfetto_cmd.h"
-#include "perfetto/base/build_config.h"
-#include "perfetto/base/proc_utils.h"
-#include "perfetto/ext/base/scoped_file.h"
-#include "perfetto/ext/base/string_splitter.h"
-
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
-// For dup() (and _setmode() on windows).
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-#include <fcntl.h>
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-
+#include <algorithm>
+#include <array>
#include <atomic>
#include <chrono>
-#include <fstream>
+#include <cinttypes>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+#include <functional>
#include <iostream>
#include <iterator>
+#include <memory>
#include <mutex>
+#include <optional>
#include <random>
-#include <sstream>
+#include <string>
#include <thread>
+#include <utility>
+#include <vector>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
-#include "perfetto/base/time.h"
-#include "perfetto/ext/base/android_utils.h"
+#include "perfetto/base/proc_utils.h" // IWYU pragma: keep
+#include "perfetto/ext/base/android_utils.h" // IWYU pragma: keep
#include "perfetto/ext/base/ctrl_c_handler.h"
#include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/getopt.h"
+#include "perfetto/ext/base/getopt.h" // IWYU pragma: keep
#include "perfetto/ext/base/no_destructor.h"
#include "perfetto/ext/base/pipe.h"
+#include "perfetto/ext/base/scoped_file.h"
+#include "perfetto/ext/base/string_splitter.h"
+#include "perfetto/ext/base/string_utils.h"
#include "perfetto/ext/base/string_view.h"
-#include "perfetto/ext/base/temp_file.h"
+#include "perfetto/ext/base/thread_task_runner.h"
#include "perfetto/ext/base/thread_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/base/uuid.h"
@@ -64,11 +65,14 @@
#include "perfetto/ext/traced/traced.h"
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/trace_packet.h"
-#include "perfetto/protozero/proto_utils.h"
-#include "perfetto/tracing/core/data_source_descriptor.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
+#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "perfetto/tracing/core/flush_flags.h"
+#include "perfetto/tracing/core/forward_decls.h"
#include "perfetto/tracing/core/trace_config.h"
-#include "perfetto/tracing/core/tracing_service_state.h"
#include "perfetto/tracing/default_socket.h"
+#include "protos/perfetto/common/data_source_descriptor.gen.h"
+#include "src/android_stats/perfetto_atoms.h"
#include "src/android_stats/statsd_logging_helper.h"
#include "src/perfetto_cmd/bugreport_path.h"
#include "src/perfetto_cmd/config.h"
@@ -81,6 +85,14 @@
#include "protos/perfetto/common/tracing_service_state.gen.h"
#include "protos/perfetto/common/track_event_descriptor.gen.h"
+// For dup() (and _setmode() on windows).
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <fcntl.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
namespace perfetto {
namespace {
@@ -92,7 +104,7 @@
class LoggingErrorReporter : public ErrorReporter {
public:
LoggingErrorReporter(std::string file_name, const char* config)
- : file_name_(file_name), config_(config) {}
+ : file_name_(std::move(file_name)), config_(config) {}
void AddError(size_t row,
size_t column,
@@ -1014,7 +1026,14 @@
std::this_thread::sleep_for(std::chrono::milliseconds(dist(minstd)));
}
- if (trace_config_->trigger_config().trigger_timeout_ms() == 0) {
+ if (clone_tsid_) {
+ if (snapshot_trigger_name_.empty()) {
+ LogUploadEvent(PerfettoStatsdAtom::kCloneTraceBegin);
+ } else {
+ LogUploadEvent(PerfettoStatsdAtom::kCloneTriggerTraceBegin,
+ snapshot_trigger_name_);
+ }
+ } else if (trace_config_->trigger_config().trigger_timeout_ms() == 0) {
LogUploadEvent(PerfettoStatsdAtom::kTraceBegin);
} else {
LogUploadEvent(PerfettoStatsdAtom::kBackgroundTraceBegin);
@@ -1533,11 +1552,15 @@
}
if (observable_events.has_clone_trigger_hit()) {
int64_t tsid = observable_events.clone_trigger_hit().tracing_session_id();
- OnCloneSnapshotTriggerReceived(static_cast<TracingSessionID>(tsid));
+ std::string trigger_name =
+ observable_events.clone_trigger_hit().trigger_name();
+ OnCloneSnapshotTriggerReceived(static_cast<TracingSessionID>(tsid),
+ std::move(trigger_name));
}
}
-void PerfettoCmd::OnCloneSnapshotTriggerReceived(TracingSessionID tsid) {
+void PerfettoCmd::OnCloneSnapshotTriggerReceived(TracingSessionID tsid,
+ std::string trigger_name) {
std::string cmdline;
cmdline.reserve(128);
ArgsAppend(&cmdline, "perfetto");
@@ -1555,13 +1578,15 @@
} else {
PERFETTO_FATAL("Cannot use CLONE_SNAPSHOT with the current cmdline args");
}
- CloneSessionOnThread(tsid, cmdline, kSingleExtraThread, nullptr);
+ CloneSessionOnThread(tsid, cmdline, kSingleExtraThread,
+ std::move(trigger_name), nullptr);
}
void PerfettoCmd::CloneSessionOnThread(
TracingSessionID tsid,
const std::string& cmdline,
CloneThreadMode thread_mode,
+ std::string trigger_name,
std::function<void()> on_clone_callback) {
PERFETTO_DLOG("Creating snapshot for tracing session %" PRIu64, tsid);
@@ -1583,7 +1608,7 @@
std::string trace_config_copy = trace_config_->SerializeAsString();
snapshot_threads_.back().PostTask(
- [tsid, cmdline, trace_config_copy, on_clone_callback] {
+ [tsid, cmdline, trace_config_copy, trigger_name, on_clone_callback] {
int argc = 0;
char* argv[32];
// `splitter` needs to live on the stack for the whole scope as it owns
@@ -1595,6 +1620,7 @@
}
perfetto::PerfettoCmd cmd;
cmd.snapshot_config_ = std::move(trace_config_copy);
+ cmd.snapshot_trigger_name_ = std::move(trigger_name);
cmd.on_session_cloned_ = on_clone_callback;
auto cmdline_res = cmd.ParseCmdlineAndMaybeDaemonize(argc, argv);
PERFETTO_CHECK(!cmdline_res.has_value()); // No daemonization expected.
@@ -1686,7 +1712,7 @@
ArgsAppend(&cmdline, "--clone-for-bugreport");
ArgsAppend(&cmdline, "--out");
ArgsAppend(&cmdline, out_path);
- CloneSessionOnThread(it->tsid, cmdline, kNewThreadPerRequest, sync_fn);
+ CloneSessionOnThread(it->tsid, cmdline, kNewThreadPerRequest, "", sync_fn);
} // for(sessions)
PERFETTO_DLOG("Issuing %zu CloneSession requests", num_sessions);
@@ -1720,6 +1746,15 @@
android_stats::MaybeLogUploadEvent(atom, uuid.lsb(), uuid.msb());
}
+void PerfettoCmd::LogUploadEvent(PerfettoStatsdAtom atom,
+ const std::string& trigger_name) {
+ if (!statsd_logging_)
+ return;
+ base::Uuid uuid(uuid_);
+ android_stats::MaybeLogUploadEvent(atom, uuid.lsb(), uuid.msb(),
+ trigger_name);
+}
+
void PerfettoCmd::LogTriggerEvents(
PerfettoTriggerAtom atom,
const std::vector<std::string>& trigger_names) {
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index 844afaf..160a701 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -17,8 +17,7 @@
#ifndef SRC_PERFETTO_CMD_PERFETTO_CMD_H_
#define SRC_PERFETTO_CMD_PERFETTO_CMD_H_
-#include <time.h>
-
+#include <cstdint>
#include <functional>
#include <list>
#include <memory>
@@ -32,9 +31,12 @@
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/thread_task_runner.h"
#include "perfetto/ext/base/unix_task_runner.h"
+#include "perfetto/ext/base/uuid.h"
#include "perfetto/ext/base/weak_ptr.h"
+#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/consumer.h"
#include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "perfetto/tracing/core/forward_decls.h"
#include "src/android_stats/perfetto_atoms.h"
#include "src/perfetto_cmd/packet_writer.h"
@@ -86,6 +88,7 @@
void CloneSessionOnThread(TracingSessionID,
const std::string& cmdline, // \0 separated.
CloneThreadMode,
+ std::string clone_trigger_name,
std::function<void()> on_clone_callback);
void OnTimeout();
bool is_detach() const { return !detach_key_.empty(); }
@@ -126,7 +129,8 @@
// will have no effect.
void NotifyBgProcessPipe(BgProcessStatus status);
- void OnCloneSnapshotTriggerReceived(TracingSessionID);
+ void OnCloneSnapshotTriggerReceived(TracingSessionID,
+ std::string trigger_name);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
static base::ScopedFile CreateUnlinkedTmpFile();
@@ -135,6 +139,7 @@
void ReportTraceToAndroidFrameworkOrCrash();
#endif
void LogUploadEvent(PerfettoStatsdAtom atom);
+ void LogUploadEvent(PerfettoStatsdAtom atom, const std::string& trigger_name);
void LogTriggerEvents(PerfettoTriggerAtom atom,
const std::vector<std::string>& trigger_names);
@@ -185,6 +190,7 @@
std::list<base::ThreadTaskRunner> snapshot_threads_;
int snapshot_count_ = 0;
std::string snapshot_config_;
+ std::string snapshot_trigger_name_;
base::WeakPtrFactory<PerfettoCmd> weak_factory_{this};
};
diff --git a/src/trace_processor/importers/common/process_tracker.cc b/src/trace_processor/importers/common/process_tracker.cc
index 3fc95fc..e292801 100644
--- a/src/trace_processor/importers/common/process_tracker.cc
+++ b/src/trace_processor/importers/common/process_tracker.cc
@@ -356,6 +356,17 @@
UniquePid upid = GetOrCreateProcess(pid);
auto* process_table = context_->storage->mutable_process_table();
+ // If we both know the previous and current parent pid and the two are not
+ // matching, we must have died and restarted: create a new process.
+ if (pupid) {
+ std::optional<UniquePid> prev_parent_upid =
+ process_table->parent_upid()[upid];
+ if (prev_parent_upid && prev_parent_upid != pupid) {
+ upid = StartNewProcess(std::nullopt, ppid, pid, kNullStringId,
+ ThreadNamePriority::kOther);
+ }
+ }
+
StringId proc_name_id = context_->storage->InternString(name);
process_table->mutable_name()->Set(upid, proc_name_id);
process_table->mutable_cmdline()->Set(
diff --git a/src/trace_redaction/main.cc b/src/trace_redaction/main.cc
index 296f12f..78bf3d0 100644
--- a/src/trace_redaction/main.cc
+++ b/src/trace_redaction/main.cc
@@ -84,10 +84,18 @@
auto* redact_ftrace_events = redactor.emplace_transform<RedactFtraceEvent>();
redact_ftrace_events
- ->emplace_back<RedactTaskNewTask::kFieldId, RedactTaskNewTask>();
- redact_ftrace_events
->emplace_back<RemoveProcessFreeComm::kFieldId, RemoveProcessFreeComm>();
+ // By default, the comm value is cleared. However, when thread merging is
+ // enabled (kTaskNewtaskFieldNumber + ThreadMergeDropField), the event is
+ // dropped, meaning that this primitive was effectivly a no-op. This primitive
+ // remains so that removing thread merging won't leak thread names via new
+ // task events.
+ auto* redact_new_task =
+ redact_ftrace_events
+ ->emplace_back<RedactTaskNewTask::kFieldId, RedactTaskNewTask>();
+ redact_new_task->emplace_back<ClearComms>();
+
// This set of transformations will change pids. This will break the
// connections between pids and the timeline (the synth threads are not in the
// timeline). If a transformation uses the timeline, it must be before this
diff --git a/src/trace_redaction/redact_ftrace_event.h b/src/trace_redaction/redact_ftrace_event.h
index 9de6cc6..68aff05 100644
--- a/src/trace_redaction/redact_ftrace_event.h
+++ b/src/trace_redaction/redact_ftrace_event.h
@@ -57,8 +57,12 @@
// Add a new redaction. T must extend FtraceEventRedaction. This relies on the
// honor system; no more than one redaction can be mapped to a field.
template <uint32_t field_id, class T>
- void emplace_back() {
- redactions_.Insert(field_id, std::make_unique<T>());
+ T* emplace_back() {
+ auto ptr = std::make_unique<T>();
+ T* raw_ptr = ptr.get();
+
+ redactions_.Insert(field_id, std::move(ptr));
+ return raw_ptr;
}
private:
diff --git a/src/trace_redaction/redact_task_newtask.cc b/src/trace_redaction/redact_task_newtask.cc
index fb0cfe8..7a0fbeb 100644
--- a/src/trace_redaction/redact_task_newtask.cc
+++ b/src/trace_redaction/redact_task_newtask.cc
@@ -16,28 +16,15 @@
#include "src/trace_redaction/redact_task_newtask.h"
-#include "src/trace_redaction/proto_util.h"
-
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
#include "protos/perfetto/trace/ftrace/task.pbzero.h"
+#include "src/trace_processor/util/status_macros.h"
namespace perfetto::trace_redaction {
namespace {
-// TODO(vaage): Merge with RedactComm in redact_sched_switch.cc.
-protozero::ConstChars RedactComm(const Context& context,
- uint64_t ts,
- int32_t pid,
- protozero::ConstChars comm) {
- if (context.timeline->PidConnectsToUid(ts, pid, *context.package_uid)) {
- return comm;
- }
-
- return {};
-}
-
} // namespace
// Redact sched switch trace events in an ftrace event bundle:
//
@@ -56,9 +43,11 @@
// equal to "event.task_newtask.pid" (a thread cannot start itself).
base::Status RedactTaskNewTask::Redact(
const Context& context,
- const protos::pbzero::FtraceEventBundle::Decoder&,
+ const protos::pbzero::FtraceEventBundle::Decoder& bundle,
protozero::ProtoDecoder& event,
protos::pbzero::FtraceEvent* event_message) const {
+ PERFETTO_DCHECK(transform_);
+
if (!context.package_uid.has_value()) {
return base::ErrStatus("RedactTaskNewTask: missing package uid");
}
@@ -68,45 +57,41 @@
}
// The timestamp is needed to do the timeline look-up. If the packet has no
- // timestamp, don't add the sched switch event. This is the safest option.
- auto timestamp =
+ // timestamp, don't add the sched switch event.
+ auto timestamp_field =
event.FindField(protos::pbzero::FtraceEvent::kTimestampFieldNumber);
- if (!timestamp.valid()) {
- return base::OkStatus();
- }
-
- auto new_task =
+ auto new_task_field =
event.FindField(protos::pbzero::FtraceEvent::kTaskNewtaskFieldNumber);
- if (!new_task.valid()) {
+
+ if (!timestamp_field.valid() || !new_task_field.valid()) {
return base::ErrStatus(
- "RedactTaskNewTask: was used for unsupported field type");
+ "RedactTaskNewTask: missing required FtraceEvent field.");
}
- protozero::ProtoDecoder new_task_decoder(new_task.as_bytes());
+ protos::pbzero::TaskNewtaskFtraceEvent::Decoder new_task(
+ new_task_field.as_bytes());
- auto pid = new_task_decoder.FindField(
- protos::pbzero::TaskNewtaskFtraceEvent::kPidFieldNumber);
-
- if (!pid.valid()) {
- return base::OkStatus();
+ // There are only four fields in a new task event. Since two of them can
+ // change, it is easier to work with them directly.
+ if (!new_task.has_pid() || !new_task.has_comm() ||
+ !new_task.has_clone_flags() || !new_task.has_oom_score_adj()) {
+ return base::ErrStatus(
+ "RedactTaskNewTask: missing required TaskNewtaskFtraceEvent field.");
}
- // Avoid making the message until we know that we have prev and next pids.
+ auto pid = new_task.pid();
+ auto comm = new_task.comm().ToStdString();
+
+ auto cpu = static_cast<int32_t>(bundle.cpu());
+
+ RETURN_IF_ERROR(transform_->Transform(context, timestamp_field.as_uint64(),
+ cpu, &pid, &comm));
+
auto* new_task_message = event_message->set_task_newtask();
-
- for (auto field = new_task_decoder.ReadField(); field.valid();
- field = new_task_decoder.ReadField()) {
- // Perfetto view (ui.perfetto.dev) crashes if the comm value is missing.
- // To work around this, the comm value is replaced with an empty string.
- // This appears to work.
- if (field.id() ==
- protos::pbzero::TaskNewtaskFtraceEvent::kCommFieldNumber) {
- new_task_message->set_comm(RedactComm(context, timestamp.as_uint64(),
- pid.as_int32(), field.as_string()));
- } else {
- proto_util::AppendField(field, new_task_message);
- }
- }
+ new_task_message->set_pid(pid);
+ new_task_message->set_comm(comm);
+ new_task_message->set_clone_flags(new_task.clone_flags());
+ new_task_message->set_oom_score_adj(new_task.oom_score_adj());
return base::OkStatus();
}
diff --git a/src/trace_redaction/redact_task_newtask.h b/src/trace_redaction/redact_task_newtask.h
index 51c1124..5b589fc 100644
--- a/src/trace_redaction/redact_task_newtask.h
+++ b/src/trace_redaction/redact_task_newtask.h
@@ -18,6 +18,7 @@
#define SRC_TRACE_REDACTION_REDACT_TASK_NEWTASK_H_
#include "src/trace_redaction/redact_ftrace_event.h"
+#include "src/trace_redaction/redact_sched_switch.h"
#include "src/trace_redaction/trace_redaction_framework.h"
namespace perfetto::trace_redaction {
@@ -34,6 +35,14 @@
const protos::pbzero::FtraceEventBundle::Decoder& bundle,
protozero::ProtoDecoder& event,
protos::pbzero::FtraceEvent* event_message) const override;
+
+ template <class Transform>
+ void emplace_back() {
+ transform_ = std::make_unique<Transform>();
+ }
+
+ public:
+ std::unique_ptr<SchedSwitchTransform> transform_;
};
} // namespace perfetto::trace_redaction
diff --git a/src/trace_redaction/redact_task_newtask_unittest.cc b/src/trace_redaction/redact_task_newtask_unittest.cc
index 33886f6..11b1405 100644
--- a/src/trace_redaction/redact_task_newtask_unittest.cc
+++ b/src/trace_redaction/redact_task_newtask_unittest.cc
@@ -16,19 +16,21 @@
#include "src/trace_redaction/redact_task_newtask.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
-#include "protos/perfetto/trace/ftrace/task.gen.h"
+#include "src/base/test/status_matchers.h"
#include "test/gtest_and_gmock.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.gen.h"
#include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
#include "protos/perfetto/trace/ftrace/ftrace_event_bundle.gen.h"
-#include "protos/perfetto/trace/ftrace/sched.gen.h"
+#include "protos/perfetto/trace/ftrace/task.gen.h"
#include "protos/perfetto/trace/trace.gen.h"
#include "protos/perfetto/trace/trace_packet.gen.h"
namespace perfetto::trace_redaction {
namespace {
+constexpr uint64_t kCpu = 1;
+
constexpr uint64_t kUidA = 1;
constexpr uint64_t kUidB = 2;
@@ -44,19 +46,23 @@
class RedactTaskNewTaskTest : public testing::Test {
protected:
void SetUp() override {
- auto* event = bundle_.add_event();
+ bundle_.set_cpu(kCpu);
+ auto* event = bundle_.add_event();
event->set_timestamp(123456789);
event->set_pid(kPidA);
auto* new_task = event->mutable_task_newtask();
+ new_task->set_clone_flags(0);
new_task->set_comm(std::string(kCommA));
+ new_task->set_oom_score_adj(0);
new_task->set_pid(kPidA);
}
base::Status Redact(const Context& context,
protos::pbzero::FtraceEvent* event_message) {
RedactTaskNewTask redact;
+ redact.emplace_back<ClearComms>();
auto bundle_str = bundle_.SerializeAsString();
protos::pbzero::FtraceEventBundle::Decoder bundle_decoder(bundle_str);
@@ -93,8 +99,6 @@
};
TEST_F(RedactTaskNewTaskTest, RejectMissingPackageUid) {
- RedactTaskNewTask redact;
-
Context context;
context.timeline = std::make_unique<ProcessThreadTimeline>();
@@ -106,8 +110,6 @@
}
TEST_F(RedactTaskNewTaskTest, RejectMissingTimeline) {
- RedactTaskNewTask redact;
-
Context context;
context.package_uid = kUidA;
@@ -119,8 +121,6 @@
}
TEST_F(RedactTaskNewTaskTest, PidInPackageKeepsComm) {
- RedactTaskNewTask redact;
-
// Because Uid A is the target, when Pid A starts (new task event), it should
// keep its comm value.
Context context;
@@ -130,8 +130,7 @@
protos::pbzero::FtraceEvent::Decoder event_decoder(event_string());
protozero::HeapBuffered<protos::pbzero::FtraceEvent> event_message;
- auto result = Redact(context, event_message.get());
- ASSERT_TRUE(result.ok());
+ ASSERT_OK(Redact(context, event_message.get()));
protos::gen::FtraceEvent redacted_event;
redacted_event.ParseFromString(event_message.SerializeAsString());
@@ -142,8 +141,6 @@
}
TEST_F(RedactTaskNewTaskTest, PidOutsidePackageLosesComm) {
- RedactTaskNewTask redact;
-
// Because Uid B is the target, when Pid A starts (new task event), it should
// lose its comm value.
Context context;
@@ -153,8 +150,7 @@
protos::pbzero::FtraceEvent::Decoder event_decoder(event_string());
protozero::HeapBuffered<protos::pbzero::FtraceEvent> event_message;
- auto result = Redact(context, event_message.get());
- ASSERT_TRUE(result.ok());
+ ASSERT_OK(Redact(context, event_message.get()));
protos::gen::FtraceEvent redacted_event;
redacted_event.ParseFromString(event_message.SerializeAsString());
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index 66b9b1b..4045978 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -869,6 +869,9 @@
case kDevId64ToUint64:
ReadDevId<uint64_t>(field_start, field_id, message, metadata);
return true;
+ case kFtraceSymAddr32ToUint64:
+ ReadSymbolAddr<uint32_t>(field_start, field_id, message, metadata);
+ return true;
case kFtraceSymAddr64ToUint64:
ReadSymbolAddr<uint64_t>(field_start, field_id, message, metadata);
return true;
diff --git a/src/traced/probes/ftrace/event_info_constants.cc b/src/traced/probes/ftrace/event_info_constants.cc
index 37f9c77..4a0d08f 100644
--- a/src/traced/probes/ftrace/event_info_constants.cc
+++ b/src/traced/probes/ftrace/event_info_constants.cc
@@ -106,6 +106,8 @@
*out = kBoolToUint64;
} else if (ftrace == kFtraceDataLoc && proto == ProtoSchemaType::kString) {
*out = kDataLocToString;
+ } else if (ftrace == kFtraceSymAddr32 && proto == ProtoSchemaType::kUint64) {
+ *out = kFtraceSymAddr32ToUint64;
} else if (ftrace == kFtraceSymAddr64 && proto == ProtoSchemaType::kUint64) {
*out = kFtraceSymAddr64ToUint64;
} else {
diff --git a/src/traced/probes/ftrace/event_info_constants.h b/src/traced/probes/ftrace/event_info_constants.h
index 0283f12..cce144f 100644
--- a/src/traced/probes/ftrace/event_info_constants.h
+++ b/src/traced/probes/ftrace/event_info_constants.h
@@ -48,6 +48,7 @@
kFtraceDevId32,
kFtraceDevId64,
kFtraceDataLoc,
+ kFtraceSymAddr32,
kFtraceSymAddr64,
};
@@ -84,6 +85,7 @@
kDevId32ToUint64,
kDevId64ToUint64,
kDataLocToString,
+ kFtraceSymAddr32ToUint64,
kFtraceSymAddr64ToUint64,
};
@@ -127,6 +129,7 @@
return "devid64";
case kFtraceDataLoc:
return "__data_loc";
+ case kFtraceSymAddr32:
case kFtraceSymAddr64:
return "void*";
case kInvalidFtraceFieldType:
diff --git a/src/traced/probes/ftrace/proto_translation_table.cc b/src/traced/probes/ftrace/proto_translation_table.cc
index 9dcde14..7e9092e 100644
--- a/src/traced/probes/ftrace/proto_translation_table.cc
+++ b/src/traced/probes/ftrace/proto_translation_table.cc
@@ -239,6 +239,7 @@
case kFtraceUint64:
case kFtraceInode32:
case kFtraceInode64:
+ case kFtraceSymAddr32:
case kFtraceSymAddr64:
*proto_type = ProtoSchemaType::kUint64;
*proto_field_id = GenericFtraceEvent::Field::kUintValueFieldNumber;
@@ -310,13 +311,16 @@
return true;
}
- // Kernel addresses that need symbolization via kallsyms. Only 64-bit kernels
- // are supported for now. 32-bit kernels seems to be going away.
- if ((base::StartsWith(type_and_name, "void*") ||
- base::StartsWith(type_and_name, "void *")) &&
- size == 8) {
- *out = kFtraceSymAddr64;
- return true;
+ // Kernel addresses that need symbolization via kallsyms.
+ if (base::StartsWith(type_and_name, "void*") ||
+ base::StartsWith(type_and_name, "void *")) {
+ if (size == 4) {
+ *out = kFtraceSymAddr32;
+ return true;
+ } else if (size == 8) {
+ *out = kFtraceSymAddr64;
+ return true;
+ }
}
// Variable length strings: "char foo" + size: 0 (as in 'print').
diff --git a/src/tracing/service/tracing_service_impl.cc b/src/tracing/service/tracing_service_impl.cc
index d667767..6631d68 100644
--- a/src/tracing/service/tracing_service_impl.cc
+++ b/src/tracing/service/tracing_service_impl.cc
@@ -24,6 +24,7 @@
#include <limits>
#include <optional>
#include <regex>
+#include <string>
#include <unordered_set>
#include "perfetto/base/time.h"
#include "perfetto/ext/tracing/core/client_identity.h"
@@ -1689,13 +1690,14 @@
tracing_session.config, tracing_session.trace_uuid,
PerfettoStatsdAtom::kTracedTriggerCloneSnapshot, iter->name());
task_runner_->PostDelayedTask(
- [weak_this, tsid] {
+ [weak_this, tsid, trigger_name = iter->name()] {
if (!weak_this)
return;
auto* tsess = weak_this->GetTracingSession(tsid);
if (!tsess || !tsess->consumer_maybe_null)
return;
- tsess->consumer_maybe_null->NotifyCloneSnapshotTrigger();
+ tsess->consumer_maybe_null->NotifyCloneSnapshotTrigger(
+ trigger_name);
},
iter->stop_delay_ms());
break;
@@ -4265,13 +4267,15 @@
observable_events->set_all_data_sources_started(true);
}
-void TracingServiceImpl::ConsumerEndpointImpl::NotifyCloneSnapshotTrigger() {
+void TracingServiceImpl::ConsumerEndpointImpl::NotifyCloneSnapshotTrigger(
+ const std::string& trigger_name) {
if (!(observable_events_mask_ & ObservableEvents::TYPE_CLONE_TRIGGER_HIT)) {
return;
}
auto* observable_events = AddObservableEvents();
auto* clone_trig = observable_events->mutable_clone_trigger_hit();
clone_trig->set_tracing_session_id(static_cast<int64_t>(tracing_session_id_));
+ clone_trig->set_trigger_name(trigger_name);
}
ObservableEvents*
diff --git a/src/tracing/service/tracing_service_impl.h b/src/tracing/service/tracing_service_impl.h
index 9fa84fe..1dbcbe6 100644
--- a/src/tracing/service/tracing_service_impl.h
+++ b/src/tracing/service/tracing_service_impl.h
@@ -32,6 +32,7 @@
#include "perfetto/base/time.h"
#include "perfetto/ext/base/circular_queue.h"
#include "perfetto/ext/base/periodic_task.h"
+#include "perfetto/ext/base/string_view.h"
#include "perfetto/ext/base/uuid.h"
#include "perfetto/ext/base/weak_ptr.h"
#include "perfetto/ext/tracing/core/basic_types.h"
@@ -211,7 +212,7 @@
~ConsumerEndpointImpl() override;
void NotifyOnTracingDisabled(const std::string& error);
- void NotifyCloneSnapshotTrigger();
+ void NotifyCloneSnapshotTrigger(const std::string& trigger_name);
// TracingService::ConsumerEndpoint implementation.
void EnableTracing(const TraceConfig&, base::ScopedFile) override;
diff --git a/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py b/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py
index a706d7e..83e1034 100644
--- a/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py
+++ b/test/trace_processor/diff_tests/parser/process_tracking/process_tracking_exec.py
@@ -22,24 +22,25 @@
trace = synth_common.create_trace()
-# Create a parent process which will be forked below.
+# Create a parent process which will be forked below.
trace.add_packet(ts=1)
trace.add_process(10, 0, "parent")
-# Fork off the new process and then kill it 5ns later.
+# Fork the process into a child.
trace.add_ftrace_packet(0)
trace.add_newtask(ts=15, tid=10, new_tid=11, new_comm='child', flags=0)
trace.add_sched(ts=16, prev_pid=10, next_pid=11, next_comm='child')
-# Create a parent process which will be forked below.
+# Scrape event for the forked process.
trace.add_packet(ts=20)
-trace.add_process(11, 0, "child_process")
+trace.add_process(11, 10, "child_process")
+# Rename of the main thread of forked process.
trace.add_ftrace_packet(0)
trace.add_rename(
ts=25, tid=11, old_comm='child', new_comm='true_name', oom_score_adj=1000)
-# Create a parent process which will be forked below.
+# Scrape of the forked process.
trace.add_packet(ts=30)
trace.add_process(11, 10, "true_process_name")
diff --git a/test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py b/test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py
index 68641ad..19bf834 100644
--- a/test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py
+++ b/test/trace_processor/diff_tests/parser/process_tracking/synth_process_tracking.py
@@ -90,7 +90,7 @@
ts=28, prev_pid=32, next_pid=40, prev_comm='p3-t2', next_comm='p4-t0')
trace.add_packet(ts=29)
-trace.add_process(40, 0, "process_4")
+trace.add_process(40, 30, "process_4")
# And now, this new process starts a new thread that recycles TID=31 (previously
# used as p3-t1, now becomes p4-t1).
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 31972d4..62d1ac6 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -185,6 +185,11 @@
# Keep in sync with Chromium's //third_party/protobuf.
Dependency(
'buildtools/protobuf',
+ # If you revert the below version back to an earlier version of
+ # protobuf, make sure to revert the changes to
+ # //gn/standalone/protoc.py as well.
+ #
+ # This comment can be removed with protobuf is next upreved.
'https://chromium.googlesource.com/external/github.com/protocolbuffers/protobuf.git',
'f0dc78d7e6e331b8c6bb2d5283e06aa26883ca7c', # refs/tags/v21.12
'all',