Merge "TraceProcessor: Improve atrace parser" am: aeff6922a9
Original change: https://android-review.googlesource.com/c/platform/external/perfetto/+/1907874
Change-Id: If12c6563faefa9cd3c1642ee84118791d17d3f27
diff --git a/src/trace_processor/forwarding_trace_parser.cc b/src/trace_processor/forwarding_trace_parser.cc
index b983d7b..619a9e6 100644
--- a/src/trace_processor/forwarding_trace_parser.cc
+++ b/src/trace_processor/forwarding_trace_parser.cc
@@ -158,7 +158,7 @@
if (size == 0)
return kUnknownTraceType;
std::string start(reinterpret_cast<const char*>(data),
- std::min<size_t>(size, 32));
+ std::min<size_t>(size, kGuessTraceMaxLookahead));
if (size >= 8) {
uint64_t first_word;
memcpy(&first_word, data, sizeof(first_word));
@@ -180,10 +180,16 @@
base::StartsWith(start, "<html>"))
return kSystraceTraceType;
- // Ctrace is deflate'ed systrace.
- if (base::Contains(start, "TRACE:"))
+ // Traces obtained from atrace -z (compress).
+ // They all have the string "TRACE:" followed by 78 9C which is a zlib header
+ // for "deflate, default compression, window size=32K" (see b/208691037)
+ if (base::Contains(start, "TRACE:\n\x78\x9c"))
return kCtraceTraceType;
+ // Traces obtained from atrace without -z (no compression).
+ if (base::Contains(start, "TRACE:\n"))
+ return kSystraceTraceType;
+
// Ninja's buils log (.ninja_log).
if (base::StartsWith(start, "# ninja log"))
return kNinjaLogTraceType;
diff --git a/src/trace_processor/forwarding_trace_parser.h b/src/trace_processor/forwarding_trace_parser.h
index a5164cf..566b3b8 100644
--- a/src/trace_processor/forwarding_trace_parser.h
+++ b/src/trace_processor/forwarding_trace_parser.h
@@ -24,6 +24,8 @@
namespace perfetto {
namespace trace_processor {
+constexpr size_t kGuessTraceMaxLookahead = 64;
+
enum TraceType {
kUnknownTraceType,
kProtoTraceType,
diff --git a/src/trace_processor/importers/systrace/systrace_trace_parser.cc b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
index 445dda1..0fe8781 100644
--- a/src/trace_processor/importers/systrace/systrace_trace_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_trace_parser.cc
@@ -19,6 +19,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/string_splitter.h"
#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/forwarding_trace_parser.h"
#include "src/trace_processor/importers/common/process_tracker.h"
#include "src/trace_processor/trace_sorter.h"
@@ -71,6 +72,18 @@
blob.data() + blob.size());
if (state_ == ParseState::kBeforeParse) {
+ // Remove anything before the TRACE:\n marker, which is emitted when
+ // obtaining traces via `adb shell "atrace -t 1 sched" > out.txt`.
+ std::array<uint8_t, 7> kAtraceMarker = {'T', 'R', 'A', 'C', 'E', ':', '\n'};
+ auto search_end = partial_buf_.begin() +
+ static_cast<int>(std::min(partial_buf_.size(),
+ kGuessTraceMaxLookahead));
+ auto it = std::search(partial_buf_.begin(), search_end,
+ kAtraceMarker.begin(), kAtraceMarker.end());
+ if (it != search_end)
+ partial_buf_.erase(partial_buf_.begin(), it + kAtraceMarker.size());
+
+ // Deal with HTML traces.
state_ = partial_buf_[0] == '<' ? ParseState::kHtmlBeforeSystrace
: ParseState::kSystrace;
}
diff --git a/test/data/atrace_compressed.ctrace.sha256 b/test/data/atrace_compressed.ctrace.sha256
new file mode 100644
index 0000000..d39c5ea
--- /dev/null
+++ b/test/data/atrace_compressed.ctrace.sha256
@@ -0,0 +1 @@
+db92be3d78ab0619af5068240b88bad78a655f3e403c5f7c7876956eb5b260b0
\ No newline at end of file
diff --git a/test/data/atrace_uncompressed_b_208691037.sha256 b/test/data/atrace_uncompressed_b_208691037.sha256
new file mode 100644
index 0000000..7348172
--- /dev/null
+++ b/test/data/atrace_uncompressed_b_208691037.sha256
@@ -0,0 +1 @@
+9872b827df72895a98af2977c117ad3bc31f8c62be79d211bdf254170db4e1de
\ No newline at end of file
diff --git a/test/trace_processor/parsing/atrace_compressed_sched_count.out b/test/trace_processor/parsing/atrace_compressed_sched_count.out
new file mode 100644
index 0000000..c03bd11
--- /dev/null
+++ b/test/trace_processor/parsing/atrace_compressed_sched_count.out
@@ -0,0 +1,2 @@
+"COUNT(1)"
+1120
diff --git a/test/trace_processor/parsing/atrace_uncompressed_sched_count.out b/test/trace_processor/parsing/atrace_uncompressed_sched_count.out
new file mode 100644
index 0000000..41c340b
--- /dev/null
+++ b/test/trace_processor/parsing/atrace_uncompressed_sched_count.out
@@ -0,0 +1,2 @@
+"COUNT(1)"
+9
diff --git a/test/trace_processor/parsing/index b/test/trace_processor/parsing/index
index b586e28..ce6f074 100644
--- a/test/trace_processor/parsing/index
+++ b/test/trace_processor/parsing/index
@@ -163,3 +163,10 @@
# Multiuser
android_multiuser_switch.textproto android_multiuser android_multiuser_switch.out
+
+# Output of atrace -z.
+../../data/atrace_compressed.ctrace sched_smoke.sql atrace_compressed_sched_count.out
+
+# Output of adb shell "atrace -t 1 sched" > out.txt". It has extra garbage
+# coming from stderr before the TRACE: marker. See b/208691037.
+../../data/atrace_uncompressed_b_208691037 sched_smoke.sql atrace_uncompressed_sched_count.out