blob: 3eb9e9d75bb65b9a932226ceb99952195cb4696d [file] [log] [blame]
Lalit Maganti93b76362018-06-01 03:03:58 +01001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Primiano Tucci0d72a312018-08-07 14:42:45 +010017#include "src/trace_processor/proto_trace_parser.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010018
Primiano Tucci132a34d2018-09-19 19:34:01 +010019#include <string.h>
20
Lalit Magantidf3e9262018-06-04 17:45:00 +010021#include <string>
22
Primiano Tuccid933d912018-09-04 09:15:07 +010023#include "perfetto/base/logging.h"
Primiano Tucci2da5d2e2018-08-10 14:23:31 +010024#include "perfetto/base/string_view.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010025#include "perfetto/base/utils.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010026#include "perfetto/protozero/proto_decoder.h"
Isabelle Taylor54ce7052018-10-01 14:00:15 +010027#include "perfetto/traced/sys_stats_counters.h"
Primiano Tuccia270f012019-01-07 20:01:00 +000028#include "src/trace_processor/clock_tracker.h"
Isabelle Taylora97c5f52018-10-23 17:36:12 +010029#include "src/trace_processor/event_tracker.h"
Lalit Maganti1d915a62019-01-07 12:10:42 +000030#include "src/trace_processor/ftrace_descriptors.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010031#include "src/trace_processor/process_tracker.h"
Hector Dearman947f12a2018-09-11 16:50:36 +010032#include "src/trace_processor/slice_tracker.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010033#include "src/trace_processor/trace_processor_context.h"
34
Lalit Magantidf3e9262018-06-04 17:45:00 +010035#include "perfetto/trace/trace.pb.h"
36#include "perfetto/trace/trace_packet.pb.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010037
38namespace perfetto {
39namespace trace_processor {
40
Lalit Maganti1d915a62019-01-07 12:10:42 +000041namespace {
42
43using protozero::ProtoDecoder;
44using Variadic = TraceStorage::Args::Variadic;
45
46} // namespace
47
Hector Dearman947f12a2018-09-11 16:50:36 +010048// We have to handle trace_marker events of a few different types:
49// 1. some random text
50// 2. B|1636|pokeUserActivity
51// 3. E|1636
52// 4. C|1636|wq:monitor|0
53bool ParseSystraceTracePoint(base::StringView str, SystraceTracePoint* out) {
54 // THIS char* IS NOT NULL TERMINATED.
55 const char* s = str.data();
56 size_t len = str.size();
57
Hector Dearman9e6ddd82018-09-21 10:17:02 +010058 // If str matches '[BEC]\|[0-9]+[\|\n]' set tid_length to the length of
Hector Dearman947f12a2018-09-11 16:50:36 +010059 // the number. Otherwise return false.
Lalit Magantide6267f2018-11-08 12:35:34 +000060 if (s[1] != '|' && s[1] != '\n')
Hector Dearman947f12a2018-09-11 16:50:36 +010061 return false;
62 if (s[0] != 'B' && s[0] != 'E' && s[0] != 'C')
63 return false;
Lalit Magantide6267f2018-11-08 12:35:34 +000064 size_t tid_length = 0;
65 for (size_t i = 2; i < len; i++) {
Hector Dearman947f12a2018-09-11 16:50:36 +010066 if (s[i] == '|' || s[i] == '\n') {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010067 tid_length = i - 2;
Hector Dearman947f12a2018-09-11 16:50:36 +010068 break;
69 }
70 if (s[i] < '0' || s[i] > '9')
71 return false;
72 }
73
Lalit Magantide6267f2018-11-08 12:35:34 +000074 if (tid_length == 0) {
75 out->tid = 0;
76 } else {
77 std::string tid_str(s + 2, tid_length);
78 out->tid = static_cast<uint32_t>(std::stoi(tid_str.c_str()));
79 }
Hector Dearman947f12a2018-09-11 16:50:36 +010080
81 out->phase = s[0];
82 switch (s[0]) {
83 case 'B': {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010084 size_t name_index = 2 + tid_length + 1;
Ioannis Ilkos843e4c42019-01-23 17:32:55 +000085 out->name = base::StringView(
86 s + name_index, len - name_index - (s[len - 1] == '\n' ? 1 : 0));
Hector Dearman947f12a2018-09-11 16:50:36 +010087 return true;
88 }
Isabelle Taylor31e04402018-09-19 12:13:25 +010089 case 'E': {
Hector Dearman947f12a2018-09-11 16:50:36 +010090 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +010091 }
92 case 'C': {
Hector Dearman9e6ddd82018-09-21 10:17:02 +010093 size_t name_index = 2 + tid_length + 1;
Isabelle Taylor31e04402018-09-19 12:13:25 +010094 size_t name_length = 0;
95 for (size_t i = name_index; i < len; i++) {
96 if (s[i] == '|' || s[i] == '\n') {
97 name_length = i - name_index;
98 break;
99 }
100 }
101 out->name = base::StringView(s + name_index, name_length);
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000102
Isabelle Taylor31e04402018-09-19 12:13:25 +0100103 size_t value_index = name_index + name_length + 1;
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000104 size_t value_len = len - value_index;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100105 char value_str[32];
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000106 if (value_len >= sizeof(value_str)) {
107 return false;
108 }
109 memcpy(value_str, s + value_index, value_len);
110 value_str[value_len] = 0;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100111 out->value = std::stod(value_str);
Hector Dearman947f12a2018-09-11 16:50:36 +0100112 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100113 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100114 default:
115 return false;
116 }
117}
118
Primiano Tucci7e330292018-08-24 19:10:52 +0200119ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100120 : context_(context),
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000121 utid_name_id_(context->storage->InternString("utid")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100122 cpu_freq_name_id_(context->storage->InternString("cpufreq")),
Hector Dearman7b794cc2018-11-30 14:35:30 +0000123 cpu_idle_name_id_(context->storage->InternString("cpuidle")),
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000124 comm_name_id_(context->storage->InternString("comm")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100125 num_forks_name_id_(context->storage->InternString("num_forks")),
126 num_irq_total_name_id_(context->storage->InternString("num_irq_total")),
127 num_softirq_total_name_id_(
128 context->storage->InternString("num_softirq_total")),
129 num_irq_name_id_(context->storage->InternString("num_irq")),
130 num_softirq_name_id_(context->storage->InternString("num_softirq")),
131 cpu_times_user_ns_id_(
132 context->storage->InternString("cpu.times.user_ns")),
133 cpu_times_user_ice_ns_id_(
134 context->storage->InternString("cpu.times.user_ice_ns")),
135 cpu_times_system_mode_ns_id_(
136 context->storage->InternString("cpu.times.system_mode_ns")),
137 cpu_times_idle_ns_id_(
138 context->storage->InternString("cpu.times.idle_ns")),
139 cpu_times_io_wait_ns_id_(
140 context->storage->InternString("cpu.times.io_wait_ns")),
141 cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
142 cpu_times_softirq_ns_id_(
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100143 context->storage->InternString("cpu.times.softirq_ns")),
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000144 signal_deliver_id_(context->storage->InternString("signal_deliver")),
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100145 signal_generate_id_(context->storage->InternString("signal_generate")),
146 batt_charge_id_(context->storage->InternString("batt.charge_uah")),
147 batt_capacity_id_(context->storage->InternString("batt.capacity_pct")),
148 batt_current_id_(context->storage->InternString("batt.current_ua")),
149 batt_current_avg_id_(
Primiano Tucci44231042018-12-06 21:34:32 +0000150 context->storage->InternString("batt.current.avg_ua")),
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000151 lmk_id_(context->storage->InternString("mem.lmk")),
Primiano Tucci90cdc852018-12-21 10:29:44 +0100152 oom_score_adj_id_(context->storage->InternString("oom_score_adj")),
153 ion_total_unknown_id_(context->storage->InternString("mem.ion.unknown")),
154 ion_change_unknown_id_(
155 context->storage->InternString("mem.ion_change.unknown")) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100156 for (const auto& name : BuildMeminfoCounterNames()) {
157 meminfo_strs_id_.emplace_back(context->storage->InternString(name));
158 }
159 for (const auto& name : BuildVmstatCounterNames()) {
160 vmstat_strs_id_.emplace_back(context->storage->InternString(name));
161 }
Lalit Maganti6820abc2019-01-21 11:12:23 +0000162 rss_members_.emplace_back(context->storage->InternString("mem.rss.file"));
163 rss_members_.emplace_back(context->storage->InternString("mem.rss.anon"));
Lalit Maganti5a95df22019-01-24 13:28:36 +0000164 rss_members_.emplace_back(context->storage->InternString("mem.swap"));
Lalit Maganti6820abc2019-01-21 11:12:23 +0000165 rss_members_.emplace_back(context->storage->InternString("mem.rss.shmem"));
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100166 rss_members_.emplace_back(
Lalit Maganti6820abc2019-01-21 11:12:23 +0000167 context->storage->InternString("mem.rss.unknown")); // Keep this last.
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700168
Lalit Maganti6820abc2019-01-21 11:12:23 +0000169 using ProcessStats = protos::ProcessStats;
Lalit Maganti41c98922019-01-23 19:35:58 +0000170 proc_stats_process_names_[ProcessStats::Process::kVmSizeKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700171 context->storage->InternString("mem.virt");
Lalit Maganti41c98922019-01-23 19:35:58 +0000172 proc_stats_process_names_[ProcessStats::Process::kVmRssKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700173 context->storage->InternString("mem.rss");
Lalit Maganti41c98922019-01-23 19:35:58 +0000174 proc_stats_process_names_[ProcessStats::Process::kRssAnonKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700175 context->storage->InternString("mem.rss.anon");
Lalit Maganti41c98922019-01-23 19:35:58 +0000176 proc_stats_process_names_[ProcessStats::Process::kRssFileKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700177 context->storage->InternString("mem.rss.file");
Lalit Maganti41c98922019-01-23 19:35:58 +0000178 proc_stats_process_names_[ProcessStats::Process::kRssShmemKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700179 context->storage->InternString("mem.rss.shmem");
Lalit Maganti41c98922019-01-23 19:35:58 +0000180 proc_stats_process_names_[ProcessStats::Process::kVmSwapKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700181 context->storage->InternString("mem.swap");
Lalit Maganti41c98922019-01-23 19:35:58 +0000182 proc_stats_process_names_[ProcessStats::Process::kVmLockedKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700183 context->storage->InternString("mem.locked");
Lalit Maganti41c98922019-01-23 19:35:58 +0000184 proc_stats_process_names_[ProcessStats::Process::kVmHwmKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700185 context->storage->InternString("mem.rss.watermark");
Lalit Maganti41c98922019-01-23 19:35:58 +0000186 proc_stats_process_names_[ProcessStats::Process::kOomScoreAdjFieldNumber] =
187 oom_score_adj_id_;
Lalit Magantia824c332019-01-23 17:55:58 +0000188
189 mm_event_counter_names_[0] = MmEventCounterNames(
190 context->storage->InternString("mem.mm.min_flt.count"),
191 context->storage->InternString("mem.mm.min_flt.max_lat"),
192 context->storage->InternString("mem.mm.min_flt.avg_lat"));
193 mm_event_counter_names_[1] = MmEventCounterNames(
194 context->storage->InternString("mem.mm.maj_flt.count"),
195 context->storage->InternString("mem.mm.maj_flt.max_lat"),
196 context->storage->InternString("mem.mm.maj_flt.avg_lat"));
197 mm_event_counter_names_[2] = MmEventCounterNames(
198 context->storage->InternString("mem.mm.read_io.count"),
199 context->storage->InternString("mem.mm.read_io.max_lat"),
200 context->storage->InternString("mem.mm.read_io.avg_lat"));
201 mm_event_counter_names_[3] = MmEventCounterNames(
202 context->storage->InternString("mem.mm.compaction.count"),
203 context->storage->InternString("mem.mm.compaction.max_lat"),
204 context->storage->InternString("mem.mm.compaction.avg_lat"));
205 mm_event_counter_names_[4] = MmEventCounterNames(
206 context->storage->InternString("mem.mm.reclaim.count"),
207 context->storage->InternString("mem.mm.reclaim.max_lat"),
208 context->storage->InternString("mem.mm.reclaim.avg_lat"));
209 mm_event_counter_names_[5] = MmEventCounterNames(
210 context->storage->InternString("mem.mm.swp_flt.count"),
211 context->storage->InternString("mem.mm.swp_flt.max_lat"),
212 context->storage->InternString("mem.mm.swp_flt.avg_lat"));
213 mm_event_counter_names_[6] = MmEventCounterNames(
214 context->storage->InternString("mem.mm.kern_alloc.count"),
215 context->storage->InternString("mem.mm.kern_alloc.max_lat"),
216 context->storage->InternString("mem.mm.kern_alloc.avg_lat"));
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100217}
Lalit Maganti93b76362018-06-01 03:03:58 +0100218
Primiano Tucci0d72a312018-08-07 14:42:45 +0100219ProtoTraceParser::~ProtoTraceParser() = default;
220
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000221void ProtoTraceParser::ParseTracePacket(int64_t ts, TraceBlobView packet) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100222 ProtoDecoder decoder(packet.data(), packet.length());
Lalit Maganti93b76362018-06-01 03:03:58 +0100223
Lalit Magantidf3e9262018-06-04 17:45:00 +0100224 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
225 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100226 case protos::TracePacket::kProcessTreeFieldNumber: {
227 const size_t fld_off = packet.offset_of(fld.data());
228 ParseProcessTree(packet.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100229 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100230 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700231 case protos::TracePacket::kProcessStatsFieldNumber: {
232 const size_t fld_off = packet.offset_of(fld.data());
233 ParseProcessStats(ts, packet.slice(fld_off, fld.size()));
234 break;
235 }
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100236 case protos::TracePacket::kSysStatsFieldNumber: {
237 const size_t fld_off = packet.offset_of(fld.data());
238 ParseSysStats(ts, packet.slice(fld_off, fld.size()));
239 break;
240 }
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100241 case protos::TracePacket::kBatteryFieldNumber: {
242 const size_t fld_off = packet.offset_of(fld.data());
243 ParseBatteryCounters(ts, packet.slice(fld_off, fld.size()));
244 break;
245 }
Primiano Tucci0e38a142019-01-07 20:51:09 +0000246 case protos::TracePacket::kTraceStatsFieldNumber: {
247 const size_t fld_off = packet.offset_of(fld.data());
248 ParseTraceStats(packet.slice(fld_off, fld.size()));
249 break;
250 }
251 case protos::TracePacket::kFtraceStatsFieldNumber: {
252 const size_t fld_off = packet.offset_of(fld.data());
253 ParseFtraceStats(packet.slice(fld_off, fld.size()));
254 break;
255 }
Primiano Tuccia270f012019-01-07 20:01:00 +0000256 case protos::TracePacket::kClockSnapshotFieldNumber: {
257 const size_t fld_off = packet.offset_of(fld.data());
258 ParseClockSnapshot(packet.slice(fld_off, fld.size()));
259 break;
260 }
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000261 case protos::TracePacket::kAndroidLogFieldNumber: {
262 const size_t fld_off = packet.offset_of(fld.data());
263 ParseAndroidLogPacket(packet.slice(fld_off, fld.size()));
264 break;
265 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100266 default:
267 break;
268 }
269 }
270 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
271}
272
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000273void ProtoTraceParser::ParseSysStats(int64_t ts, TraceBlobView stats) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100274 ProtoDecoder decoder(stats.data(), stats.length());
275 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
276 switch (fld.id) {
277 case protos::SysStats::kMeminfoFieldNumber: {
278 const size_t fld_off = stats.offset_of(fld.data());
279 ParseMemInfo(ts, stats.slice(fld_off, fld.size()));
280 break;
281 }
282 case protos::SysStats::kVmstatFieldNumber: {
283 const size_t fld_off = stats.offset_of(fld.data());
284 ParseVmStat(ts, stats.slice(fld_off, fld.size()));
285 break;
286 }
287 case protos::SysStats::kCpuStatFieldNumber: {
288 const size_t fld_off = stats.offset_of(fld.data());
289 ParseCpuTimes(ts, stats.slice(fld_off, fld.size()));
290 break;
291 }
292 case protos::SysStats::kNumIrqFieldNumber: {
293 const size_t fld_off = stats.offset_of(fld.data());
294 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
295 /*is_softirq=*/false);
296 break;
297 }
298 case protos::SysStats::kNumSoftirqFieldNumber: {
299 const size_t fld_off = stats.offset_of(fld.data());
300 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
301 /*is_softirq=*/true);
302 break;
303 }
304 case protos::SysStats::kNumForksFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100305 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000306 ts, fld.as_uint32(), num_forks_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100307 break;
308 }
309 case protos::SysStats::kNumIrqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100310 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000311 ts, fld.as_uint32(), num_irq_total_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100312 break;
313 }
314 case protos::SysStats::kNumSoftirqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100315 context_->event_tracker->PushCounter(ts, fld.as_uint32(),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100316 num_softirq_total_name_id_, 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000317 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100318 break;
319 }
320 default:
321 break;
322 }
323 }
324}
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000325void ProtoTraceParser::ParseIrqCount(int64_t ts,
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100326 TraceBlobView irq,
327 bool is_soft) {
328 ProtoDecoder decoder(irq.data(), irq.length());
329 uint32_t key = 0;
330 uint32_t value = 0;
331 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
332 switch (fld.id) {
333 case protos::SysStats::InterruptCount::kIrqFieldNumber:
334 key = fld.as_uint32();
335 break;
336 case protos::SysStats::InterruptCount::kCountFieldNumber:
337 value = fld.as_uint32();
338 break;
339 }
340 }
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000341 RefType ref_type = is_soft ? RefType::kRefIrq : RefType::kRefSoftIrq;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100342 StringId name_id = is_soft ? num_irq_name_id_ : num_softirq_name_id_;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100343 context_->event_tracker->PushCounter(ts, value, name_id, key, ref_type);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100344}
345
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000346void ProtoTraceParser::ParseMemInfo(int64_t ts, TraceBlobView mem) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100347 ProtoDecoder decoder(mem.data(), mem.length());
348 uint32_t key = 0;
349 uint32_t value = 0;
350 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
351 switch (fld.id) {
352 case protos::SysStats::MeminfoValue::kKeyFieldNumber:
353 key = fld.as_uint32();
354 break;
355 case protos::SysStats::MeminfoValue::kValueFieldNumber:
356 value = fld.as_uint32();
357 break;
358 }
359 }
360 if (PERFETTO_UNLIKELY(key >= meminfo_strs_id_.size())) {
361 PERFETTO_ELOG("MemInfo key %d is not recognized.", key);
Primiano Tucci0e38a142019-01-07 20:51:09 +0000362 context_->storage->IncrementStats(stats::meminfo_unknown_keys);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100363 return;
364 }
Ioannis Ilkos5ef15b42019-01-08 10:57:52 +0000365 // /proc/meminfo counters are in kB, convert to bytes
366 context_->event_tracker->PushCounter(ts, value * 1024L, meminfo_strs_id_[key],
367 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100368}
369
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000370void ProtoTraceParser::ParseVmStat(int64_t ts, TraceBlobView stat) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100371 ProtoDecoder decoder(stat.data(), stat.length());
372 uint32_t key = 0;
373 uint32_t value = 0;
374 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
375 switch (fld.id) {
376 case protos::SysStats::VmstatValue::kKeyFieldNumber:
377 key = fld.as_uint32();
378 break;
379 case protos::SysStats::VmstatValue::kValueFieldNumber:
380 value = fld.as_uint32();
381 break;
382 }
383 }
384 if (PERFETTO_UNLIKELY(key >= vmstat_strs_id_.size())) {
385 PERFETTO_ELOG("VmStat key %d is not recognized.", key);
Primiano Tucci0e38a142019-01-07 20:51:09 +0000386 context_->storage->IncrementStats(stats::vmstat_unknown_keys);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100387 return;
388 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100389 context_->event_tracker->PushCounter(ts, value, vmstat_strs_id_[key], 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000390 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100391}
392
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000393void ProtoTraceParser::ParseCpuTimes(int64_t ts, TraceBlobView cpu_times) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100394 ProtoDecoder decoder(cpu_times.data(), cpu_times.length());
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000395 uint64_t raw_cpu = 0;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100396 uint32_t value = 0;
397 // Speculate on CPU being first.
398 constexpr auto kCpuFieldTag = protozero::proto_utils::MakeTagVarInt(
399 protos::SysStats::CpuTimes::kCpuIdFieldNumber);
400 if (cpu_times.length() > 2 && cpu_times.data()[0] == kCpuFieldTag &&
401 cpu_times.data()[1] < 0x80) {
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000402 raw_cpu = cpu_times.data()[1];
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100403 } else {
404 if (!PERFETTO_LIKELY((
405 decoder.FindIntField<protos::SysStats::CpuTimes::kCpuIdFieldNumber>(
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000406 &raw_cpu)))) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100407 PERFETTO_ELOG("CPU field not found in CpuTimes");
Primiano Tucci0e38a142019-01-07 20:51:09 +0000408 context_->storage->IncrementStats(stats::invalid_cpu_times);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100409 return;
410 }
411 }
412
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000413 int64_t cpu = static_cast<int64_t>(raw_cpu);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100414 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
415 switch (fld.id) {
416 case protos::SysStats::CpuTimes::kUserNsFieldNumber: {
417 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100418 context_->event_tracker->PushCounter(ts, value, cpu_times_user_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000419 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100420 break;
421 }
422 case protos::SysStats::CpuTimes::kUserIceNsFieldNumber: {
423 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100424 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000425 ts, value, cpu_times_user_ice_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100426 break;
427 }
428 case protos::SysStats::CpuTimes::kSystemModeNsFieldNumber: {
429 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100430 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000431 ts, value, cpu_times_system_mode_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100432 break;
433 }
434 case protos::SysStats::CpuTimes::kIdleNsFieldNumber: {
435 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100436 context_->event_tracker->PushCounter(ts, value, cpu_times_idle_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000437 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100438 break;
439 }
440 case protos::SysStats::CpuTimes::kIoWaitNsFieldNumber: {
441 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100442 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000443 ts, value, cpu_times_io_wait_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100444 break;
445 }
446 case protos::SysStats::CpuTimes::kIrqNsFieldNumber: {
447 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100448 context_->event_tracker->PushCounter(ts, value, cpu_times_irq_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000449 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100450 break;
451 }
452 case protos::SysStats::CpuTimes::kSoftirqNsFieldNumber: {
453 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100454 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000455 ts, value, cpu_times_softirq_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100456 break;
457 }
458 default:
459 break;
460 }
461 }
462}
463
Primiano Tuccid933d912018-09-04 09:15:07 +0100464void ProtoTraceParser::ParseProcessTree(TraceBlobView pstree) {
465 ProtoDecoder decoder(pstree.data(), pstree.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100466
Isabelle Taylord80932a2018-06-19 17:00:47 +0100467 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100468 const size_t fld_off = pstree.offset_of(fld.data());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100469 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100470 case protos::ProcessTree::kProcessesFieldNumber: {
471 ParseProcess(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100472 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100473 }
474 case protos::ProcessTree::kThreadsFieldNumber: {
475 ParseThread(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100476 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100477 }
Isabelle Taylord80932a2018-06-19 17:00:47 +0100478 default:
479 break;
480 }
481 }
482 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
483}
484
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000485void ProtoTraceParser::ParseProcessStats(int64_t ts, TraceBlobView stats) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700486 ProtoDecoder decoder(stats.data(), stats.length());
487
488 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
489 const size_t fld_off = stats.offset_of(fld.data());
490 switch (fld.id) {
Lalit Maganti6820abc2019-01-21 11:12:23 +0000491 case protos::ProcessStats::kProcessesFieldNumber: {
Lalit Maganti41c98922019-01-23 19:35:58 +0000492 ParseProcessStatsProcess(ts, stats.slice(fld_off, fld.size()));
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700493 break;
494 }
495 default:
496 break;
497 }
498 }
499 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
500}
501
Lalit Maganti41c98922019-01-23 19:35:58 +0000502void ProtoTraceParser::ParseProcessStatsProcess(int64_t ts,
503 TraceBlobView proc_stat) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700504 ProtoDecoder decoder(proc_stat.data(), proc_stat.length());
505 uint32_t pid = 0;
Lalit Maganti41c98922019-01-23 19:35:58 +0000506
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700507 // Maps a process counter field it to its value.
508 // E.g., 4 := 1024 -> "mem.rss.anon" := 1024.
Lalit Maganti41c98922019-01-23 19:35:58 +0000509 std::array<int64_t, kProcStatsProcessSize> counter_values{};
510 std::array<bool, kProcStatsProcessSize> has_counter{};
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700511
512 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
513 switch (fld.id) {
Lalit Maganti6820abc2019-01-21 11:12:23 +0000514 case protos::ProcessStats::Process::kPidFieldNumber:
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700515 pid = fld.as_uint32();
516 break;
Lalit Maganti41c98922019-01-23 19:35:58 +0000517 default: {
518 bool is_counter_field = fld.id < has_counter.size() &&
519 proc_stats_process_names_[fld.id] != 0;
520 if (is_counter_field) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700521 // Memory counters are in KB, keep values in bytes in the trace
522 // processor.
Lalit Maganti41c98922019-01-23 19:35:58 +0000523 counter_values[fld.id] =
524 fld.id == protos::ProcessStats::Process::kOomScoreAdjFieldNumber
525 ? fld.as_int64()
526 : fld.as_int64() * 1024;
527 has_counter[fld.id] = true;
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700528 } else {
Primiano Tucci0e38a142019-01-07 20:51:09 +0000529 context_->storage->IncrementStats(stats::proc_stat_unknown_counters);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700530 }
Lalit Maganti41c98922019-01-23 19:35:58 +0000531 break;
532 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700533 }
534 }
535
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700536 // Skip field_id 0 (invalid) and 1 (pid).
537 for (size_t field_id = 2; field_id < counter_values.size(); field_id++) {
538 if (!has_counter[field_id])
539 continue;
540
541 // Lookup the interned string id from the field name using the
Lalit Maganti41c98922019-01-23 19:35:58 +0000542 // pre-cached |proc_stats_process_names_| map.
543 StringId name = proc_stats_process_names_[field_id];
544 int64_t value = counter_values[field_id];
545
546 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
547 context_->event_tracker->PushCounter(ts, value, name, upid,
548 RefType::kRefUpid);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700549 }
550
551 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
552}
553
Primiano Tuccid933d912018-09-04 09:15:07 +0100554void ProtoTraceParser::ParseThread(TraceBlobView thread) {
555 ProtoDecoder decoder(thread.data(), thread.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100556 uint32_t tid = 0;
557 uint32_t tgid = 0;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100558 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
559 switch (fld.id) {
560 case protos::ProcessTree::Thread::kTidFieldNumber:
561 tid = fld.as_uint32();
562 break;
563 case protos::ProcessTree::Thread::kTgidFieldNumber:
564 tgid = fld.as_uint32();
565 break;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100566 default:
567 break;
568 }
569 }
Isabelle Taylora0a22972018-08-03 12:06:12 +0100570 context_->process_tracker->UpdateThread(tid, tgid);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100571
572 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
573}
574
Primiano Tuccid933d912018-09-04 09:15:07 +0100575void ProtoTraceParser::ParseProcess(TraceBlobView process) {
576 ProtoDecoder decoder(process.data(), process.length());
577
Isabelle Taylord80932a2018-06-19 17:00:47 +0100578 uint32_t pid = 0;
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100579 base::StringView process_name;
Primiano Tuccid933d912018-09-04 09:15:07 +0100580
Isabelle Taylord80932a2018-06-19 17:00:47 +0100581 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
582 switch (fld.id) {
583 case protos::ProcessTree::Process::kPidFieldNumber:
584 pid = fld.as_uint32();
585 break;
586 case protos::ProcessTree::Process::kCmdlineFieldNumber:
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100587 if (process_name.empty())
588 process_name = fld.as_string();
Isabelle Taylord80932a2018-06-19 17:00:47 +0100589 break;
590 default:
591 break;
592 }
593 }
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100594 context_->process_tracker->UpdateProcess(pid, process_name);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100595 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
596}
597
Primiano Tuccid933d912018-09-04 09:15:07 +0100598void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000599 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100600 TraceBlobView ftrace) {
601 ProtoDecoder decoder(ftrace.data(), ftrace.length());
Lalit Maganti1d915a62019-01-07 12:10:42 +0000602 uint64_t raw_pid = 0;
603 if (!PERFETTO_LIKELY(
604 (decoder.FindIntField<protos::FtraceEvent::kPidFieldNumber>(
605 &raw_pid)))) {
606 PERFETTO_ELOG("Pid field not found in ftrace packet");
607 return;
608 }
609 uint32_t pid = static_cast<uint32_t>(raw_pid);
610
Lalit Magantidf3e9262018-06-04 17:45:00 +0100611 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
Lalit Maganti1d915a62019-01-07 12:10:42 +0000612 bool is_metadata_field =
613 fld.id == protos::FtraceEvent::kPidFieldNumber ||
614 fld.id == protos::FtraceEvent::kTimestampFieldNumber;
615 if (is_metadata_field)
616 continue;
617
618 const size_t fld_off = ftrace.offset_of(fld.data());
Lalit Maganticc674222019-01-23 17:54:00 +0000619 // TODO(b/123252504): don't parse raw events for now.
620 /*
Lalit Maganti1d915a62019-01-07 12:10:42 +0000621 if (fld.id == protos::FtraceEvent::kGenericFieldNumber) {
Lalit Magantie87cc812019-01-10 15:20:06 +0000622 ParseGenericFtrace(timestamp, cpu, pid,
623 ftrace.slice(fld_off, fld.size()));
Lalit Maganti1d915a62019-01-07 12:10:42 +0000624 } else {
Lalit Magantie87cc812019-01-10 15:20:06 +0000625 ParseTypedFtraceToRaw(fld.id, timestamp, cpu, pid,
Lalit Maganti1d915a62019-01-07 12:10:42 +0000626 ftrace.slice(fld_off, fld.size()));
627 }
Lalit Maganticc674222019-01-23 17:54:00 +0000628 */
Lalit Maganti1d915a62019-01-07 12:10:42 +0000629
Lalit Magantidf3e9262018-06-04 17:45:00 +0100630 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100631 case protos::FtraceEvent::kSchedSwitchFieldNumber: {
Primiano Tuccid933d912018-09-04 09:15:07 +0100632 ParseSchedSwitch(cpu, timestamp, ftrace.slice(fld_off, fld.size()));
Lalit Magantidf3e9262018-06-04 17:45:00 +0100633 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100634 }
Isabelle Taylor14674d42018-09-07 11:33:11 +0100635 case protos::FtraceEvent::kCpuFrequency: {
Isabelle Taylor14674d42018-09-07 11:33:11 +0100636 ParseCpuFreq(timestamp, ftrace.slice(fld_off, fld.size()));
637 break;
638 }
Hector Dearman7b794cc2018-11-30 14:35:30 +0000639 case protos::FtraceEvent::kCpuIdle: {
Hector Dearman7b794cc2018-11-30 14:35:30 +0000640 ParseCpuIdle(timestamp, ftrace.slice(fld_off, fld.size()));
641 break;
642 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100643 case protos::FtraceEvent::kPrintFieldNumber: {
Lalit Magantide6267f2018-11-08 12:35:34 +0000644 ParsePrint(cpu, timestamp, pid, ftrace.slice(fld_off, fld.size()));
Hector Dearman947f12a2018-09-11 16:50:36 +0100645 break;
646 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100647 case protos::FtraceEvent::kRssStatFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100648 ParseRssStat(timestamp, pid, ftrace.slice(fld_off, fld.size()));
649 break;
650 }
651 case protos::FtraceEvent::kIonHeapGrow: {
Primiano Tucci90cdc852018-12-21 10:29:44 +0100652 ParseIonHeapGrowOrShrink(timestamp, pid,
653 ftrace.slice(fld_off, fld.size()), true);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100654 break;
655 }
656 case protos::FtraceEvent::kIonHeapShrink: {
Primiano Tucci90cdc852018-12-21 10:29:44 +0100657 ParseIonHeapGrowOrShrink(timestamp, pid,
658 ftrace.slice(fld_off, fld.size()), false);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100659 break;
660 }
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000661 case protos::FtraceEvent::kSignalGenerate: {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000662 ParseSignalGenerate(timestamp, ftrace.slice(fld_off, fld.size()));
663 break;
664 }
665 case protos::FtraceEvent::kSignalDeliver: {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000666 ParseSignalDeliver(timestamp, pid, ftrace.slice(fld_off, fld.size()));
667 break;
668 }
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000669 case protos::FtraceEvent::kLowmemoryKill: {
670 ParseLowmemoryKill(timestamp, ftrace.slice(fld_off, fld.size()));
671 break;
672 }
Primiano Tucci44231042018-12-06 21:34:32 +0000673 case protos::FtraceEvent::kOomScoreAdjUpdate: {
Primiano Tucci44231042018-12-06 21:34:32 +0000674 ParseOOMScoreAdjUpdate(timestamp, ftrace.slice(fld_off, fld.size()));
675 break;
676 }
Lalit Magantia824c332019-01-23 17:55:58 +0000677 case protos::FtraceEvent::kMmEventRecordFieldNumber: {
678 ParseMmEventRecordField(timestamp, pid,
679 ftrace.slice(fld_off, fld.size()));
680 break;
681 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100682 default:
683 break;
684 }
685 }
686 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
687}
688
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000689void ProtoTraceParser::ParseSignalDeliver(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000690 uint32_t pid,
691 TraceBlobView view) {
692 ProtoDecoder decoder(view.data(), view.length());
693 uint32_t sig = 0;
694 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
695 switch (fld.id) {
696 case protos::SignalDeliverFtraceEvent::kSigFieldNumber:
697 sig = fld.as_uint32();
698 break;
699 }
700 }
701 auto* instants = context_->storage->mutable_instants();
702 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
703 instants->AddInstantEvent(timestamp, signal_deliver_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000704 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000705}
706
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000707// This event has both the pid of the thread that sent the signal and the
708// destination of the signal. Currently storing the pid of the destination.
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000709void ProtoTraceParser::ParseSignalGenerate(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000710 TraceBlobView view) {
711 ProtoDecoder decoder(view.data(), view.length());
712 uint32_t pid = 0;
713 uint32_t sig = 0;
714 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
715 switch (fld.id) {
716 case protos::SignalGenerateFtraceEvent::kPidFieldNumber:
717 pid = fld.as_uint32();
718 break;
719 case protos::SignalGenerateFtraceEvent::kSigFieldNumber:
720 sig = fld.as_uint32();
721 break;
722 }
723 }
724 auto* instants = context_->storage->mutable_instants();
725 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
726 instants->AddInstantEvent(timestamp, signal_generate_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000727 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000728}
729
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000730void ProtoTraceParser::ParseLowmemoryKill(int64_t timestamp,
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000731 TraceBlobView view) {
732 // TODO(taylori): Store the pagecache_size, pagecache_limit and free fields
733 // in an args table
734 ProtoDecoder decoder(view.data(), view.length());
735 uint32_t pid = 0;
736 base::StringView comm;
737 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
738 switch (fld.id) {
739 case protos::LowmemoryKillFtraceEvent::kPidFieldNumber:
740 pid = fld.as_uint32();
741 break;
742 case protos::LowmemoryKillFtraceEvent::kCommFieldNumber:
743 comm = fld.as_string();
744 break;
745 }
746 }
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000747
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000748 // Storing the pid of the event that is lmk-ed.
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000749 auto* instants = context_->storage->mutable_instants();
Lalit Maganti94c522b2019-01-15 00:03:15 +0000750 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000751 uint32_t row =
Lalit Maganti94c522b2019-01-15 00:03:15 +0000752 instants->AddInstantEvent(timestamp, lmk_id_, 0, upid, RefType::kRefUpid);
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000753
754 // Store the comm as an arg.
755 RowId row_id = TraceStorage::CreateRowId(TableId::kInstants, row);
756 auto comm_id = context_->storage->InternString(comm);
757 context_->storage->mutable_args()->AddArg(
758 row_id, comm_name_id_, comm_name_id_, Variadic::String(comm_id));
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000759}
760
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000761void ProtoTraceParser::ParseRssStat(int64_t timestamp,
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100762 uint32_t pid,
763 TraceBlobView view) {
764 ProtoDecoder decoder(view.data(), view.length());
Primiano Tuccibc560992018-12-06 19:11:45 +0000765 const auto kRssStatUnknown = static_cast<uint32_t>(rss_members_.size()) - 1;
766 uint32_t member = kRssStatUnknown;
Primiano Tuccidbe49832018-12-18 19:37:04 +0000767 int64_t size = 0;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100768 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
769 switch (fld.id) {
770 case protos::RssStatFtraceEvent::kMemberFieldNumber:
771 member = fld.as_uint32();
772 break;
773 case protos::RssStatFtraceEvent::kSizeFieldNumber:
Primiano Tuccidbe49832018-12-18 19:37:04 +0000774 size = fld.as_int64();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100775 break;
776 }
777 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700778 if (member >= rss_members_.size()) {
Primiano Tucci0e38a142019-01-07 20:51:09 +0000779 context_->storage->IncrementStats(stats::rss_stat_unknown_keys);
Primiano Tuccibc560992018-12-06 19:11:45 +0000780 member = kRssStatUnknown;
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700781 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100782 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Lalit Maganti6d2edf62018-11-08 16:36:35 +0000783
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100784 context_->event_tracker->PushCounter(timestamp, size, rss_members_[member],
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000785 utid, RefType::kRefUtidLookupUpid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100786 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
787}
788
Primiano Tucci90cdc852018-12-21 10:29:44 +0100789void ProtoTraceParser::ParseIonHeapGrowOrShrink(int64_t timestamp,
790 uint32_t pid,
791 TraceBlobView view,
792 bool grow) {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100793 ProtoDecoder decoder(view.data(), view.length());
Primiano Tucci90cdc852018-12-21 10:29:44 +0100794 int64_t total_bytes = 0;
795 int64_t change_bytes = 0;
796 StringId global_name_id = ion_total_unknown_id_;
797 StringId change_name_id = ion_change_unknown_id_;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100798 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
799 switch (fld.id) {
800 case protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber:
Primiano Tucci90cdc852018-12-21 10:29:44 +0100801 total_bytes = fld.as_int64();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100802 break;
Primiano Tucci90cdc852018-12-21 10:29:44 +0100803 case protos::IonHeapGrowFtraceEvent::kLenFieldNumber:
804 change_bytes = fld.as_int64() * (grow ? 1 : -1);
805 break;
806 case protos::IonHeapGrowFtraceEvent::kHeapNameFieldNumber: {
807 char counter_name[255];
808 base::StringView heap_name = fld.as_string();
809 snprintf(counter_name, sizeof(counter_name), "mem.ion.%.*s",
810 int(heap_name.size()), heap_name.data());
811 global_name_id = context_->storage->InternString(counter_name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100812
Primiano Tucci90cdc852018-12-21 10:29:44 +0100813 snprintf(counter_name, sizeof(counter_name), "mem.ion_change.%.*s",
814 int(heap_name.size()), heap_name.data());
815 change_name_id = context_->storage->InternString(counter_name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100816 break;
Primiano Tucci90cdc852018-12-21 10:29:44 +0100817 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100818 }
819 }
Primiano Tucci90cdc852018-12-21 10:29:44 +0100820 // Push the global counter.
821 context_->event_tracker->PushCounter(timestamp, total_bytes, global_name_id,
822 0, RefType::kRefNoRef);
823
824 // Push the change counter.
825 // TODO(b/121331269): these should really be instant events. For now we
Primiano Tuccicd37b4d2018-12-21 16:33:32 +0100826 // manually reset them to 0 after 1ns.
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100827 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Primiano Tucci90cdc852018-12-21 10:29:44 +0100828 context_->event_tracker->PushCounter(timestamp, change_bytes, change_name_id,
829 utid, RefType::kRefUtid);
Primiano Tuccicd37b4d2018-12-21 16:33:32 +0100830 context_->event_tracker->PushCounter(timestamp + 1, 0, change_name_id, utid,
831 RefType::kRefUtid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100832 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
Primiano Tucci90cdc852018-12-21 10:29:44 +0100833
834 // We are reusing the same function for ion_heap_grow and ion_heap_shrink.
835 // It is fine as the arguments are the same, but we need to be sure that the
836 // protobuf field id for both are the same.
837 static_assert(
838 protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber ==
839 protos::IonHeapShrinkFtraceEvent::kTotalAllocatedFieldNumber &&
840 protos::IonHeapGrowFtraceEvent::kLenFieldNumber ==
841 protos::IonHeapShrinkFtraceEvent::kLenFieldNumber &&
842 protos::IonHeapGrowFtraceEvent::kHeapNameFieldNumber ==
843 protos::IonHeapShrinkFtraceEvent::kHeapNameFieldNumber,
844 "field mismatch");
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100845}
846
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000847void ProtoTraceParser::ParseCpuFreq(int64_t timestamp, TraceBlobView view) {
Isabelle Taylor14674d42018-09-07 11:33:11 +0100848 ProtoDecoder decoder(view.data(), view.length());
849
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100850 uint32_t cpu_affected = 0;
Isabelle Taylor14674d42018-09-07 11:33:11 +0100851 uint32_t new_freq = 0;
852 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
853 switch (fld.id) {
854 case protos::CpuFrequencyFtraceEvent::kCpuIdFieldNumber:
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100855 cpu_affected = fld.as_uint32();
Isabelle Taylor14674d42018-09-07 11:33:11 +0100856 break;
857 case protos::CpuFrequencyFtraceEvent::kStateFieldNumber:
858 new_freq = fld.as_uint32();
859 break;
860 }
861 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100862 context_->event_tracker->PushCounter(timestamp, new_freq, cpu_freq_name_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000863 cpu_affected, RefType::kRefCpuId);
Isabelle Taylor14674d42018-09-07 11:33:11 +0100864 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
865}
866
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000867void ProtoTraceParser::ParseCpuIdle(int64_t timestamp, TraceBlobView view) {
Hector Dearman7b794cc2018-11-30 14:35:30 +0000868 ProtoDecoder decoder(view.data(), view.length());
869
870 uint32_t cpu_affected = 0;
871 uint32_t new_state = 0;
872 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
873 switch (fld.id) {
874 case protos::CpuIdleFtraceEvent::kCpuIdFieldNumber:
875 cpu_affected = fld.as_uint32();
876 break;
877 case protos::CpuIdleFtraceEvent::kStateFieldNumber:
878 new_state = fld.as_uint32();
879 break;
880 }
881 }
882 context_->event_tracker->PushCounter(timestamp, new_state, cpu_idle_name_id_,
883 cpu_affected, RefType::kRefCpuId);
884 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
885}
886
Primiano Tucci7e330292018-08-24 19:10:52 +0200887void ProtoTraceParser::ParseSchedSwitch(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000888 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100889 TraceBlobView sswitch) {
890 ProtoDecoder decoder(sswitch.data(), sswitch.length());
891
Lalit Magantidf3e9262018-06-04 17:45:00 +0100892 uint32_t prev_pid = 0;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000893 int64_t prev_state = 0;
Lalit Magantifde29042018-10-04 13:28:52 +0100894 base::StringView next_comm;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100895 uint32_t next_pid = 0;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000896 int32_t next_prio = 0;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100897 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
898 switch (fld.id) {
899 case protos::SchedSwitchFtraceEvent::kPrevPidFieldNumber:
900 prev_pid = fld.as_uint32();
901 break;
Lalit Maganti35622b72018-06-06 12:03:11 +0100902 case protos::SchedSwitchFtraceEvent::kPrevStateFieldNumber:
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000903 prev_state = fld.as_int64();
Lalit Maganti35622b72018-06-06 12:03:11 +0100904 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100905 case protos::SchedSwitchFtraceEvent::kNextPidFieldNumber:
906 next_pid = fld.as_uint32();
907 break;
Lalit Magantifde29042018-10-04 13:28:52 +0100908 case protos::SchedSwitchFtraceEvent::kNextCommFieldNumber:
909 next_comm = fld.as_string();
910 break;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000911 case protos::SchedSwitchFtraceEvent::kNextPrioFieldNumber:
912 next_prio = fld.as_int32();
913 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100914 default:
915 break;
916 }
917 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100918 context_->event_tracker->PushSchedSwitch(cpu, timestamp, prev_pid, prev_state,
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000919 next_pid, next_comm, next_prio);
Lalit Magantidf3e9262018-06-04 17:45:00 +0100920 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
921}
922
Hector Dearman947f12a2018-09-11 16:50:36 +0100923void ProtoTraceParser::ParsePrint(uint32_t,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000924 int64_t timestamp,
Lalit Magantide6267f2018-11-08 12:35:34 +0000925 uint32_t pid,
Hector Dearman947f12a2018-09-11 16:50:36 +0100926 TraceBlobView print) {
927 ProtoDecoder decoder(print.data(), print.length());
928
929 base::StringView buf{};
930 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
931 if (fld.id == protos::PrintFtraceEvent::kBufFieldNumber) {
932 buf = fld.as_string();
933 break;
934 }
935 }
936
937 SystraceTracePoint point{};
938 if (!ParseSystraceTracePoint(buf, &point))
939 return;
940
Hector Dearman947f12a2018-09-11 16:50:36 +0100941 switch (point.phase) {
942 case 'B': {
943 StringId name_id = context_->storage->InternString(point.name);
Lalit Magantide6267f2018-11-08 12:35:34 +0000944 context_->slice_tracker->BeginAndroid(timestamp, pid, point.tid,
945 0 /*cat_id*/, name_id);
Hector Dearman947f12a2018-09-11 16:50:36 +0100946 break;
947 }
948
949 case 'E': {
Lalit Magantide6267f2018-11-08 12:35:34 +0000950 context_->slice_tracker->EndAndroid(timestamp, pid, point.tid);
Hector Dearman947f12a2018-09-11 16:50:36 +0100951 break;
952 }
Isabelle Taylor31e04402018-09-19 12:13:25 +0100953
954 case 'C': {
Lalit Maganti94c522b2019-01-15 00:03:15 +0000955 // LMK events from userspace are hacked as counter events with the "value"
956 // of the counter representing the pid of the killed process which is
957 // reset to 0 once the kill is complete.
958 // Homogenise this with kernel LMK events as an instant event, ignoring
959 // the resets to 0.
960 if (point.name == "kill_one_process") {
961 auto killed_pid = static_cast<uint32_t>(point.value);
962 if (killed_pid != 0) {
963 UniquePid killed_upid =
964 context_->process_tracker->UpdateProcess(killed_pid);
965 context_->storage->mutable_instants()->AddInstantEvent(
966 timestamp, lmk_id_, 0, killed_upid, RefType::kRefUpid);
967 }
968 // TODO(tilal6991): we should not add LMK events to the counters table
969 // once the UI has support for displaying instants.
970 }
Lalit Magantide6267f2018-11-08 12:35:34 +0000971 UniqueTid utid =
972 context_->process_tracker->UpdateThread(timestamp, point.tid, 0);
Isabelle Taylor31e04402018-09-19 12:13:25 +0100973 StringId name_id = context_->storage->InternString(point.name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100974 context_->event_tracker->PushCounter(timestamp, point.value, name_id,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000975 utid, RefType::kRefUtid);
Isabelle Taylor31e04402018-09-19 12:13:25 +0100976 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100977 }
978 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
979}
980
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000981void ProtoTraceParser::ParseBatteryCounters(int64_t ts, TraceBlobView battery) {
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100982 ProtoDecoder decoder(battery.data(), battery.length());
983 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
984 switch (fld.id) {
985 case protos::BatteryCounters::kChargeCounterUahFieldNumber:
986 context_->event_tracker->PushCounter(
987 ts, fld.as_int64(), batt_charge_id_, 0, RefType::kRefNoRef);
988 break;
989 case protos::BatteryCounters::kCapacityPercentFieldNumber:
990 context_->event_tracker->PushCounter(
991 ts, static_cast<double>(fld.as_float()), batt_capacity_id_, 0,
992 RefType::kRefNoRef);
993 break;
994 case protos::BatteryCounters::kCurrentUaFieldNumber:
995 context_->event_tracker->PushCounter(
996 ts, fld.as_int64(), batt_current_id_, 0, RefType::kRefNoRef);
997 break;
998 case protos::BatteryCounters::kCurrentAvgUaFieldNumber:
999 context_->event_tracker->PushCounter(
1000 ts, fld.as_int64(), batt_current_avg_id_, 0, RefType::kRefNoRef);
1001 break;
1002 default:
1003 break;
1004 }
1005 }
1006 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1007}
1008
Lalit Maganti85ca4a82018-12-07 17:28:02 +00001009void ProtoTraceParser::ParseOOMScoreAdjUpdate(int64_t ts,
Primiano Tucci44231042018-12-06 21:34:32 +00001010 TraceBlobView oom_update) {
1011 ProtoDecoder decoder(oom_update.data(), oom_update.length());
1012 uint32_t pid = 0;
1013 int16_t oom_adj = 0;
1014
1015 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1016 switch (fld.id) {
1017 case protos::OomScoreAdjUpdateFtraceEvent::kOomScoreAdjFieldNumber:
Primiano Tucci90cdc852018-12-21 10:29:44 +01001018 // TODO(b/120618641): The int16_t static cast is required because of
1019 // the linked negative varint encoding bug.
Primiano Tucci44231042018-12-06 21:34:32 +00001020 oom_adj = static_cast<int16_t>(fld.as_int32());
1021 break;
1022 case protos::OomScoreAdjUpdateFtraceEvent::kPidFieldNumber:
1023 pid = fld.as_uint32();
1024 break;
1025 case protos::OomScoreAdjUpdateFtraceEvent::kCommFieldNumber:
1026 default:
1027 break;
1028 }
1029 }
1030 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1031
1032 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
1033 context_->event_tracker->PushCounter(ts, oom_adj, oom_score_adj_id_, upid,
1034 RefType::kRefUpid);
1035}
1036
Lalit Magantia824c332019-01-23 17:55:58 +00001037void ProtoTraceParser::ParseMmEventRecordField(int64_t ts,
1038 uint32_t pid,
1039 TraceBlobView view) {
1040 ProtoDecoder decoder(view.data(), view.length());
1041
1042 uint32_t type = 0;
1043 uint32_t count = 0;
1044 uint32_t max_lat = 0;
1045 uint32_t avg_lat = 0;
1046 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1047 switch (fld.id) {
1048 case protos::MmEventRecordFtraceEvent::kTypeFieldNumber:
1049 type = fld.as_uint32();
1050 break;
1051 case protos::MmEventRecordFtraceEvent::kCountFieldNumber:
1052 count = fld.as_uint32();
1053 break;
1054 case protos::MmEventRecordFtraceEvent::kMaxLatFieldNumber:
1055 max_lat = fld.as_uint32();
1056 break;
1057 case protos::MmEventRecordFtraceEvent::kAvgLatFieldNumber:
1058 avg_lat = fld.as_uint32();
1059 break;
1060 default:
1061 context_->storage->IncrementStats(stats::mm_unknown_counter);
1062 break;
1063 }
1064 }
1065
1066 UniqueTid utid = context_->process_tracker->UpdateThread(ts, pid, 0);
1067 if (type >= mm_event_counter_names_.size()) {
1068 context_->storage->IncrementStats(stats::mm_unknown_type);
1069 return;
1070 }
1071
1072 const auto& counter_names = mm_event_counter_names_[type];
1073 context_->event_tracker->PushCounter(ts, count, counter_names.count, utid,
1074 RefType::kRefUtidLookupUpid);
1075 context_->event_tracker->PushCounter(ts, max_lat, counter_names.max_lat, utid,
1076 RefType::kRefUtidLookupUpid);
1077 context_->event_tracker->PushCounter(ts, avg_lat, counter_names.avg_lat, utid,
1078 RefType::kRefUtidLookupUpid);
1079
1080 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1081}
1082
Lalit Maganti1d915a62019-01-07 12:10:42 +00001083void ProtoTraceParser::ParseGenericFtrace(int64_t timestamp,
Lalit Magantie87cc812019-01-10 15:20:06 +00001084 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +00001085 uint32_t tid,
1086 TraceBlobView view) {
1087 ProtoDecoder decoder(view.data(), view.length());
1088
1089 base::StringView event_name;
1090 if (!PERFETTO_LIKELY((decoder.FindStringField<
1091 protos::GenericFtraceEvent::kEventNameFieldNumber>(
1092 &event_name)))) {
1093 PERFETTO_ELOG("Event name not found in generic ftrace packet");
1094 return;
1095 }
1096
1097 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, tid, 0);
1098 StringId event_id = context_->storage->InternString(std::move(event_name));
1099 RowId row_id = context_->storage->mutable_raw_events()->AddRawEvent(
Lalit Magantie87cc812019-01-10 15:20:06 +00001100 timestamp, event_id, cpu, utid);
Lalit Maganti1d915a62019-01-07 12:10:42 +00001101
1102 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1103 switch (fld.id) {
1104 case protos::GenericFtraceEvent::kFieldFieldNumber:
1105 const size_t fld_off = view.offset_of(fld.data());
1106 ParseGenericFtraceField(row_id, view.slice(fld_off, fld.size()));
1107 break;
1108 }
1109 }
1110}
1111
1112void ProtoTraceParser::ParseGenericFtraceField(RowId generic_row_id,
1113 TraceBlobView view) {
1114 ProtoDecoder decoder(view.data(), view.length());
1115
1116 base::StringView field_name;
1117 if (!PERFETTO_LIKELY((decoder.FindStringField<
1118 protos::GenericFtraceEvent::Field::kNameFieldNumber>(
1119 &field_name)))) {
1120 PERFETTO_ELOG("Event name not found in generic ftrace packet");
1121 return;
1122 }
1123 auto field_name_id = context_->storage->InternString(std::move(field_name));
1124 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1125 switch (fld.id) {
1126 case protos::GenericFtraceEvent::Field::kIntValue:
1127 case protos::GenericFtraceEvent::Field::kUintValue: {
1128 context_->storage->mutable_args()->AddArg(
1129 generic_row_id, field_name_id, field_name_id,
1130 Variadic::Integer(fld.as_integer()));
1131 break;
1132 }
1133 case protos::GenericFtraceEvent::Field::kStrValue: {
1134 StringId value = context_->storage->InternString(fld.as_string());
1135 context_->storage->mutable_args()->AddArg(generic_row_id, field_name_id,
1136 field_name_id,
1137 Variadic::String(value));
1138 }
1139 }
1140 }
1141}
1142
1143void ProtoTraceParser::ParseTypedFtraceToRaw(uint32_t ftrace_id,
1144 int64_t timestamp,
Lalit Magantie87cc812019-01-10 15:20:06 +00001145 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +00001146 uint32_t tid,
1147 TraceBlobView view) {
1148 ProtoDecoder decoder(view.data(), view.length());
1149 if (ftrace_id >= GetDescriptorsSize()) {
1150 PERFETTO_DLOG("Event with id: %d does not exist and cannot be parsed.",
1151 ftrace_id);
1152 return;
1153 }
1154 MessageDescriptor* m = GetMessageDescriptorForId(ftrace_id);
1155 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, tid, 0);
1156 RowId raw_event_id = context_->storage->mutable_raw_events()->AddRawEvent(
Lalit Magantie87cc812019-01-10 15:20:06 +00001157 timestamp, context_->storage->InternString(m->name), cpu, utid);
Lalit Maganti1d915a62019-01-07 12:10:42 +00001158 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1159 ProtoSchemaType type = m->fields[fld.id].type;
1160 StringId name_id = context_->storage->InternString(m->fields[fld.id].name);
1161 switch (type) {
1162 case ProtoSchemaType::kUint32:
1163 case ProtoSchemaType::kInt32:
1164 case ProtoSchemaType::kUint64:
1165 case ProtoSchemaType::kInt64:
1166 case ProtoSchemaType::kFixed64:
1167 case ProtoSchemaType::kFixed32:
1168 case ProtoSchemaType::kSfixed32:
1169 case ProtoSchemaType::kSfixed64:
1170 case ProtoSchemaType::kSint32:
1171 case ProtoSchemaType::kSint64:
1172 case ProtoSchemaType::kBool:
1173 case ProtoSchemaType::kEnum: {
1174 context_->storage->mutable_args()->AddArg(
1175 raw_event_id, name_id, name_id,
1176 Variadic::Integer(fld.as_integer()));
1177 break;
1178 }
1179 case ProtoSchemaType::kString:
1180 case ProtoSchemaType::kBytes: {
1181 StringId value = context_->storage->InternString(fld.as_string());
1182 context_->storage->mutable_args()->AddArg(
1183 raw_event_id, name_id, name_id, Variadic::String(value));
1184 break;
1185 }
1186 case ProtoSchemaType::kDouble:
1187 case ProtoSchemaType::kFloat: {
1188 context_->storage->mutable_args()->AddArg(
1189 raw_event_id, name_id, name_id, Variadic::Real(fld.as_real()));
1190 break;
1191 }
1192 case ProtoSchemaType::kUnknown:
1193 case ProtoSchemaType::kGroup:
1194 case ProtoSchemaType::kMessage:
1195 PERFETTO_DLOG("Could not store %s as a field in args table.",
1196 ProtoSchemaToString(type));
1197 break;
1198 }
1199 }
1200}
1201
Primiano Tuccia270f012019-01-07 20:01:00 +00001202void ProtoTraceParser::ParseClockSnapshot(TraceBlobView packet) {
1203 ProtoDecoder decoder(packet.data(), packet.length());
1204 int64_t clock_boottime = 0;
1205 int64_t clock_monotonic = 0;
1206 int64_t clock_realtime = 0;
1207
1208 // This loop iterates over the "repeated Clock" entries.
1209 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1210 switch (fld.id) {
1211 case protos::ClockSnapshot::kClocksFieldNumber: {
1212 const size_t fld_off = packet.offset_of(fld.data());
1213 auto clk = ParseClockField(packet.slice(fld_off, fld.size()));
1214 switch (clk.first) {
1215 case protos::ClockSnapshot::Clock::BOOTTIME:
1216 clock_boottime = clk.second;
1217 break;
1218 case protos::ClockSnapshot::Clock::REALTIME:
1219 clock_realtime = clk.second;
1220 break;
1221 case protos::ClockSnapshot::Clock::MONOTONIC:
1222 clock_monotonic = clk.second;
1223 break;
1224 }
1225 break;
1226 }
1227 default:
1228 break;
1229 }
1230 }
1231 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1232
1233 // Usually these snapshots come all together.
1234 PERFETTO_DCHECK(clock_boottime > 0 && clock_monotonic > 0 &&
1235 clock_realtime > 0);
1236
1237 if (clock_boottime <= 0) {
1238 PERFETTO_ELOG("ClockSnapshot has an invalid BOOTTIME (%" PRId64 ")",
1239 clock_boottime);
Primiano Tucci0e38a142019-01-07 20:51:09 +00001240 context_->storage->IncrementStats(stats::invalid_clock_snapshots);
Primiano Tuccia270f012019-01-07 20:01:00 +00001241 return;
1242 }
1243
1244 auto* ct = context_->clock_tracker.get();
1245
1246 // |clock_boottime| is used as the reference trace time.
1247 ct->SyncClocks(ClockDomain::kBootTime, clock_boottime, clock_boottime);
1248
1249 if (clock_monotonic > 0)
1250 ct->SyncClocks(ClockDomain::kMonotonic, clock_monotonic, clock_boottime);
1251
1252 if (clock_realtime > 0)
1253 ct->SyncClocks(ClockDomain::kRealTime, clock_realtime, clock_boottime);
1254}
1255
1256std::pair<int, int64_t> ProtoTraceParser::ParseClockField(
1257 TraceBlobView packet) {
1258 ProtoDecoder decoder(packet.data(), packet.length());
1259 int type = protos::ClockSnapshot::Clock::UNKNOWN;
1260 int64_t value = -1;
1261
1262 // This loop iterates over the |type| and |timestamp| field of each
1263 // clock snapshot.
1264 for (auto fld = decoder.ReadField(); fld.id; fld = decoder.ReadField()) {
1265 switch (fld.id) {
1266 case protos::ClockSnapshot::Clock::kTypeFieldNumber:
1267 type = fld.as_int32();
1268 break;
1269 case protos::ClockSnapshot::Clock::kTimestampFieldNumber:
1270 value = fld.as_int64();
1271 break;
1272 }
1273 }
1274 return std::make_pair(type, value);
1275}
1276
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001277void ProtoTraceParser::ParseAndroidLogPacket(TraceBlobView packet) {
1278 ProtoDecoder decoder(packet.data(), packet.length());
1279 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1280 switch (fld.id) {
1281 case protos::AndroidLogPacket::kEventsFieldNumber: {
1282 const size_t fld_off = packet.offset_of(fld.data());
1283 ParseAndroidLogEvent(packet.slice(fld_off, fld.size()));
1284 break;
1285 }
Primiano Tucci0e38a142019-01-07 20:51:09 +00001286 case protos::AndroidLogPacket::kStatsFieldNumber: {
1287 const size_t fld_off = packet.offset_of(fld.data());
1288 ParseAndroidLogStats(packet.slice(fld_off, fld.size()));
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001289 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001290 }
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001291 }
1292 }
1293 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1294}
1295
1296void ProtoTraceParser::ParseAndroidLogEvent(TraceBlobView event) {
1297 // TODO(primiano): Add events and non-stringified fields to the "raw" table.
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001298 ProtoDecoder decoder(event.data(), event.length());
1299 int64_t ts = 0;
1300 uint32_t pid = 0;
1301 uint32_t tid = 0;
1302 uint8_t prio = 0;
1303 StringId tag_id = 0;
1304 StringId msg_id = 0;
1305 char arg_msg[4096];
1306 char* arg_str = &arg_msg[0];
1307 *arg_str = '\0';
1308 auto arg_avail = [&arg_msg, &arg_str]() {
1309 return sizeof(arg_msg) - static_cast<size_t>(arg_str - arg_msg);
1310 };
1311
1312 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1313 switch (fld.id) {
1314 case protos::AndroidLogPacket::LogEvent::kPidFieldNumber:
1315 pid = fld.as_uint32();
1316 break;
1317 case protos::AndroidLogPacket::LogEvent::kTidFieldNumber:
1318 tid = fld.as_uint32();
1319 break;
1320 case protos::AndroidLogPacket::LogEvent::kTimestampFieldNumber:
1321 ts = fld.as_int64();
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001322 break;
1323 case protos::AndroidLogPacket::LogEvent::kPrioFieldNumber:
1324 prio = static_cast<uint8_t>(fld.as_uint32());
1325 break;
1326 case protos::AndroidLogPacket::LogEvent::kTagFieldNumber:
1327 tag_id = context_->storage->InternString(fld.as_string());
1328 break;
1329 case protos::AndroidLogPacket::LogEvent::kMessageFieldNumber:
1330 msg_id = context_->storage->InternString(fld.as_string());
1331 break;
1332 case protos::AndroidLogPacket::LogEvent::kArgsFieldNumber: {
1333 const size_t fld_off = event.offset_of(fld.data());
1334 TraceBlobView arg_data = event.slice(fld_off, fld.size());
1335 ParseAndroidLogBinaryArg(std::move(arg_data), &arg_str, arg_avail());
1336 break;
1337 }
1338 default:
1339 break;
1340 }
1341 }
1342 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1343
1344 if (prio == 0)
1345 prio = protos::AndroidLogPriority::PRIO_INFO;
1346
1347 if (arg_str != &arg_msg[0]) {
1348 PERFETTO_DCHECK(!msg_id);
1349 // Skip the first space char (" foo=1 bar=2" -> "foo=1 bar=2").
1350 msg_id = context_->storage->InternString(&arg_msg[1]);
1351 }
1352 UniquePid utid = tid ? context_->process_tracker->UpdateThread(tid, pid) : 0;
1353 int64_t trace_time =
1354 context_->clock_tracker->ToTraceTime(ClockDomain::kRealTime, ts);
1355
1356 // Log events are NOT required to be sorted by trace_time. The virtual table
1357 // will take care of sorting on-demand.
1358 context_->storage->mutable_android_log()->AddLogEvent(trace_time, utid, prio,
1359 tag_id, msg_id);
1360}
1361
1362void ProtoTraceParser::ParseAndroidLogBinaryArg(TraceBlobView arg,
1363 char** str,
1364 size_t avail) {
1365 ProtoDecoder decoder(arg.data(), arg.length());
1366 for (auto fld = decoder.ReadField(); fld.id; fld = decoder.ReadField()) {
1367 switch (fld.id) {
1368 case protos::AndroidLogPacket::LogEvent::Arg::kNameFieldNumber: {
1369 base::StringView name = fld.as_string();
1370 *str += snprintf(*str, avail, " %.*s=", static_cast<int>(name.size()),
1371 name.data());
1372 break;
1373 }
1374 case protos::AndroidLogPacket::LogEvent::Arg::kStringValueFieldNumber: {
1375 base::StringView val = fld.as_string();
1376 *str += snprintf(*str, avail, "\"%.*s\"", static_cast<int>(val.size()),
1377 val.data());
1378 break;
1379 }
1380 case protos::AndroidLogPacket::LogEvent::Arg::kIntValueFieldNumber:
1381 *str += snprintf(*str, avail, "%" PRId64, fld.as_int64());
1382 break;
1383 case protos::AndroidLogPacket::LogEvent::Arg::kFloatValueFieldNumber:
1384 *str +=
1385 snprintf(*str, avail, "%f", static_cast<double>(fld.as_float()));
1386 break;
1387 }
1388 }
1389}
1390
Primiano Tucci0e38a142019-01-07 20:51:09 +00001391void ProtoTraceParser::ParseAndroidLogStats(TraceBlobView packet) {
1392 ProtoDecoder decoder(packet.data(), packet.length());
1393 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1394 switch (fld.id) {
1395 case protos::AndroidLogPacket::Stats::kNumFailedFieldNumber:
1396 context_->storage->SetStats(stats::android_log_num_failed,
1397 fld.as_int64());
1398 break;
1399 case protos::AndroidLogPacket::Stats::kNumSkippedFieldNumber:
1400 context_->storage->SetStats(stats::android_log_num_skipped,
1401 fld.as_int64());
1402 break;
1403 case protos::AndroidLogPacket::Stats::kNumTotalFieldNumber:
1404 context_->storage->SetStats(stats::android_log_num_total,
1405 fld.as_int64());
1406 break;
1407 }
1408 }
1409 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1410}
1411
1412void ProtoTraceParser::ParseTraceStats(TraceBlobView packet) {
1413 ProtoDecoder decoder(packet.data(), packet.length());
1414 int buf_num = 0;
1415 auto* storage = context_->storage.get();
1416 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1417 switch (fld.id) {
1418 case protos::TraceStats::kProducersConnectedFieldNumber:
1419 storage->SetStats(stats::traced_producers_connected, fld.as_int64());
1420 break;
1421 case protos::TraceStats::kProducersSeenFieldNumber:
1422 storage->SetStats(stats::traced_producers_seen, fld.as_int64());
1423 break;
1424 case protos::TraceStats::kDataSourcesRegisteredFieldNumber:
1425 storage->SetStats(stats::traced_data_sources_registered,
1426 fld.as_int64());
1427 break;
1428 case protos::TraceStats::kDataSourcesSeenFieldNumber:
1429 storage->SetStats(stats::traced_data_sources_seen, fld.as_int64());
1430 break;
1431 case protos::TraceStats::kTracingSessionsFieldNumber:
1432 storage->SetStats(stats::traced_tracing_sessions, fld.as_int64());
1433 break;
1434 case protos::TraceStats::kTotalBuffersFieldNumber:
1435 storage->SetStats(stats::traced_total_buffers, fld.as_int64());
1436 break;
1437 case protos::TraceStats::kBufferStatsFieldNumber: {
1438 const size_t fld_off = packet.offset_of(fld.data());
1439 TraceBlobView buf_data = packet.slice(fld_off, fld.size());
1440 ProtoDecoder buf_d(buf_data.data(), buf_data.length());
1441 for (auto fld2 = buf_d.ReadField(); fld2.id; fld2 = buf_d.ReadField()) {
1442 switch (fld2.id) {
Eric Secklerbd8aae52019-01-28 08:57:31 +00001443 case protos::TraceStats::BufferStats::kBufferSizeFieldNumber:
1444 storage->SetIndexedStats(stats::traced_buf_buffer_size, buf_num,
1445 fld2.as_int64());
1446 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001447 case protos::TraceStats::BufferStats::kBytesWrittenFieldNumber:
1448 storage->SetIndexedStats(stats::traced_buf_bytes_written, buf_num,
1449 fld2.as_int64());
1450 break;
Eric Secklerbd8aae52019-01-28 08:57:31 +00001451 case protos::TraceStats::BufferStats::kBytesOverwrittenFieldNumber:
1452 storage->SetIndexedStats(stats::traced_buf_bytes_overwritten,
1453 buf_num, fld2.as_int64());
1454 break;
1455 case protos::TraceStats::BufferStats::kBytesReadFieldNumber:
1456 storage->SetIndexedStats(stats::traced_buf_bytes_read, buf_num,
1457 fld2.as_int64());
1458 break;
1459 case protos::TraceStats::BufferStats::
1460 kPaddingBytesWrittenFieldNumber:
1461 storage->SetIndexedStats(stats::traced_buf_padding_bytes_written,
1462 buf_num, fld2.as_int64());
1463 break;
1464 case protos::TraceStats::BufferStats::
1465 kPaddingBytesClearedFieldNumber:
1466 storage->SetIndexedStats(stats::traced_buf_padding_bytes_cleared,
1467 buf_num, fld2.as_int64());
1468 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001469 case protos::TraceStats::BufferStats::kChunksWrittenFieldNumber:
1470 storage->SetIndexedStats(stats::traced_buf_chunks_written,
1471 buf_num, fld2.as_int64());
1472 break;
Stephen Nuskod13fdf82019-01-15 11:22:58 +00001473 case protos::TraceStats::BufferStats::kChunksRewrittenFieldNumber:
1474 storage->SetIndexedStats(stats::traced_buf_chunks_rewritten,
1475 buf_num, fld2.as_int64());
1476 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001477 case protos::TraceStats::BufferStats::kChunksOverwrittenFieldNumber:
1478 storage->SetIndexedStats(stats::traced_buf_chunks_overwritten,
1479 buf_num, fld2.as_int64());
1480 break;
Primiano Tuccib45a69b2019-01-25 14:32:10 +00001481 case protos::TraceStats::BufferStats::kChunksDiscardedFieldNumber:
1482 storage->SetIndexedStats(stats::traced_buf_chunks_discarded,
1483 buf_num, fld2.as_int64());
1484 break;
Eric Secklerbd8aae52019-01-28 08:57:31 +00001485 case protos::TraceStats::BufferStats::kChunksReadFieldNumber:
1486 storage->SetIndexedStats(stats::traced_buf_chunks_read, buf_num,
1487 fld2.as_int64());
1488 break;
Stephen Nuskod13fdf82019-01-15 11:22:58 +00001489 case protos::TraceStats::BufferStats::
1490 kChunksCommittedOutOfOrderFieldNumber:
1491 storage->SetIndexedStats(
1492 stats::traced_buf_chunks_committed_out_of_order, buf_num,
1493 fld2.as_int64());
1494 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001495 case protos::TraceStats::BufferStats::kWriteWrapCountFieldNumber:
1496 storage->SetIndexedStats(stats::traced_buf_write_wrap_count,
1497 buf_num, fld2.as_int64());
1498 break;
1499 case protos::TraceStats::BufferStats::kPatchesSucceededFieldNumber:
1500 storage->SetIndexedStats(stats::traced_buf_patches_succeeded,
1501 buf_num, fld2.as_int64());
1502 break;
1503 case protos::TraceStats::BufferStats::kPatchesFailedFieldNumber:
1504 storage->SetIndexedStats(stats::traced_buf_patches_failed,
1505 buf_num, fld2.as_int64());
1506 break;
1507 case protos::TraceStats::BufferStats::
1508 kReadaheadsSucceededFieldNumber:
1509 storage->SetIndexedStats(stats::traced_buf_readaheads_succeeded,
1510 buf_num, fld2.as_int64());
1511 break;
1512 case protos::TraceStats::BufferStats::kReadaheadsFailedFieldNumber:
1513 storage->SetIndexedStats(stats::traced_buf_readaheads_failed,
1514 buf_num, fld2.as_int64());
1515 break;
1516 }
1517 } // for (buf_fld)
1518 buf_num++;
1519 break;
1520 }
1521 default:
1522 break;
1523 }
1524 }
1525 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1526}
1527
1528void ProtoTraceParser::ParseFtraceStats(TraceBlobView packet) {
1529 ProtoDecoder decoder(packet.data(), packet.length());
1530 size_t phase = 0;
1531 auto* storage = context_->storage.get();
1532 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1533 switch (fld.id) {
1534 case protos::FtraceStats::kPhaseFieldNumber:
1535 phase = fld.int_value == protos::FtraceStats_Phase_END_OF_TRACE ? 1 : 0;
1536
1537 // This code relies on the fact that each ftrace_cpu_XXX_end event is
1538 // just after the corresponding ftrace_cpu_XXX_begin event.
1539 static_assert(stats::ftrace_cpu_read_events_end -
1540 stats::ftrace_cpu_read_events_begin ==
1541 1 &&
1542 stats::ftrace_cpu_entries_end -
1543 stats::ftrace_cpu_entries_begin ==
1544 1,
1545 "ftrace_cpu_XXX stats definition are messed up");
1546 break;
1547 case protos::FtraceStats::kCpuStatsFieldNumber: {
1548 const size_t fld_off = packet.offset_of(fld.data());
1549 TraceBlobView cpu_data = packet.slice(fld_off, fld.size());
1550 ProtoDecoder cpu_d(cpu_data.data(), cpu_data.length());
1551 int cpu_num = -1;
1552 for (auto fld2 = cpu_d.ReadField(); fld2.id; fld2 = cpu_d.ReadField()) {
1553 switch (fld2.id) {
1554 case protos::FtraceCpuStats::kCpuFieldNumber:
1555 cpu_num = fld2.as_int32();
1556 break;
1557 case protos::FtraceCpuStats::kEntriesFieldNumber:
1558 storage->SetIndexedStats(stats::ftrace_cpu_entries_begin + phase,
1559 cpu_num, fld2.as_int64());
1560 break;
1561 case protos::FtraceCpuStats::kOverrunFieldNumber:
1562 storage->SetIndexedStats(stats::ftrace_cpu_overrun_begin + phase,
1563 cpu_num, fld2.as_int64());
1564 break;
1565 case protos::FtraceCpuStats::kCommitOverrunFieldNumber:
1566 storage->SetIndexedStats(
1567 stats::ftrace_cpu_commit_overrun_begin + phase, cpu_num,
1568 fld2.as_int64());
1569 break;
1570 case protos::FtraceCpuStats::kBytesReadFieldNumber:
1571 storage->SetIndexedStats(
1572 stats::ftrace_cpu_bytes_read_begin + phase, cpu_num,
1573 fld2.as_int64());
1574 break;
1575 case protos::FtraceCpuStats::kOldestEventTsFieldNumber:
1576 storage->SetIndexedStats(
1577 stats::ftrace_cpu_oldest_event_ts_begin + phase, cpu_num,
1578 static_cast<int64_t>(fld2.as_double() * 1e9));
1579 break;
1580 case protos::FtraceCpuStats::kNowTsFieldNumber:
1581 storage->SetIndexedStats(
1582 stats::ftrace_cpu_now_ts_begin + phase, cpu_num,
1583 static_cast<int64_t>(fld2.as_double() * 1e9));
1584 break;
1585 case protos::FtraceCpuStats::kDroppedEventsFieldNumber:
1586 storage->SetIndexedStats(
1587 stats::ftrace_cpu_dropped_events_begin + phase, cpu_num,
1588 fld2.as_int64());
1589 break;
1590 case protos::FtraceCpuStats::kReadEventsFieldNumber:
1591 storage->SetIndexedStats(
1592 stats::ftrace_cpu_read_events_begin + phase, cpu_num,
1593 fld2.as_int64());
1594 break;
1595 }
1596 } // for (buf_fld)
1597 break;
1598 }
1599 default:
1600 break;
1601 }
1602 }
1603 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1604}
1605
Lalit Maganti93b76362018-06-01 03:03:58 +01001606} // namespace trace_processor
1607} // namespace perfetto