Merge "Separate the actual trace to pprof conversion"
diff --git a/BUILD b/BUILD
index aca32e3..c5bdbca 100644
--- a/BUILD
+++ b/BUILD
@@ -115,8 +115,8 @@
"src/protozero/protoc_plugin/protozero_plugin.cc",
],
deps = [
- "//third_party/protobuf",
- "//third_party/protobuf:libprotoc",
+ "//third_party/protobuf:libprotoc_legacy",
+ "//third_party/protobuf:protobuf_legacy",
],
)
@@ -671,8 +671,8 @@
"//third_party/perfetto/protos:trace_sys_stats_zero_cc_proto",
"//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
"//third_party/perfetto/protos:trace_zero_cc_proto",
- "//third_party/protobuf",
- "//third_party/protobuf:libprotoc",
+ "//third_party/protobuf:libprotoc_legacy",
+ "//third_party/protobuf:protobuf_legacy",
"//third_party/sqlite",
"//third_party/sqlite:sqlite_ext_percentile",
"//third_party/zlib:zlibsystem",
@@ -938,8 +938,8 @@
"//third_party/perfetto/protos:trace_track_event_cc_proto",
"//third_party/perfetto/protos:trace_track_event_zero_cc_proto",
"//third_party/perfetto/protos:trace_zero_cc_proto",
- "//third_party/protobuf",
- "//third_party/protobuf:libprotoc",
+ "//third_party/protobuf:libprotoc_legacy",
+ "//third_party/protobuf:protobuf_legacy",
"//third_party/sqlite",
"//third_party/sqlite:sqlite_ext_percentile",
"//third_party/zlib:zlibsystem",
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index 2ad06b2..cfad464 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -51,7 +51,8 @@
// refers to them (since the last reset of interning state). They may also be
// emitted proactively in advance of referring to them in later packets.
//
-// Next id: 8.
+// Next reserved id: 8 (up to 15).
+// Next id: 20.
message InternedData {
// Each field's message type needs to specify an |iid| field, which is the ID
// of the entry in the field's interning index. Each field constructs its own
@@ -73,8 +74,6 @@
repeated InternedString mapping_paths = 17;
// Names of functions used in frames below.
repeated InternedString function_names = 5;
- // Symbol tables added to the end of the trace, for the current sequence.
- repeated InternedModuleSymbol module_symbols = 20;
// Executable files mapped into processes.
repeated Mapping mappings = 19;
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 86b59e9..6f3843a 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -2602,7 +2602,8 @@
// refers to them (since the last reset of interning state). They may also be
// emitted proactively in advance of referring to them in later packets.
//
-// Next id: 8.
+// Next reserved id: 8 (up to 15).
+// Next id: 20.
message InternedData {
// Each field's message type needs to specify an |iid| field, which is the ID
// of the entry in the field's interning index. Each field constructs its own
@@ -2624,8 +2625,6 @@
repeated InternedString mapping_paths = 17;
// Names of functions used in frames below.
repeated InternedString function_names = 5;
- // Symbol tables added to the end of the trace, for the current sequence.
- repeated InternedModuleSymbol module_symbols = 20;
// Executable files mapped into processes.
repeated Mapping mappings = 19;
@@ -2732,9 +2731,9 @@
// A symbol field that is emitted after the trace is written. These tables would
// be appended as the last packets in the trace that the profiler will use, so
// that the actual trace need not be rewritten to symbolize the profiles.
-message InternedModuleSymbol {
+message ProfiledFrameSymbols {
// Use the frame id as the interning key for the symbols.
- optional int64 frame_id = 1;
+ optional int64 frame_iid = 1;
optional int64 function_name_id = 2; // key to InternedString
optional int64 file_name_id = 3; // key to InternedString
@@ -3060,7 +3059,7 @@
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 54.
+// Next id: 56.
message TracePacket {
// TODO(primiano): in future we should add a timestamp_clock_domain field to
// allow mixing timestamps from different clock domains.
@@ -3096,6 +3095,9 @@
GpuRenderStageEvent gpu_render_stage_event = 53;
StreamingProfilePacket streaming_profile_packet = 54;
+ // Only used in profile packets.
+ ProfiledFrameSymbols profiled_frame_symbols = 55;
+
// Only used by TrackEvent.
ProcessDescriptor process_descriptor = 43;
ThreadDescriptor thread_descriptor = 44;
diff --git a/protos/perfetto/trace/profiling/profile_common.proto b/protos/perfetto/trace/profiling/profile_common.proto
index d0983e1..42c13db 100644
--- a/protos/perfetto/trace/profiling/profile_common.proto
+++ b/protos/perfetto/trace/profiling/profile_common.proto
@@ -34,9 +34,9 @@
// A symbol field that is emitted after the trace is written. These tables would
// be appended as the last packets in the trace that the profiler will use, so
// that the actual trace need not be rewritten to symbolize the profiles.
-message InternedModuleSymbol {
+message ProfiledFrameSymbols {
// Use the frame id as the interning key for the symbols.
- optional int64 frame_id = 1;
+ optional int64 frame_iid = 1;
optional int64 function_name_id = 2; // key to InternedString
optional int64 file_name_id = 3; // key to InternedString
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 756fa51..c2a138e 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -34,6 +34,7 @@
import "perfetto/trace/perfetto/perfetto_metatrace.proto";
import "perfetto/trace/power/battery_counters.proto";
import "perfetto/trace/power/power_rails.proto";
+import "perfetto/trace/profiling/profile_common.proto";
import "perfetto/trace/profiling/profile_packet.proto";
import "perfetto/trace/ps/process_stats.proto";
import "perfetto/trace/ps/process_tree.proto";
@@ -51,7 +52,7 @@
// TracePacket(s).
//
// Next reserved id: 13 (up to 15).
-// Next id: 54.
+// Next id: 56.
message TracePacket {
// TODO(primiano): in future we should add a timestamp_clock_domain field to
// allow mixing timestamps from different clock domains.
@@ -87,6 +88,9 @@
GpuRenderStageEvent gpu_render_stage_event = 53;
StreamingProfilePacket streaming_profile_packet = 54;
+ // Only used in profile packets.
+ ProfiledFrameSymbols profiled_frame_symbols = 55;
+
// Only used by TrackEvent.
ProcessDescriptor process_descriptor = 43;
ThreadDescriptor thread_descriptor = 44;
diff --git a/src/tracing/core/tracing_service_impl.cc b/src/tracing/core/tracing_service_impl.cc
index 11e042f..bd887ea 100644
--- a/src/tracing/core/tracing_service_impl.cc
+++ b/src/tracing/core/tracing_service_impl.cc
@@ -1426,8 +1426,13 @@
base::TimeMillis now = base::GetWallTimeMs();
if (now >= tracing_session->last_snapshot_time + kSnapshotsInterval) {
tracing_session->last_snapshot_time = now;
+ // Don't emit the stats immediately, but instead wait until no more trace
+ // data is available to read. That way, any problems that occur while
+ // reading from the buffers are reflected in the emitted stats. This is
+ // particularly important for use cases where ReadBuffers is only ever
+ // called after the tracing session is stopped.
+ tracing_session->should_emit_stats = true;
SnapshotSyncMarker(&packets);
- SnapshotStats(tracing_session, &packets);
if (!tracing_session->config.builtin_data_sources()
.disable_clock_snapshotting()) {
@@ -1530,6 +1535,19 @@
} // for(packets...)
} // for(buffers...)
+ const bool has_more = did_hit_threshold;
+ if (!has_more && tracing_session->should_emit_stats) {
+ size_t prev_packets_size = packets.size();
+ SnapshotStats(tracing_session, &packets);
+ tracing_session->should_emit_stats = false;
+
+ // Add sizes of packets emitted by SnapshotStats.
+ for (size_t i = prev_packets_size; i < packets.size(); ++i) {
+ packets_bytes += packets[i].size();
+ total_slices += packets[i].slices().size();
+ }
+ }
+
// If the caller asked us to write into a file by setting
// |write_into_file| == true in the trace config, drain the packets read
// (if any) into the given file descriptor.
@@ -1614,7 +1632,6 @@
return;
} // if (tracing_session->write_into_file)
- const bool has_more = did_hit_threshold;
if (has_more) {
auto weak_consumer = consumer->GetWeakPtr();
auto weak_this = weak_ptr_factory_.GetWeakPtr();
diff --git a/src/tracing/core/tracing_service_impl.h b/src/tracing/core/tracing_service_impl.h
index 0146f8b..9f009a0 100644
--- a/src/tracing/core/tracing_service_impl.h
+++ b/src/tracing/core/tracing_service_impl.h
@@ -452,6 +452,10 @@
// the output stream.
base::TimeMillis last_snapshot_time = {};
+ // Whether we should emit the trace stats next time we reach EOF while
+ // performing ReadBuffers.
+ bool should_emit_stats = false;
+
// Whether we mirrored the trace config back to the trace output yet.
bool did_emit_config = false;
diff --git a/src/tracing/core/tracing_service_impl_unittest.cc b/src/tracing/core/tracing_service_impl_unittest.cc
index 24e2988..547c9f9 100644
--- a/src/tracing/core/tracing_service_impl_unittest.cc
+++ b/src/tracing/core/tracing_service_impl_unittest.cc
@@ -1347,8 +1347,7 @@
// SystemInfo
// Trace read clocksnapshot
// Trace synchronisation
- // Trace stats
- static const int kNumPreamblePackets = 6;
+ static const int kNumPreamblePackets = 5;
static const int kNumTestPackets = 9;
static const char kPayload[] = "1234567890abcdef-";
diff --git a/tools/gen_bazel b/tools/gen_bazel
index 010f69d..6f7d5ca 100755
--- a/tools/gen_bazel
+++ b/tools/gen_bazel
@@ -95,8 +95,8 @@
def enable_protobuf_full(module):
- module.deps.add(Label('//third_party/protobuf:libprotoc'))
- module.deps.add(Label('//third_party/protobuf'))
+ module.deps.add(Label('//third_party/protobuf:libprotoc_legacy'))
+ module.deps.add(Label('//third_party/protobuf:protobuf_legacy'))
def enable_perfetto_version(module):
diff --git a/tools/trace_to_text/trace_to_systrace.cc b/tools/trace_to_text/trace_to_systrace.cc
index ffb503e..53a873b 100644
--- a/tools/trace_to_text/trace_to_systrace.cc
+++ b/tools/trace_to_text/trace_to_systrace.cc
@@ -229,8 +229,11 @@
auto p_callback = [](Iterator* it, base::StringWriter* writer) {
uint32_t pid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
uint32_t ppid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
- const char* name = it->Get(2 /* col */).string_value;
- FormatProcess(pid, ppid, name, writer);
+ const auto& name_col = it->Get(2 /* col */);
+ auto name_view = name_col.type == trace_processor::SqlValue::kString
+ ? base::StringView(name_col.string_value)
+ : base::StringView();
+ FormatProcess(pid, ppid, name_view, writer);
};
if (!q_writer.RunQuery(kPSql, p_callback))
return 1;
@@ -240,12 +243,15 @@
// Write out all the threads in the trace.
static const char kTSql[] =
"select tid, COALESCE(upid, 0), thread.name "
- "from thread inner join process using (upid)";
+ "from thread left join process using (upid)";
auto t_callback = [](Iterator* it, base::StringWriter* writer) {
uint32_t tid = static_cast<uint32_t>(it->Get(0 /* col */).long_value);
uint32_t tgid = static_cast<uint32_t>(it->Get(1 /* col */).long_value);
- const char* name = it->Get(2 /* col */).string_value;
- FormatThread(tid, tgid, name, writer);
+ const auto& name_col = it->Get(2 /* col */);
+ auto name_view = name_col.type == trace_processor::SqlValue::kString
+ ? base::StringView(name_col.string_value)
+ : base::StringView();
+ FormatThread(tid, tgid, name_view, writer);
};
if (!q_writer.RunQuery(kTSql, t_callback))
return 1;