Merge "Detect heapprofd with untrustworth self_max_count."
diff --git a/src/trace_processor/importers/proto/heap_profile_tracker.cc b/src/trace_processor/importers/proto/heap_profile_tracker.cc
index 951bb8c..968da7d 100644
--- a/src/trace_processor/importers/proto/heap_profile_tracker.cc
+++ b/src/trace_processor/importers/proto/heap_profile_tracker.cc
@@ -177,9 +177,10 @@
uint32_t merged_idx =
callsite_to_merged_callsite[*callsites_tbl.id().IndexOf(
CallsiteId(static_cast<uint32_t>(callsite_id)))];
- // On Android R, the count field is incorrectly set. As such, we cannot
- // depend on count == 0 to imply size == 0, so we check for both of them
- // separately. TODO(fmayer): Hide count on R builds.
+ // On old heapprofd producers, the count field is incorrectly set and we
+ // zero it in proto_trace_parser.cc.
+ // As such, we cannot depend on count == 0 to imply size == 0, so we check
+ // for both of them separately.
if (size > 0) {
tbl->mutable_alloc_size()->Set(merged_idx,
tbl->alloc_size()[merged_idx] + size);
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 4a2e0b9..f35618c 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -336,6 +336,11 @@
stats::heapprofd_unwind_samples, static_cast<int>(entry.pid()),
static_cast<int64_t>(stats.heap_samples()));
+ // orig_sampling_interval_bytes was introduced slightly after a bug with
+ // self_max_count was fixed in the producer. We use this as a proxy
+ // whether or not we are getting this data from a fixed producer or not.
+ bool trustworthy_max_count = entry.orig_sampling_interval_bytes() > 0;
+
for (auto sample_it = entry.samples(); sample_it; ++sample_it) {
protos::pbzero::ProfilePacket::HeapSample::Decoder sample(*sample_it);
@@ -351,7 +356,8 @@
src_allocation.callstack_id = sample.callstack_id();
if (sample.has_self_max()) {
src_allocation.self_allocated = sample.self_max();
- src_allocation.alloc_count = sample.self_max_count();
+ if (trustworthy_max_count)
+ src_allocation.alloc_count = sample.self_max_count();
} else {
src_allocation.self_allocated = sample.self_allocated();
src_allocation.self_freed = sample.self_freed();
diff --git a/test/trace_processor/profiling/heap_profile_dump_max.out b/test/trace_processor/profiling/heap_profile_dump_max.out
new file mode 100644
index 0000000..1ef5076
--- /dev/null
+++ b/test/trace_processor/profiling/heap_profile_dump_max.out
@@ -0,0 +1,3 @@
+"id","type","ts","upid","heap_name","callsite_id","count","size"
+0,"heap_profile_allocation",-10,2,"malloc",2,6,1000
+1,"heap_profile_allocation",-10,2,"malloc",3,1,90
diff --git a/test/trace_processor/profiling/heap_profile_dump_max.textproto b/test/trace_processor/profiling/heap_profile_dump_max.textproto
new file mode 100644
index 0000000..6efbfe1
--- /dev/null
+++ b/test/trace_processor/profiling/heap_profile_dump_max.textproto
@@ -0,0 +1,149 @@
+packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+}
+
+packet {
+ clock_snapshot {
+ clocks: {
+ clock_id: 6 # BOOTTIME
+ timestamp: 0
+ }
+ clocks: {
+ clock_id: 4 # MONOTONIC_COARSE
+ timestamp: 10
+ }
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 999
+ previous_packet_dropped: true
+ incremental_state_cleared: true
+ timestamp: 10
+ profile_packet {
+ strings {
+ iid: 1
+ str: "f1"
+ }
+ strings {
+ iid: 2
+ str: "f2"
+ }
+ strings {
+ iid: 3
+ str: "f3"
+ }
+ strings {
+ iid: 4
+ str: "liblib.so"
+ }
+ strings {
+ iid: 5
+ str: "build-id"
+ }
+ frames {
+ iid: 1
+ function_name_id: 1
+ mapping_id: 1
+ rel_pc: 0x1000
+ }
+ frames {
+ iid: 2
+ function_name_id: 2
+ mapping_id: 1
+ rel_pc: 0x2000
+ }
+ frames {
+ iid: 3
+ function_name_id: 3
+ mapping_id: 1
+ rel_pc: 0x3000
+ }
+ frames {
+ iid: 4
+ function_name_id: 2
+ mapping_id: 2
+ rel_pc: 0x4000
+ }
+ callstacks {
+ iid: 1
+ frame_ids: 1
+ frame_ids: 2
+ frame_ids: 3
+ }
+ callstacks {
+ iid: 2
+ frame_ids: 1
+ frame_ids: 4
+ }
+ mappings {
+ iid: 1
+ path_string_ids: 4
+ build_id: 5
+ }
+ mappings {
+ iid: 2
+ path_string_ids: 4
+ build_id: 5
+ }
+ process_dumps {
+ pid: 2
+ orig_sampling_interval_bytes: 1024
+ sampling_interval_bytes: 1024
+ samples {
+ callstack_id: 1
+ self_max: 1000
+ self_max_count: 6
+ }
+ samples {
+ callstack_id: 2
+ self_max: 90
+ self_max_count: 1
+ }
+ }
+ }
+}
+# Add some symbolization packets
+packet {
+ module_symbols {
+ path: "/liblib.so"
+ build_id: "build-id"
+ address_symbols {
+ address: 0x3000
+ lines {
+ function_name: "symbolized f3"
+ source_file_name: "f3.cc"
+ line_number: 33
+ }
+ }
+ address_symbols {
+ address: 0x2000
+ lines {
+ function_name: "symbolized f2"
+ source_file_name: "f2.cc"
+ line_number: 22
+ }
+ }
+ address_symbols {
+ address: 0x4000
+ lines {
+ function_name: "symbolized f2"
+ source_file_name: "f2.cc"
+ line_number: 23
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/profiling/heap_profile_dump_max_legacy.out b/test/trace_processor/profiling/heap_profile_dump_max_legacy.out
new file mode 100644
index 0000000..a5e6319
--- /dev/null
+++ b/test/trace_processor/profiling/heap_profile_dump_max_legacy.out
@@ -0,0 +1,3 @@
+"id","type","ts","upid","heap_name","callsite_id","count","size"
+0,"heap_profile_allocation",-10,2,"malloc",2,0,1000
+1,"heap_profile_allocation",-10,2,"malloc",3,0,90
diff --git a/test/trace_processor/profiling/heap_profile_dump_max_legacy.textproto b/test/trace_processor/profiling/heap_profile_dump_max_legacy.textproto
new file mode 100644
index 0000000..86cadb4
--- /dev/null
+++ b/test/trace_processor/profiling/heap_profile_dump_max_legacy.textproto
@@ -0,0 +1,147 @@
+packet {
+ process_tree {
+ processes {
+ pid: 1
+ ppid: 0
+ cmdline: "init"
+ uid: 0
+ }
+ processes {
+ pid: 2
+ ppid: 1
+ cmdline: "system_server"
+ uid: 1000
+ }
+ }
+}
+
+packet {
+ clock_snapshot {
+ clocks: {
+ clock_id: 6 # BOOTTIME
+ timestamp: 0
+ }
+ clocks: {
+ clock_id: 4 # MONOTONIC_COARSE
+ timestamp: 10
+ }
+ }
+}
+
+packet {
+ trusted_packet_sequence_id: 999
+ previous_packet_dropped: true
+ incremental_state_cleared: true
+ timestamp: 10
+ profile_packet {
+ strings {
+ iid: 1
+ str: "f1"
+ }
+ strings {
+ iid: 2
+ str: "f2"
+ }
+ strings {
+ iid: 3
+ str: "f3"
+ }
+ strings {
+ iid: 4
+ str: "liblib.so"
+ }
+ strings {
+ iid: 5
+ str: "build-id"
+ }
+ frames {
+ iid: 1
+ function_name_id: 1
+ mapping_id: 1
+ rel_pc: 0x1000
+ }
+ frames {
+ iid: 2
+ function_name_id: 2
+ mapping_id: 1
+ rel_pc: 0x2000
+ }
+ frames {
+ iid: 3
+ function_name_id: 3
+ mapping_id: 1
+ rel_pc: 0x3000
+ }
+ frames {
+ iid: 4
+ function_name_id: 2
+ mapping_id: 2
+ rel_pc: 0x4000
+ }
+ callstacks {
+ iid: 1
+ frame_ids: 1
+ frame_ids: 2
+ frame_ids: 3
+ }
+ callstacks {
+ iid: 2
+ frame_ids: 1
+ frame_ids: 4
+ }
+ mappings {
+ iid: 1
+ path_string_ids: 4
+ build_id: 5
+ }
+ mappings {
+ iid: 2
+ path_string_ids: 4
+ build_id: 5
+ }
+ process_dumps {
+ pid: 2
+ samples {
+ callstack_id: 1
+ self_max: 1000
+ self_max_count: 6
+ }
+ samples {
+ callstack_id: 2
+ self_max: 90
+ self_max_count: 1
+ }
+ }
+ }
+}
+# Add some symbolization packets
+packet {
+ module_symbols {
+ path: "/liblib.so"
+ build_id: "build-id"
+ address_symbols {
+ address: 0x3000
+ lines {
+ function_name: "symbolized f3"
+ source_file_name: "f3.cc"
+ line_number: 33
+ }
+ }
+ address_symbols {
+ address: 0x2000
+ lines {
+ function_name: "symbolized f2"
+ source_file_name: "f2.cc"
+ line_number: 22
+ }
+ }
+ address_symbols {
+ address: 0x4000
+ lines {
+ function_name: "symbolized f2"
+ source_file_name: "f2.cc"
+ line_number: 23
+ }
+ }
+ }
+}
diff --git a/test/trace_processor/profiling/index b/test/trace_processor/profiling/index
index ab299b5..60166f5 100644
--- a/test/trace_processor/profiling/index
+++ b/test/trace_processor/profiling/index
@@ -3,6 +3,8 @@
heap_profile_jit.textproto heap_profile_frames.sql heap_profile_jit.out
heap_profile_deobfuscate.textproto heap_profile_deobfuscate.sql heap_profile_deobfuscate.out
heap_profile_deobfuscate_memfd.textproto heap_profile_deobfuscate.sql heap_profile_deobfuscate.out
+heap_profile_dump_max_legacy.textproto heap_profile_tracker_new_stack.sql heap_profile_dump_max_legacy.out
+heap_profile_dump_max.textproto heap_profile_tracker_new_stack.sql heap_profile_dump_max.out
profiler_smaps.textproto profiler_smaps.sql profiler_smaps.out