blob: a36e76e7c6269723fe2d905d64f5c49b5c7dedc4 [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"
Hector Dearmanba43f602019-01-29 14:36:11 +000024#include "perfetto/base/optional.h"
Primiano Tucci2da5d2e2018-08-10 14:23:31 +010025#include "perfetto/base/string_view.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010026#include "perfetto/base/utils.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010027#include "perfetto/protozero/proto_decoder.h"
Isabelle Taylor54ce7052018-10-01 14:00:15 +010028#include "perfetto/traced/sys_stats_counters.h"
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +000029#include "src/trace_processor/args_tracker.h"
Primiano Tuccia270f012019-01-07 20:01:00 +000030#include "src/trace_processor/clock_tracker.h"
Isabelle Taylora97c5f52018-10-23 17:36:12 +010031#include "src/trace_processor/event_tracker.h"
Lalit Maganti1d915a62019-01-07 12:10:42 +000032#include "src/trace_processor/ftrace_descriptors.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010033#include "src/trace_processor/process_tracker.h"
Hector Dearman947f12a2018-09-11 16:50:36 +010034#include "src/trace_processor/slice_tracker.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010035#include "src/trace_processor/trace_processor_context.h"
36
Lalit Magantidf3e9262018-06-04 17:45:00 +010037#include "perfetto/trace/trace.pb.h"
38#include "perfetto/trace/trace_packet.pb.h"
Lalit Maganti93b76362018-06-01 03:03:58 +010039
40namespace perfetto {
41namespace trace_processor {
42
Lalit Maganti1d915a62019-01-07 12:10:42 +000043namespace {
44
45using protozero::ProtoDecoder;
46using Variadic = TraceStorage::Args::Variadic;
47
48} // namespace
49
Hector Dearman947f12a2018-09-11 16:50:36 +010050// We have to handle trace_marker events of a few different types:
51// 1. some random text
52// 2. B|1636|pokeUserActivity
53// 3. E|1636
54// 4. C|1636|wq:monitor|0
55bool ParseSystraceTracePoint(base::StringView str, SystraceTracePoint* out) {
56 // THIS char* IS NOT NULL TERMINATED.
57 const char* s = str.data();
58 size_t len = str.size();
59
Ioannis Ilkos21a76182019-01-28 14:05:01 +000060 // If str matches '[BEC]\|[0-9]+[\|\n]' set tgid_length to the length of
Hector Dearman947f12a2018-09-11 16:50:36 +010061 // the number. Otherwise return false.
Lalit Magantide6267f2018-11-08 12:35:34 +000062 if (s[1] != '|' && s[1] != '\n')
Hector Dearman947f12a2018-09-11 16:50:36 +010063 return false;
64 if (s[0] != 'B' && s[0] != 'E' && s[0] != 'C')
65 return false;
Ioannis Ilkos21a76182019-01-28 14:05:01 +000066 size_t tgid_length = 0;
Lalit Magantide6267f2018-11-08 12:35:34 +000067 for (size_t i = 2; i < len; i++) {
Hector Dearman947f12a2018-09-11 16:50:36 +010068 if (s[i] == '|' || s[i] == '\n') {
Ioannis Ilkos21a76182019-01-28 14:05:01 +000069 tgid_length = i - 2;
Hector Dearman947f12a2018-09-11 16:50:36 +010070 break;
71 }
72 if (s[i] < '0' || s[i] > '9')
73 return false;
74 }
75
Ioannis Ilkos21a76182019-01-28 14:05:01 +000076 if (tgid_length == 0) {
77 out->tgid = 0;
Lalit Magantide6267f2018-11-08 12:35:34 +000078 } else {
Ioannis Ilkos21a76182019-01-28 14:05:01 +000079 std::string tgid_str(s + 2, tgid_length);
80 out->tgid = static_cast<uint32_t>(std::stoi(tgid_str.c_str()));
Lalit Magantide6267f2018-11-08 12:35:34 +000081 }
Hector Dearman947f12a2018-09-11 16:50:36 +010082
83 out->phase = s[0];
84 switch (s[0]) {
85 case 'B': {
Ioannis Ilkos21a76182019-01-28 14:05:01 +000086 size_t name_index = 2 + tgid_length + 1;
Ioannis Ilkos843e4c42019-01-23 17:32:55 +000087 out->name = base::StringView(
88 s + name_index, len - name_index - (s[len - 1] == '\n' ? 1 : 0));
Hector Dearman947f12a2018-09-11 16:50:36 +010089 return true;
90 }
Isabelle Taylor31e04402018-09-19 12:13:25 +010091 case 'E': {
Hector Dearman947f12a2018-09-11 16:50:36 +010092 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +010093 }
94 case 'C': {
Ioannis Ilkos21a76182019-01-28 14:05:01 +000095 size_t name_index = 2 + tgid_length + 1;
Isabelle Taylor31e04402018-09-19 12:13:25 +010096 size_t name_length = 0;
97 for (size_t i = name_index; i < len; i++) {
98 if (s[i] == '|' || s[i] == '\n') {
99 name_length = i - name_index;
100 break;
101 }
102 }
103 out->name = base::StringView(s + name_index, name_length);
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000104
Isabelle Taylor31e04402018-09-19 12:13:25 +0100105 size_t value_index = name_index + name_length + 1;
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000106 size_t value_len = len - value_index;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100107 char value_str[32];
Ioannis Ilkos45b361a2019-01-14 16:51:48 +0000108 if (value_len >= sizeof(value_str)) {
109 return false;
110 }
111 memcpy(value_str, s + value_index, value_len);
112 value_str[value_len] = 0;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100113 out->value = std::stod(value_str);
Hector Dearman947f12a2018-09-11 16:50:36 +0100114 return true;
Isabelle Taylor31e04402018-09-19 12:13:25 +0100115 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100116 default:
117 return false;
118 }
119}
120
Primiano Tucci7e330292018-08-24 19:10:52 +0200121ProtoTraceParser::ProtoTraceParser(TraceProcessorContext* context)
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100122 : context_(context),
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000123 utid_name_id_(context->storage->InternString("utid")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100124 cpu_freq_name_id_(context->storage->InternString("cpufreq")),
Hector Dearman7b794cc2018-11-30 14:35:30 +0000125 cpu_idle_name_id_(context->storage->InternString("cpuidle")),
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000126 comm_name_id_(context->storage->InternString("comm")),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100127 num_forks_name_id_(context->storage->InternString("num_forks")),
128 num_irq_total_name_id_(context->storage->InternString("num_irq_total")),
129 num_softirq_total_name_id_(
130 context->storage->InternString("num_softirq_total")),
131 num_irq_name_id_(context->storage->InternString("num_irq")),
132 num_softirq_name_id_(context->storage->InternString("num_softirq")),
133 cpu_times_user_ns_id_(
134 context->storage->InternString("cpu.times.user_ns")),
135 cpu_times_user_ice_ns_id_(
136 context->storage->InternString("cpu.times.user_ice_ns")),
137 cpu_times_system_mode_ns_id_(
138 context->storage->InternString("cpu.times.system_mode_ns")),
139 cpu_times_idle_ns_id_(
140 context->storage->InternString("cpu.times.idle_ns")),
141 cpu_times_io_wait_ns_id_(
142 context->storage->InternString("cpu.times.io_wait_ns")),
143 cpu_times_irq_ns_id_(context->storage->InternString("cpu.times.irq_ns")),
144 cpu_times_softirq_ns_id_(
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100145 context->storage->InternString("cpu.times.softirq_ns")),
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000146 signal_deliver_id_(context->storage->InternString("signal_deliver")),
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100147 signal_generate_id_(context->storage->InternString("signal_generate")),
148 batt_charge_id_(context->storage->InternString("batt.charge_uah")),
149 batt_capacity_id_(context->storage->InternString("batt.capacity_pct")),
150 batt_current_id_(context->storage->InternString("batt.current_ua")),
151 batt_current_avg_id_(
Primiano Tucci44231042018-12-06 21:34:32 +0000152 context->storage->InternString("batt.current.avg_ua")),
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000153 lmk_id_(context->storage->InternString("mem.lmk")),
Primiano Tucci90cdc852018-12-21 10:29:44 +0100154 oom_score_adj_id_(context->storage->InternString("oom_score_adj")),
155 ion_total_unknown_id_(context->storage->InternString("mem.ion.unknown")),
156 ion_change_unknown_id_(
157 context->storage->InternString("mem.ion_change.unknown")) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100158 for (const auto& name : BuildMeminfoCounterNames()) {
159 meminfo_strs_id_.emplace_back(context->storage->InternString(name));
160 }
161 for (const auto& name : BuildVmstatCounterNames()) {
162 vmstat_strs_id_.emplace_back(context->storage->InternString(name));
163 }
Lalit Maganti6820abc2019-01-21 11:12:23 +0000164 rss_members_.emplace_back(context->storage->InternString("mem.rss.file"));
165 rss_members_.emplace_back(context->storage->InternString("mem.rss.anon"));
Lalit Maganti5a95df22019-01-24 13:28:36 +0000166 rss_members_.emplace_back(context->storage->InternString("mem.swap"));
Lalit Maganti6820abc2019-01-21 11:12:23 +0000167 rss_members_.emplace_back(context->storage->InternString("mem.rss.shmem"));
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100168 rss_members_.emplace_back(
Lalit Maganti6820abc2019-01-21 11:12:23 +0000169 context->storage->InternString("mem.rss.unknown")); // Keep this last.
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700170
Lalit Maganti6820abc2019-01-21 11:12:23 +0000171 using ProcessStats = protos::ProcessStats;
Lalit Maganti41c98922019-01-23 19:35:58 +0000172 proc_stats_process_names_[ProcessStats::Process::kVmSizeKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700173 context->storage->InternString("mem.virt");
Lalit Maganti41c98922019-01-23 19:35:58 +0000174 proc_stats_process_names_[ProcessStats::Process::kVmRssKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700175 context->storage->InternString("mem.rss");
Lalit Maganti41c98922019-01-23 19:35:58 +0000176 proc_stats_process_names_[ProcessStats::Process::kRssAnonKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700177 context->storage->InternString("mem.rss.anon");
Lalit Maganti41c98922019-01-23 19:35:58 +0000178 proc_stats_process_names_[ProcessStats::Process::kRssFileKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700179 context->storage->InternString("mem.rss.file");
Lalit Maganti41c98922019-01-23 19:35:58 +0000180 proc_stats_process_names_[ProcessStats::Process::kRssShmemKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700181 context->storage->InternString("mem.rss.shmem");
Lalit Maganti41c98922019-01-23 19:35:58 +0000182 proc_stats_process_names_[ProcessStats::Process::kVmSwapKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700183 context->storage->InternString("mem.swap");
Lalit Maganti41c98922019-01-23 19:35:58 +0000184 proc_stats_process_names_[ProcessStats::Process::kVmLockedKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700185 context->storage->InternString("mem.locked");
Lalit Maganti41c98922019-01-23 19:35:58 +0000186 proc_stats_process_names_[ProcessStats::Process::kVmHwmKbFieldNumber] =
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700187 context->storage->InternString("mem.rss.watermark");
Lalit Maganti41c98922019-01-23 19:35:58 +0000188 proc_stats_process_names_[ProcessStats::Process::kOomScoreAdjFieldNumber] =
189 oom_score_adj_id_;
Lalit Magantia824c332019-01-23 17:55:58 +0000190
191 mm_event_counter_names_[0] = MmEventCounterNames(
192 context->storage->InternString("mem.mm.min_flt.count"),
193 context->storage->InternString("mem.mm.min_flt.max_lat"),
194 context->storage->InternString("mem.mm.min_flt.avg_lat"));
195 mm_event_counter_names_[1] = MmEventCounterNames(
196 context->storage->InternString("mem.mm.maj_flt.count"),
197 context->storage->InternString("mem.mm.maj_flt.max_lat"),
198 context->storage->InternString("mem.mm.maj_flt.avg_lat"));
199 mm_event_counter_names_[2] = MmEventCounterNames(
200 context->storage->InternString("mem.mm.read_io.count"),
201 context->storage->InternString("mem.mm.read_io.max_lat"),
202 context->storage->InternString("mem.mm.read_io.avg_lat"));
203 mm_event_counter_names_[3] = MmEventCounterNames(
204 context->storage->InternString("mem.mm.compaction.count"),
205 context->storage->InternString("mem.mm.compaction.max_lat"),
206 context->storage->InternString("mem.mm.compaction.avg_lat"));
207 mm_event_counter_names_[4] = MmEventCounterNames(
208 context->storage->InternString("mem.mm.reclaim.count"),
209 context->storage->InternString("mem.mm.reclaim.max_lat"),
210 context->storage->InternString("mem.mm.reclaim.avg_lat"));
211 mm_event_counter_names_[5] = MmEventCounterNames(
212 context->storage->InternString("mem.mm.swp_flt.count"),
213 context->storage->InternString("mem.mm.swp_flt.max_lat"),
214 context->storage->InternString("mem.mm.swp_flt.avg_lat"));
215 mm_event_counter_names_[6] = MmEventCounterNames(
216 context->storage->InternString("mem.mm.kern_alloc.count"),
217 context->storage->InternString("mem.mm.kern_alloc.max_lat"),
218 context->storage->InternString("mem.mm.kern_alloc.avg_lat"));
Lalit Magantid86161a2019-02-06 15:07:13 +0000219
220 // Build the lookup table for the strings inside ftrace events (e.g. the
221 // name of ftrace event fields and the names of their args).
222 for (size_t i = 0; i < GetDescriptorsSize(); i++) {
223 auto* descriptor = GetMessageDescriptorForId(i);
224 if (!descriptor->name) {
225 ftrace_message_strings_.emplace_back();
226 continue;
227 }
228
229 FtraceMessageStrings ftrace_strings;
230 ftrace_strings.message_name_id =
231 context->storage->InternString(descriptor->name);
232
233 for (size_t fid = 0; fid < descriptor->max_field_id; fid++) {
234 const auto& field = descriptor->fields[fid];
235 if (!field.name)
236 continue;
237 ftrace_strings.field_name_ids[fid] =
238 context->storage->InternString(field.name);
239 }
240 ftrace_message_strings_.emplace_back(ftrace_strings);
241 }
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100242}
Lalit Maganti93b76362018-06-01 03:03:58 +0100243
Primiano Tucci0d72a312018-08-07 14:42:45 +0100244ProtoTraceParser::~ProtoTraceParser() = default;
245
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000246void ProtoTraceParser::ParseTracePacket(int64_t ts, TraceBlobView packet) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100247 ProtoDecoder decoder(packet.data(), packet.length());
Lalit Maganti93b76362018-06-01 03:03:58 +0100248
Lalit Magantidf3e9262018-06-04 17:45:00 +0100249 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
250 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100251 case protos::TracePacket::kProcessTreeFieldNumber: {
252 const size_t fld_off = packet.offset_of(fld.data());
253 ParseProcessTree(packet.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100254 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100255 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700256 case protos::TracePacket::kProcessStatsFieldNumber: {
257 const size_t fld_off = packet.offset_of(fld.data());
258 ParseProcessStats(ts, packet.slice(fld_off, fld.size()));
259 break;
260 }
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100261 case protos::TracePacket::kSysStatsFieldNumber: {
262 const size_t fld_off = packet.offset_of(fld.data());
263 ParseSysStats(ts, packet.slice(fld_off, fld.size()));
264 break;
265 }
Primiano Tuccib86e9ca2018-12-03 20:20:11 +0100266 case protos::TracePacket::kBatteryFieldNumber: {
267 const size_t fld_off = packet.offset_of(fld.data());
268 ParseBatteryCounters(ts, packet.slice(fld_off, fld.size()));
269 break;
270 }
Primiano Tucci0e38a142019-01-07 20:51:09 +0000271 case protos::TracePacket::kTraceStatsFieldNumber: {
272 const size_t fld_off = packet.offset_of(fld.data());
273 ParseTraceStats(packet.slice(fld_off, fld.size()));
274 break;
275 }
276 case protos::TracePacket::kFtraceStatsFieldNumber: {
277 const size_t fld_off = packet.offset_of(fld.data());
278 ParseFtraceStats(packet.slice(fld_off, fld.size()));
279 break;
280 }
Primiano Tuccia270f012019-01-07 20:01:00 +0000281 case protos::TracePacket::kClockSnapshotFieldNumber: {
282 const size_t fld_off = packet.offset_of(fld.data());
283 ParseClockSnapshot(packet.slice(fld_off, fld.size()));
284 break;
285 }
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000286 case protos::TracePacket::kAndroidLogFieldNumber: {
287 const size_t fld_off = packet.offset_of(fld.data());
288 ParseAndroidLogPacket(packet.slice(fld_off, fld.size()));
289 break;
290 }
Hector Dearmandd639792019-01-31 15:04:59 +0000291 case protos::TracePacket::kProfilePacketFieldNumber: {
292 const size_t fld_off = packet.offset_of(fld.data());
293 ParseProfilePacket(packet.slice(fld_off, fld.size()));
294 break;
295 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100296 default:
297 break;
298 }
299 }
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000300 // TODO(lalitm): maybe move this to the flush method in the trace processor
301 // once we have it. This may reduce performance in the ArgsTracker though so
302 // needs to be handled carefully.
303 context_->args_tracker->Flush();
304
Lalit Magantidf3e9262018-06-04 17:45:00 +0100305 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
306}
307
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000308void ProtoTraceParser::ParseSysStats(int64_t ts, TraceBlobView stats) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100309 ProtoDecoder decoder(stats.data(), stats.length());
310 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
311 switch (fld.id) {
312 case protos::SysStats::kMeminfoFieldNumber: {
313 const size_t fld_off = stats.offset_of(fld.data());
314 ParseMemInfo(ts, stats.slice(fld_off, fld.size()));
315 break;
316 }
317 case protos::SysStats::kVmstatFieldNumber: {
318 const size_t fld_off = stats.offset_of(fld.data());
319 ParseVmStat(ts, stats.slice(fld_off, fld.size()));
320 break;
321 }
322 case protos::SysStats::kCpuStatFieldNumber: {
323 const size_t fld_off = stats.offset_of(fld.data());
324 ParseCpuTimes(ts, stats.slice(fld_off, fld.size()));
325 break;
326 }
327 case protos::SysStats::kNumIrqFieldNumber: {
328 const size_t fld_off = stats.offset_of(fld.data());
329 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
330 /*is_softirq=*/false);
331 break;
332 }
333 case protos::SysStats::kNumSoftirqFieldNumber: {
334 const size_t fld_off = stats.offset_of(fld.data());
335 ParseIrqCount(ts, stats.slice(fld_off, fld.size()),
336 /*is_softirq=*/true);
337 break;
338 }
339 case protos::SysStats::kNumForksFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100340 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000341 ts, fld.as_uint32(), num_forks_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100342 break;
343 }
344 case protos::SysStats::kNumIrqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100345 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000346 ts, fld.as_uint32(), num_irq_total_name_id_, 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100347 break;
348 }
349 case protos::SysStats::kNumSoftirqTotalFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100350 context_->event_tracker->PushCounter(ts, fld.as_uint32(),
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100351 num_softirq_total_name_id_, 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000352 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100353 break;
354 }
355 default:
356 break;
357 }
358 }
359}
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000360void ProtoTraceParser::ParseIrqCount(int64_t ts,
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100361 TraceBlobView irq,
362 bool is_soft) {
363 ProtoDecoder decoder(irq.data(), irq.length());
364 uint32_t key = 0;
365 uint32_t value = 0;
366 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
367 switch (fld.id) {
368 case protos::SysStats::InterruptCount::kIrqFieldNumber:
369 key = fld.as_uint32();
370 break;
371 case protos::SysStats::InterruptCount::kCountFieldNumber:
372 value = fld.as_uint32();
373 break;
374 }
375 }
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000376 RefType ref_type = is_soft ? RefType::kRefIrq : RefType::kRefSoftIrq;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100377 StringId name_id = is_soft ? num_irq_name_id_ : num_softirq_name_id_;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100378 context_->event_tracker->PushCounter(ts, value, name_id, key, ref_type);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100379}
380
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000381void ProtoTraceParser::ParseMemInfo(int64_t ts, TraceBlobView mem) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100382 ProtoDecoder decoder(mem.data(), mem.length());
383 uint32_t key = 0;
384 uint32_t value = 0;
385 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
386 switch (fld.id) {
387 case protos::SysStats::MeminfoValue::kKeyFieldNumber:
388 key = fld.as_uint32();
389 break;
390 case protos::SysStats::MeminfoValue::kValueFieldNumber:
391 value = fld.as_uint32();
392 break;
393 }
394 }
395 if (PERFETTO_UNLIKELY(key >= meminfo_strs_id_.size())) {
396 PERFETTO_ELOG("MemInfo key %d is not recognized.", key);
Primiano Tucci0e38a142019-01-07 20:51:09 +0000397 context_->storage->IncrementStats(stats::meminfo_unknown_keys);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100398 return;
399 }
Ioannis Ilkos5ef15b42019-01-08 10:57:52 +0000400 // /proc/meminfo counters are in kB, convert to bytes
401 context_->event_tracker->PushCounter(ts, value * 1024L, meminfo_strs_id_[key],
402 0, RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100403}
404
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000405void ProtoTraceParser::ParseVmStat(int64_t ts, TraceBlobView stat) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100406 ProtoDecoder decoder(stat.data(), stat.length());
407 uint32_t key = 0;
408 uint32_t value = 0;
409 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
410 switch (fld.id) {
411 case protos::SysStats::VmstatValue::kKeyFieldNumber:
412 key = fld.as_uint32();
413 break;
414 case protos::SysStats::VmstatValue::kValueFieldNumber:
415 value = fld.as_uint32();
416 break;
417 }
418 }
419 if (PERFETTO_UNLIKELY(key >= vmstat_strs_id_.size())) {
420 PERFETTO_ELOG("VmStat key %d is not recognized.", key);
Primiano Tucci0e38a142019-01-07 20:51:09 +0000421 context_->storage->IncrementStats(stats::vmstat_unknown_keys);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100422 return;
423 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100424 context_->event_tracker->PushCounter(ts, value, vmstat_strs_id_[key], 0,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000425 RefType::kRefNoRef);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100426}
427
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000428void ProtoTraceParser::ParseCpuTimes(int64_t ts, TraceBlobView cpu_times) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100429 ProtoDecoder decoder(cpu_times.data(), cpu_times.length());
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000430 uint64_t raw_cpu = 0;
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100431 uint32_t value = 0;
432 // Speculate on CPU being first.
433 constexpr auto kCpuFieldTag = protozero::proto_utils::MakeTagVarInt(
434 protos::SysStats::CpuTimes::kCpuIdFieldNumber);
435 if (cpu_times.length() > 2 && cpu_times.data()[0] == kCpuFieldTag &&
436 cpu_times.data()[1] < 0x80) {
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000437 raw_cpu = cpu_times.data()[1];
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100438 } else {
439 if (!PERFETTO_LIKELY((
440 decoder.FindIntField<protos::SysStats::CpuTimes::kCpuIdFieldNumber>(
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000441 &raw_cpu)))) {
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100442 PERFETTO_ELOG("CPU field not found in CpuTimes");
Primiano Tucci0e38a142019-01-07 20:51:09 +0000443 context_->storage->IncrementStats(stats::invalid_cpu_times);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100444 return;
445 }
446 }
447
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000448 int64_t cpu = static_cast<int64_t>(raw_cpu);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100449 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
450 switch (fld.id) {
451 case protos::SysStats::CpuTimes::kUserNsFieldNumber: {
452 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100453 context_->event_tracker->PushCounter(ts, value, cpu_times_user_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000454 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100455 break;
456 }
457 case protos::SysStats::CpuTimes::kUserIceNsFieldNumber: {
458 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100459 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000460 ts, value, cpu_times_user_ice_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100461 break;
462 }
463 case protos::SysStats::CpuTimes::kSystemModeNsFieldNumber: {
464 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100465 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000466 ts, value, cpu_times_system_mode_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100467 break;
468 }
469 case protos::SysStats::CpuTimes::kIdleNsFieldNumber: {
470 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100471 context_->event_tracker->PushCounter(ts, value, cpu_times_idle_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000472 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100473 break;
474 }
475 case protos::SysStats::CpuTimes::kIoWaitNsFieldNumber: {
476 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100477 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000478 ts, value, cpu_times_io_wait_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100479 break;
480 }
481 case protos::SysStats::CpuTimes::kIrqNsFieldNumber: {
482 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100483 context_->event_tracker->PushCounter(ts, value, cpu_times_irq_ns_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000484 cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100485 break;
486 }
487 case protos::SysStats::CpuTimes::kSoftirqNsFieldNumber: {
488 value = fld.as_uint32();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100489 context_->event_tracker->PushCounter(
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000490 ts, value, cpu_times_softirq_ns_id_, cpu, RefType::kRefCpuId);
Isabelle Taylor54ce7052018-10-01 14:00:15 +0100491 break;
492 }
493 default:
494 break;
495 }
496 }
497}
498
Primiano Tuccid933d912018-09-04 09:15:07 +0100499void ProtoTraceParser::ParseProcessTree(TraceBlobView pstree) {
500 ProtoDecoder decoder(pstree.data(), pstree.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100501
Isabelle Taylord80932a2018-06-19 17:00:47 +0100502 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100503 const size_t fld_off = pstree.offset_of(fld.data());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100504 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100505 case protos::ProcessTree::kProcessesFieldNumber: {
506 ParseProcess(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100507 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100508 }
509 case protos::ProcessTree::kThreadsFieldNumber: {
510 ParseThread(pstree.slice(fld_off, fld.size()));
Isabelle Taylord80932a2018-06-19 17:00:47 +0100511 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100512 }
Isabelle Taylord80932a2018-06-19 17:00:47 +0100513 default:
514 break;
515 }
516 }
517 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
518}
519
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000520void ProtoTraceParser::ParseProcessStats(int64_t ts, TraceBlobView stats) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700521 ProtoDecoder decoder(stats.data(), stats.length());
522
523 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
524 const size_t fld_off = stats.offset_of(fld.data());
525 switch (fld.id) {
Lalit Maganti6820abc2019-01-21 11:12:23 +0000526 case protos::ProcessStats::kProcessesFieldNumber: {
Lalit Maganti41c98922019-01-23 19:35:58 +0000527 ParseProcessStatsProcess(ts, stats.slice(fld_off, fld.size()));
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700528 break;
529 }
530 default:
531 break;
532 }
533 }
534 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
535}
536
Lalit Maganti41c98922019-01-23 19:35:58 +0000537void ProtoTraceParser::ParseProcessStatsProcess(int64_t ts,
538 TraceBlobView proc_stat) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700539 ProtoDecoder decoder(proc_stat.data(), proc_stat.length());
540 uint32_t pid = 0;
Lalit Maganti41c98922019-01-23 19:35:58 +0000541
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700542 // Maps a process counter field it to its value.
543 // E.g., 4 := 1024 -> "mem.rss.anon" := 1024.
Lalit Maganti41c98922019-01-23 19:35:58 +0000544 std::array<int64_t, kProcStatsProcessSize> counter_values{};
545 std::array<bool, kProcStatsProcessSize> has_counter{};
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700546
547 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
548 switch (fld.id) {
Lalit Maganti6820abc2019-01-21 11:12:23 +0000549 case protos::ProcessStats::Process::kPidFieldNumber:
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700550 pid = fld.as_uint32();
551 break;
Lalit Maganti41c98922019-01-23 19:35:58 +0000552 default: {
553 bool is_counter_field = fld.id < has_counter.size() &&
554 proc_stats_process_names_[fld.id] != 0;
555 if (is_counter_field) {
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700556 // Memory counters are in KB, keep values in bytes in the trace
557 // processor.
Lalit Maganti41c98922019-01-23 19:35:58 +0000558 counter_values[fld.id] =
559 fld.id == protos::ProcessStats::Process::kOomScoreAdjFieldNumber
560 ? fld.as_int64()
561 : fld.as_int64() * 1024;
562 has_counter[fld.id] = true;
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700563 } else {
Primiano Tucci0e38a142019-01-07 20:51:09 +0000564 context_->storage->IncrementStats(stats::proc_stat_unknown_counters);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700565 }
Lalit Maganti41c98922019-01-23 19:35:58 +0000566 break;
567 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700568 }
569 }
570
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700571 // Skip field_id 0 (invalid) and 1 (pid).
572 for (size_t field_id = 2; field_id < counter_values.size(); field_id++) {
573 if (!has_counter[field_id])
574 continue;
575
576 // Lookup the interned string id from the field name using the
Lalit Maganti41c98922019-01-23 19:35:58 +0000577 // pre-cached |proc_stats_process_names_| map.
578 StringId name = proc_stats_process_names_[field_id];
579 int64_t value = counter_values[field_id];
580
581 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
582 context_->event_tracker->PushCounter(ts, value, name, upid,
583 RefType::kRefUpid);
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700584 }
585
586 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
587}
588
Primiano Tuccid933d912018-09-04 09:15:07 +0100589void ProtoTraceParser::ParseThread(TraceBlobView thread) {
590 ProtoDecoder decoder(thread.data(), thread.length());
Isabelle Taylord80932a2018-06-19 17:00:47 +0100591 uint32_t tid = 0;
592 uint32_t tgid = 0;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100593 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
594 switch (fld.id) {
595 case protos::ProcessTree::Thread::kTidFieldNumber:
596 tid = fld.as_uint32();
597 break;
598 case protos::ProcessTree::Thread::kTgidFieldNumber:
599 tgid = fld.as_uint32();
600 break;
Isabelle Taylord80932a2018-06-19 17:00:47 +0100601 default:
602 break;
603 }
604 }
Isabelle Taylora0a22972018-08-03 12:06:12 +0100605 context_->process_tracker->UpdateThread(tid, tgid);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100606
607 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
608}
609
Primiano Tuccid933d912018-09-04 09:15:07 +0100610void ProtoTraceParser::ParseProcess(TraceBlobView process) {
611 ProtoDecoder decoder(process.data(), process.length());
612
Isabelle Taylord80932a2018-06-19 17:00:47 +0100613 uint32_t pid = 0;
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100614 base::StringView process_name;
Primiano Tuccid933d912018-09-04 09:15:07 +0100615
Isabelle Taylord80932a2018-06-19 17:00:47 +0100616 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
617 switch (fld.id) {
618 case protos::ProcessTree::Process::kPidFieldNumber:
619 pid = fld.as_uint32();
620 break;
621 case protos::ProcessTree::Process::kCmdlineFieldNumber:
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100622 if (process_name.empty())
623 process_name = fld.as_string();
Isabelle Taylord80932a2018-06-19 17:00:47 +0100624 break;
625 default:
626 break;
627 }
628 }
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100629 context_->process_tracker->UpdateProcess(pid, process_name);
Isabelle Taylord80932a2018-06-19 17:00:47 +0100630 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
631}
632
Primiano Tuccid933d912018-09-04 09:15:07 +0100633void ProtoTraceParser::ParseFtracePacket(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000634 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100635 TraceBlobView ftrace) {
636 ProtoDecoder decoder(ftrace.data(), ftrace.length());
Lalit Maganti1d915a62019-01-07 12:10:42 +0000637 uint64_t raw_pid = 0;
638 if (!PERFETTO_LIKELY(
639 (decoder.FindIntField<protos::FtraceEvent::kPidFieldNumber>(
640 &raw_pid)))) {
641 PERFETTO_ELOG("Pid field not found in ftrace packet");
642 return;
643 }
644 uint32_t pid = static_cast<uint32_t>(raw_pid);
645
Lalit Magantidf3e9262018-06-04 17:45:00 +0100646 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
Lalit Maganti1d915a62019-01-07 12:10:42 +0000647 bool is_metadata_field =
648 fld.id == protos::FtraceEvent::kPidFieldNumber ||
649 fld.id == protos::FtraceEvent::kTimestampFieldNumber;
650 if (is_metadata_field)
651 continue;
652
653 const size_t fld_off = ftrace.offset_of(fld.data());
654 if (fld.id == protos::FtraceEvent::kGenericFieldNumber) {
Lalit Magantie87cc812019-01-10 15:20:06 +0000655 ParseGenericFtrace(timestamp, cpu, pid,
656 ftrace.slice(fld_off, fld.size()));
Lalit Maganti1d915a62019-01-07 12:10:42 +0000657 } else {
Lalit Magantie87cc812019-01-10 15:20:06 +0000658 ParseTypedFtraceToRaw(fld.id, timestamp, cpu, pid,
Lalit Maganti1d915a62019-01-07 12:10:42 +0000659 ftrace.slice(fld_off, fld.size()));
660 }
661
Lalit Magantidf3e9262018-06-04 17:45:00 +0100662 switch (fld.id) {
Primiano Tuccid933d912018-09-04 09:15:07 +0100663 case protos::FtraceEvent::kSchedSwitchFieldNumber: {
Primiano Tuccid933d912018-09-04 09:15:07 +0100664 ParseSchedSwitch(cpu, timestamp, ftrace.slice(fld_off, fld.size()));
Lalit Magantidf3e9262018-06-04 17:45:00 +0100665 break;
Primiano Tuccid933d912018-09-04 09:15:07 +0100666 }
Isabelle Taylor14674d42018-09-07 11:33:11 +0100667 case protos::FtraceEvent::kCpuFrequency: {
Isabelle Taylor14674d42018-09-07 11:33:11 +0100668 ParseCpuFreq(timestamp, ftrace.slice(fld_off, fld.size()));
669 break;
670 }
Hector Dearman7b794cc2018-11-30 14:35:30 +0000671 case protos::FtraceEvent::kCpuIdle: {
Hector Dearman7b794cc2018-11-30 14:35:30 +0000672 ParseCpuIdle(timestamp, ftrace.slice(fld_off, fld.size()));
673 break;
674 }
Hector Dearman947f12a2018-09-11 16:50:36 +0100675 case protos::FtraceEvent::kPrintFieldNumber: {
Lalit Magantide6267f2018-11-08 12:35:34 +0000676 ParsePrint(cpu, timestamp, pid, ftrace.slice(fld_off, fld.size()));
Hector Dearman947f12a2018-09-11 16:50:36 +0100677 break;
678 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100679 case protos::FtraceEvent::kRssStatFieldNumber: {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100680 ParseRssStat(timestamp, pid, ftrace.slice(fld_off, fld.size()));
681 break;
682 }
683 case protos::FtraceEvent::kIonHeapGrow: {
Primiano Tucci90cdc852018-12-21 10:29:44 +0100684 ParseIonHeapGrowOrShrink(timestamp, pid,
685 ftrace.slice(fld_off, fld.size()), true);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100686 break;
687 }
688 case protos::FtraceEvent::kIonHeapShrink: {
Primiano Tucci90cdc852018-12-21 10:29:44 +0100689 ParseIonHeapGrowOrShrink(timestamp, pid,
690 ftrace.slice(fld_off, fld.size()), false);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100691 break;
692 }
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000693 case protos::FtraceEvent::kSignalGenerate: {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000694 ParseSignalGenerate(timestamp, ftrace.slice(fld_off, fld.size()));
695 break;
696 }
697 case protos::FtraceEvent::kSignalDeliver: {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000698 ParseSignalDeliver(timestamp, pid, ftrace.slice(fld_off, fld.size()));
699 break;
700 }
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000701 case protos::FtraceEvent::kLowmemoryKill: {
702 ParseLowmemoryKill(timestamp, ftrace.slice(fld_off, fld.size()));
703 break;
704 }
Primiano Tucci44231042018-12-06 21:34:32 +0000705 case protos::FtraceEvent::kOomScoreAdjUpdate: {
Primiano Tucci44231042018-12-06 21:34:32 +0000706 ParseOOMScoreAdjUpdate(timestamp, ftrace.slice(fld_off, fld.size()));
707 break;
708 }
Lalit Magantia824c332019-01-23 17:55:58 +0000709 case protos::FtraceEvent::kMmEventRecordFieldNumber: {
710 ParseMmEventRecordField(timestamp, pid,
711 ftrace.slice(fld_off, fld.size()));
712 break;
713 }
Lalit Magantidf3e9262018-06-04 17:45:00 +0100714 default:
715 break;
716 }
717 }
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000718 // TODO(lalitm): maybe move this to the flush method in the trace processor
719 // once we have it. This may reduce performance in the ArgsTracker though so
720 // needs to be handled carefully.
721 context_->args_tracker->Flush();
722
Lalit Magantidf3e9262018-06-04 17:45:00 +0100723 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
724}
725
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000726void ProtoTraceParser::ParseSignalDeliver(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000727 uint32_t pid,
728 TraceBlobView view) {
729 ProtoDecoder decoder(view.data(), view.length());
730 uint32_t sig = 0;
731 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
732 switch (fld.id) {
733 case protos::SignalDeliverFtraceEvent::kSigFieldNumber:
734 sig = fld.as_uint32();
735 break;
736 }
737 }
738 auto* instants = context_->storage->mutable_instants();
739 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
740 instants->AddInstantEvent(timestamp, signal_deliver_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000741 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000742}
743
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000744// This event has both the pid of the thread that sent the signal and the
745// destination of the signal. Currently storing the pid of the destination.
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000746void ProtoTraceParser::ParseSignalGenerate(int64_t timestamp,
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000747 TraceBlobView view) {
748 ProtoDecoder decoder(view.data(), view.length());
749 uint32_t pid = 0;
750 uint32_t sig = 0;
751 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
752 switch (fld.id) {
753 case protos::SignalGenerateFtraceEvent::kPidFieldNumber:
754 pid = fld.as_uint32();
755 break;
756 case protos::SignalGenerateFtraceEvent::kSigFieldNumber:
757 sig = fld.as_uint32();
758 break;
759 }
760 }
761 auto* instants = context_->storage->mutable_instants();
762 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
763 instants->AddInstantEvent(timestamp, signal_generate_id_, sig, utid,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000764 RefType::kRefUtid);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000765}
766
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000767void ProtoTraceParser::ParseLowmemoryKill(int64_t timestamp,
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000768 TraceBlobView view) {
769 // TODO(taylori): Store the pagecache_size, pagecache_limit and free fields
770 // in an args table
771 ProtoDecoder decoder(view.data(), view.length());
772 uint32_t pid = 0;
773 base::StringView comm;
774 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
775 switch (fld.id) {
776 case protos::LowmemoryKillFtraceEvent::kPidFieldNumber:
777 pid = fld.as_uint32();
778 break;
779 case protos::LowmemoryKillFtraceEvent::kCommFieldNumber:
780 comm = fld.as_string();
781 break;
782 }
783 }
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000784
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000785 // Storing the pid of the event that is lmk-ed.
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000786 auto* instants = context_->storage->mutable_instants();
Lalit Maganti94c522b2019-01-15 00:03:15 +0000787 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
Lalit Magantia93cce32019-02-06 17:45:02 +0000788 uint32_t row = instants->AddInstantEvent(timestamp, lmk_id_, 0, upid,
789 RefType::kRefUtidLookupUpid);
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000790
791 // Store the comm as an arg.
792 RowId row_id = TraceStorage::CreateRowId(TableId::kInstants, row);
793 auto comm_id = context_->storage->InternString(comm);
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +0000794 context_->args_tracker->AddArg(row_id, comm_name_id_, comm_name_id_,
795 Variadic::String(comm_id));
Isabelle Taylor0996dbf2018-11-07 11:33:38 +0000796}
797
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000798void ProtoTraceParser::ParseRssStat(int64_t timestamp,
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100799 uint32_t pid,
800 TraceBlobView view) {
801 ProtoDecoder decoder(view.data(), view.length());
Primiano Tuccibc560992018-12-06 19:11:45 +0000802 const auto kRssStatUnknown = static_cast<uint32_t>(rss_members_.size()) - 1;
803 uint32_t member = kRssStatUnknown;
Primiano Tuccidbe49832018-12-18 19:37:04 +0000804 int64_t size = 0;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100805 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
806 switch (fld.id) {
807 case protos::RssStatFtraceEvent::kMemberFieldNumber:
808 member = fld.as_uint32();
809 break;
810 case protos::RssStatFtraceEvent::kSizeFieldNumber:
Primiano Tuccidbe49832018-12-18 19:37:04 +0000811 size = fld.as_int64();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100812 break;
813 }
814 }
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700815 if (member >= rss_members_.size()) {
Primiano Tucci0e38a142019-01-07 20:51:09 +0000816 context_->storage->IncrementStats(stats::rss_stat_unknown_keys);
Primiano Tuccibc560992018-12-06 19:11:45 +0000817 member = kRssStatUnknown;
Primiano Tuccic9d4a8b2018-10-30 20:19:01 -0700818 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100819 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Lalit Maganti6d2edf62018-11-08 16:36:35 +0000820
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100821 context_->event_tracker->PushCounter(timestamp, size, rss_members_[member],
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000822 utid, RefType::kRefUtidLookupUpid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100823 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
824}
825
Primiano Tucci90cdc852018-12-21 10:29:44 +0100826void ProtoTraceParser::ParseIonHeapGrowOrShrink(int64_t timestamp,
827 uint32_t pid,
828 TraceBlobView view,
829 bool grow) {
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100830 ProtoDecoder decoder(view.data(), view.length());
Primiano Tucci90cdc852018-12-21 10:29:44 +0100831 int64_t total_bytes = 0;
832 int64_t change_bytes = 0;
833 StringId global_name_id = ion_total_unknown_id_;
834 StringId change_name_id = ion_change_unknown_id_;
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100835 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
836 switch (fld.id) {
837 case protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber:
Primiano Tucci90cdc852018-12-21 10:29:44 +0100838 total_bytes = fld.as_int64();
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100839 break;
Primiano Tucci90cdc852018-12-21 10:29:44 +0100840 case protos::IonHeapGrowFtraceEvent::kLenFieldNumber:
841 change_bytes = fld.as_int64() * (grow ? 1 : -1);
842 break;
843 case protos::IonHeapGrowFtraceEvent::kHeapNameFieldNumber: {
844 char counter_name[255];
845 base::StringView heap_name = fld.as_string();
846 snprintf(counter_name, sizeof(counter_name), "mem.ion.%.*s",
847 int(heap_name.size()), heap_name.data());
848 global_name_id = context_->storage->InternString(counter_name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100849
Primiano Tucci90cdc852018-12-21 10:29:44 +0100850 snprintf(counter_name, sizeof(counter_name), "mem.ion_change.%.*s",
851 int(heap_name.size()), heap_name.data());
852 change_name_id = context_->storage->InternString(counter_name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100853 break;
Primiano Tucci90cdc852018-12-21 10:29:44 +0100854 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100855 }
856 }
Primiano Tucci90cdc852018-12-21 10:29:44 +0100857 // Push the global counter.
858 context_->event_tracker->PushCounter(timestamp, total_bytes, global_name_id,
859 0, RefType::kRefNoRef);
860
861 // Push the change counter.
862 // TODO(b/121331269): these should really be instant events. For now we
Primiano Tuccicd37b4d2018-12-21 16:33:32 +0100863 // manually reset them to 0 after 1ns.
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100864 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, pid, 0);
Primiano Tucci90cdc852018-12-21 10:29:44 +0100865 context_->event_tracker->PushCounter(timestamp, change_bytes, change_name_id,
866 utid, RefType::kRefUtid);
Primiano Tuccicd37b4d2018-12-21 16:33:32 +0100867 context_->event_tracker->PushCounter(timestamp + 1, 0, change_name_id, utid,
868 RefType::kRefUtid);
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100869 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
Primiano Tucci90cdc852018-12-21 10:29:44 +0100870
871 // We are reusing the same function for ion_heap_grow and ion_heap_shrink.
872 // It is fine as the arguments are the same, but we need to be sure that the
873 // protobuf field id for both are the same.
874 static_assert(
875 protos::IonHeapGrowFtraceEvent::kTotalAllocatedFieldNumber ==
876 protos::IonHeapShrinkFtraceEvent::kTotalAllocatedFieldNumber &&
877 protos::IonHeapGrowFtraceEvent::kLenFieldNumber ==
878 protos::IonHeapShrinkFtraceEvent::kLenFieldNumber &&
879 protos::IonHeapGrowFtraceEvent::kHeapNameFieldNumber ==
880 protos::IonHeapShrinkFtraceEvent::kHeapNameFieldNumber,
881 "field mismatch");
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100882}
883
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000884void ProtoTraceParser::ParseCpuFreq(int64_t timestamp, TraceBlobView view) {
Isabelle Taylor14674d42018-09-07 11:33:11 +0100885 ProtoDecoder decoder(view.data(), view.length());
886
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100887 uint32_t cpu_affected = 0;
Isabelle Taylor14674d42018-09-07 11:33:11 +0100888 uint32_t new_freq = 0;
889 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
890 switch (fld.id) {
891 case protos::CpuFrequencyFtraceEvent::kCpuIdFieldNumber:
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100892 cpu_affected = fld.as_uint32();
Isabelle Taylor14674d42018-09-07 11:33:11 +0100893 break;
894 case protos::CpuFrequencyFtraceEvent::kStateFieldNumber:
895 new_freq = fld.as_uint32();
896 break;
897 }
898 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100899 context_->event_tracker->PushCounter(timestamp, new_freq, cpu_freq_name_id_,
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000900 cpu_affected, RefType::kRefCpuId);
Isabelle Taylor14674d42018-09-07 11:33:11 +0100901 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
902}
903
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000904void ProtoTraceParser::ParseCpuIdle(int64_t timestamp, TraceBlobView view) {
Hector Dearman7b794cc2018-11-30 14:35:30 +0000905 ProtoDecoder decoder(view.data(), view.length());
906
907 uint32_t cpu_affected = 0;
908 uint32_t new_state = 0;
909 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
910 switch (fld.id) {
911 case protos::CpuIdleFtraceEvent::kCpuIdFieldNumber:
912 cpu_affected = fld.as_uint32();
913 break;
914 case protos::CpuIdleFtraceEvent::kStateFieldNumber:
915 new_state = fld.as_uint32();
916 break;
917 }
918 }
919 context_->event_tracker->PushCounter(timestamp, new_state, cpu_idle_name_id_,
920 cpu_affected, RefType::kRefCpuId);
921 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
922}
923
Primiano Tucci7e330292018-08-24 19:10:52 +0200924void ProtoTraceParser::ParseSchedSwitch(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000925 int64_t timestamp,
Primiano Tuccid933d912018-09-04 09:15:07 +0100926 TraceBlobView sswitch) {
927 ProtoDecoder decoder(sswitch.data(), sswitch.length());
928
Lalit Magantidf3e9262018-06-04 17:45:00 +0100929 uint32_t prev_pid = 0;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000930 int64_t prev_state = 0;
Lalit Magantifde29042018-10-04 13:28:52 +0100931 base::StringView next_comm;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100932 uint32_t next_pid = 0;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000933 int32_t next_prio = 0;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100934 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
935 switch (fld.id) {
936 case protos::SchedSwitchFtraceEvent::kPrevPidFieldNumber:
937 prev_pid = fld.as_uint32();
938 break;
Lalit Maganti35622b72018-06-06 12:03:11 +0100939 case protos::SchedSwitchFtraceEvent::kPrevStateFieldNumber:
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000940 prev_state = fld.as_int64();
Lalit Maganti35622b72018-06-06 12:03:11 +0100941 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100942 case protos::SchedSwitchFtraceEvent::kNextPidFieldNumber:
943 next_pid = fld.as_uint32();
944 break;
Lalit Magantifde29042018-10-04 13:28:52 +0100945 case protos::SchedSwitchFtraceEvent::kNextCommFieldNumber:
946 next_comm = fld.as_string();
947 break;
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000948 case protos::SchedSwitchFtraceEvent::kNextPrioFieldNumber:
949 next_prio = fld.as_int32();
950 break;
Lalit Magantidf3e9262018-06-04 17:45:00 +0100951 default:
952 break;
953 }
954 }
Isabelle Taylora97c5f52018-10-23 17:36:12 +0100955 context_->event_tracker->PushSchedSwitch(cpu, timestamp, prev_pid, prev_state,
Lalit Maganti4af8dd82019-01-16 23:10:21 +0000956 next_pid, next_comm, next_prio);
Lalit Magantidf3e9262018-06-04 17:45:00 +0100957 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
958}
959
Hector Dearman947f12a2018-09-11 16:50:36 +0100960void ProtoTraceParser::ParsePrint(uint32_t,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000961 int64_t timestamp,
Lalit Magantide6267f2018-11-08 12:35:34 +0000962 uint32_t pid,
Hector Dearman947f12a2018-09-11 16:50:36 +0100963 TraceBlobView print) {
964 ProtoDecoder decoder(print.data(), print.length());
965
966 base::StringView buf{};
967 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
968 if (fld.id == protos::PrintFtraceEvent::kBufFieldNumber) {
969 buf = fld.as_string();
970 break;
971 }
972 }
973
974 SystraceTracePoint point{};
975 if (!ParseSystraceTracePoint(buf, &point))
976 return;
977
Hector Dearman947f12a2018-09-11 16:50:36 +0100978 switch (point.phase) {
979 case 'B': {
980 StringId name_id = context_->storage->InternString(point.name);
Ioannis Ilkos21a76182019-01-28 14:05:01 +0000981 context_->slice_tracker->BeginAndroid(timestamp, pid, point.tgid,
Lalit Magantide6267f2018-11-08 12:35:34 +0000982 0 /*cat_id*/, name_id);
Hector Dearman947f12a2018-09-11 16:50:36 +0100983 break;
984 }
985
986 case 'E': {
Ioannis Ilkos21a76182019-01-28 14:05:01 +0000987 context_->slice_tracker->EndAndroid(timestamp, pid, point.tgid);
Hector Dearman947f12a2018-09-11 16:50:36 +0100988 break;
989 }
Isabelle Taylor31e04402018-09-19 12:13:25 +0100990
991 case 'C': {
Lalit Maganti94c522b2019-01-15 00:03:15 +0000992 // LMK events from userspace are hacked as counter events with the "value"
993 // of the counter representing the pid of the killed process which is
994 // reset to 0 once the kill is complete.
995 // Homogenise this with kernel LMK events as an instant event, ignoring
996 // the resets to 0.
997 if (point.name == "kill_one_process") {
998 auto killed_pid = static_cast<uint32_t>(point.value);
999 if (killed_pid != 0) {
1000 UniquePid killed_upid =
1001 context_->process_tracker->UpdateProcess(killed_pid);
1002 context_->storage->mutable_instants()->AddInstantEvent(
1003 timestamp, lmk_id_, 0, killed_upid, RefType::kRefUpid);
1004 }
Hector Dearman8caa2fc2019-01-29 13:56:30 +00001005 // TODO(lalitm): we should not add LMK events to the counters table
Lalit Maganti94c522b2019-01-15 00:03:15 +00001006 // once the UI has support for displaying instants.
1007 }
Hector Dearman8caa2fc2019-01-29 13:56:30 +00001008 // This is per upid on purpose. Some counters are pushed from arbitrary
1009 // threads but are really per process.
1010 UniquePid upid = context_->process_tracker->UpdateProcess(point.tgid);
Isabelle Taylor31e04402018-09-19 12:13:25 +01001011 StringId name_id = context_->storage->InternString(point.name);
Isabelle Taylora97c5f52018-10-23 17:36:12 +01001012 context_->event_tracker->PushCounter(timestamp, point.value, name_id,
Hector Dearman8caa2fc2019-01-29 13:56:30 +00001013 upid, RefType::kRefUpid);
Isabelle Taylor31e04402018-09-19 12:13:25 +01001014 }
Hector Dearman947f12a2018-09-11 16:50:36 +01001015 }
1016 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1017}
1018
Lalit Maganti85ca4a82018-12-07 17:28:02 +00001019void ProtoTraceParser::ParseBatteryCounters(int64_t ts, TraceBlobView battery) {
Primiano Tuccib86e9ca2018-12-03 20:20:11 +01001020 ProtoDecoder decoder(battery.data(), battery.length());
1021 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1022 switch (fld.id) {
1023 case protos::BatteryCounters::kChargeCounterUahFieldNumber:
1024 context_->event_tracker->PushCounter(
1025 ts, fld.as_int64(), batt_charge_id_, 0, RefType::kRefNoRef);
1026 break;
1027 case protos::BatteryCounters::kCapacityPercentFieldNumber:
1028 context_->event_tracker->PushCounter(
1029 ts, static_cast<double>(fld.as_float()), batt_capacity_id_, 0,
1030 RefType::kRefNoRef);
1031 break;
1032 case protos::BatteryCounters::kCurrentUaFieldNumber:
1033 context_->event_tracker->PushCounter(
1034 ts, fld.as_int64(), batt_current_id_, 0, RefType::kRefNoRef);
1035 break;
1036 case protos::BatteryCounters::kCurrentAvgUaFieldNumber:
1037 context_->event_tracker->PushCounter(
1038 ts, fld.as_int64(), batt_current_avg_id_, 0, RefType::kRefNoRef);
1039 break;
1040 default:
1041 break;
1042 }
1043 }
1044 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1045}
1046
Lalit Maganti85ca4a82018-12-07 17:28:02 +00001047void ProtoTraceParser::ParseOOMScoreAdjUpdate(int64_t ts,
Primiano Tucci44231042018-12-06 21:34:32 +00001048 TraceBlobView oom_update) {
1049 ProtoDecoder decoder(oom_update.data(), oom_update.length());
1050 uint32_t pid = 0;
1051 int16_t oom_adj = 0;
1052
1053 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1054 switch (fld.id) {
1055 case protos::OomScoreAdjUpdateFtraceEvent::kOomScoreAdjFieldNumber:
Primiano Tucci90cdc852018-12-21 10:29:44 +01001056 // TODO(b/120618641): The int16_t static cast is required because of
1057 // the linked negative varint encoding bug.
Primiano Tucci44231042018-12-06 21:34:32 +00001058 oom_adj = static_cast<int16_t>(fld.as_int32());
1059 break;
1060 case protos::OomScoreAdjUpdateFtraceEvent::kPidFieldNumber:
1061 pid = fld.as_uint32();
1062 break;
1063 case protos::OomScoreAdjUpdateFtraceEvent::kCommFieldNumber:
1064 default:
1065 break;
1066 }
1067 }
1068 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1069
1070 UniquePid upid = context_->process_tracker->UpdateProcess(pid);
1071 context_->event_tracker->PushCounter(ts, oom_adj, oom_score_adj_id_, upid,
1072 RefType::kRefUpid);
1073}
1074
Lalit Magantia824c332019-01-23 17:55:58 +00001075void ProtoTraceParser::ParseMmEventRecordField(int64_t ts,
1076 uint32_t pid,
1077 TraceBlobView view) {
1078 ProtoDecoder decoder(view.data(), view.length());
1079
1080 uint32_t type = 0;
1081 uint32_t count = 0;
1082 uint32_t max_lat = 0;
1083 uint32_t avg_lat = 0;
1084 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1085 switch (fld.id) {
1086 case protos::MmEventRecordFtraceEvent::kTypeFieldNumber:
1087 type = fld.as_uint32();
1088 break;
1089 case protos::MmEventRecordFtraceEvent::kCountFieldNumber:
1090 count = fld.as_uint32();
1091 break;
1092 case protos::MmEventRecordFtraceEvent::kMaxLatFieldNumber:
1093 max_lat = fld.as_uint32();
1094 break;
1095 case protos::MmEventRecordFtraceEvent::kAvgLatFieldNumber:
1096 avg_lat = fld.as_uint32();
1097 break;
1098 default:
1099 context_->storage->IncrementStats(stats::mm_unknown_counter);
1100 break;
1101 }
1102 }
1103
1104 UniqueTid utid = context_->process_tracker->UpdateThread(ts, pid, 0);
1105 if (type >= mm_event_counter_names_.size()) {
1106 context_->storage->IncrementStats(stats::mm_unknown_type);
1107 return;
1108 }
1109
1110 const auto& counter_names = mm_event_counter_names_[type];
1111 context_->event_tracker->PushCounter(ts, count, counter_names.count, utid,
1112 RefType::kRefUtidLookupUpid);
1113 context_->event_tracker->PushCounter(ts, max_lat, counter_names.max_lat, utid,
1114 RefType::kRefUtidLookupUpid);
1115 context_->event_tracker->PushCounter(ts, avg_lat, counter_names.avg_lat, utid,
1116 RefType::kRefUtidLookupUpid);
1117
1118 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1119}
1120
Lalit Maganti1d915a62019-01-07 12:10:42 +00001121void ProtoTraceParser::ParseGenericFtrace(int64_t timestamp,
Lalit Magantie87cc812019-01-10 15:20:06 +00001122 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +00001123 uint32_t tid,
1124 TraceBlobView view) {
1125 ProtoDecoder decoder(view.data(), view.length());
1126
1127 base::StringView event_name;
1128 if (!PERFETTO_LIKELY((decoder.FindStringField<
1129 protos::GenericFtraceEvent::kEventNameFieldNumber>(
1130 &event_name)))) {
1131 PERFETTO_ELOG("Event name not found in generic ftrace packet");
1132 return;
1133 }
1134
1135 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, tid, 0);
1136 StringId event_id = context_->storage->InternString(std::move(event_name));
1137 RowId row_id = context_->storage->mutable_raw_events()->AddRawEvent(
Lalit Magantie87cc812019-01-10 15:20:06 +00001138 timestamp, event_id, cpu, utid);
Lalit Maganti1d915a62019-01-07 12:10:42 +00001139
1140 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1141 switch (fld.id) {
1142 case protos::GenericFtraceEvent::kFieldFieldNumber:
1143 const size_t fld_off = view.offset_of(fld.data());
1144 ParseGenericFtraceField(row_id, view.slice(fld_off, fld.size()));
1145 break;
1146 }
1147 }
1148}
1149
1150void ProtoTraceParser::ParseGenericFtraceField(RowId generic_row_id,
1151 TraceBlobView view) {
1152 ProtoDecoder decoder(view.data(), view.length());
1153
1154 base::StringView field_name;
1155 if (!PERFETTO_LIKELY((decoder.FindStringField<
1156 protos::GenericFtraceEvent::Field::kNameFieldNumber>(
1157 &field_name)))) {
1158 PERFETTO_ELOG("Event name not found in generic ftrace packet");
1159 return;
1160 }
1161 auto field_name_id = context_->storage->InternString(std::move(field_name));
1162 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1163 switch (fld.id) {
1164 case protos::GenericFtraceEvent::Field::kIntValue:
1165 case protos::GenericFtraceEvent::Field::kUintValue: {
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001166 context_->args_tracker->AddArg(generic_row_id, field_name_id,
1167 field_name_id,
1168 Variadic::Integer(fld.as_integer()));
Lalit Maganti1d915a62019-01-07 12:10:42 +00001169 break;
1170 }
1171 case protos::GenericFtraceEvent::Field::kStrValue: {
1172 StringId value = context_->storage->InternString(fld.as_string());
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001173 context_->args_tracker->AddArg(generic_row_id, field_name_id,
1174 field_name_id, Variadic::String(value));
Lalit Maganti1d915a62019-01-07 12:10:42 +00001175 }
1176 }
1177 }
1178}
1179
1180void ProtoTraceParser::ParseTypedFtraceToRaw(uint32_t ftrace_id,
1181 int64_t timestamp,
Lalit Magantie87cc812019-01-10 15:20:06 +00001182 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +00001183 uint32_t tid,
1184 TraceBlobView view) {
1185 ProtoDecoder decoder(view.data(), view.length());
1186 if (ftrace_id >= GetDescriptorsSize()) {
1187 PERFETTO_DLOG("Event with id: %d does not exist and cannot be parsed.",
1188 ftrace_id);
1189 return;
1190 }
Lalit Magantid86161a2019-02-06 15:07:13 +00001191
Lalit Maganti1d915a62019-01-07 12:10:42 +00001192 MessageDescriptor* m = GetMessageDescriptorForId(ftrace_id);
Lalit Magantid86161a2019-02-06 15:07:13 +00001193 const auto& message_strings = ftrace_message_strings_[ftrace_id];
Lalit Maganti1d915a62019-01-07 12:10:42 +00001194 UniqueTid utid = context_->process_tracker->UpdateThread(timestamp, tid, 0);
1195 RowId raw_event_id = context_->storage->mutable_raw_events()->AddRawEvent(
Lalit Magantid86161a2019-02-06 15:07:13 +00001196 timestamp, message_strings.message_name_id, cpu, utid);
Lalit Maganti1d915a62019-01-07 12:10:42 +00001197 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1198 ProtoSchemaType type = m->fields[fld.id].type;
Lalit Magantid86161a2019-02-06 15:07:13 +00001199 StringId name_id = message_strings.field_name_ids[fld.id];
Lalit Maganti1d915a62019-01-07 12:10:42 +00001200 switch (type) {
1201 case ProtoSchemaType::kUint32:
1202 case ProtoSchemaType::kInt32:
1203 case ProtoSchemaType::kUint64:
1204 case ProtoSchemaType::kInt64:
1205 case ProtoSchemaType::kFixed64:
1206 case ProtoSchemaType::kFixed32:
1207 case ProtoSchemaType::kSfixed32:
1208 case ProtoSchemaType::kSfixed64:
1209 case ProtoSchemaType::kSint32:
1210 case ProtoSchemaType::kSint64:
1211 case ProtoSchemaType::kBool:
1212 case ProtoSchemaType::kEnum: {
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001213 context_->args_tracker->AddArg(raw_event_id, name_id, name_id,
1214 Variadic::Integer(fld.as_integer()));
Lalit Maganti1d915a62019-01-07 12:10:42 +00001215 break;
1216 }
1217 case ProtoSchemaType::kString:
1218 case ProtoSchemaType::kBytes: {
1219 StringId value = context_->storage->InternString(fld.as_string());
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001220 context_->args_tracker->AddArg(raw_event_id, name_id, name_id,
1221 Variadic::String(value));
Lalit Maganti1d915a62019-01-07 12:10:42 +00001222 break;
1223 }
1224 case ProtoSchemaType::kDouble:
1225 case ProtoSchemaType::kFloat: {
Lalit Maganti4fa7c6c2019-02-06 15:06:36 +00001226 context_->args_tracker->AddArg(raw_event_id, name_id, name_id,
1227 Variadic::Real(fld.as_real()));
Lalit Maganti1d915a62019-01-07 12:10:42 +00001228 break;
1229 }
1230 case ProtoSchemaType::kUnknown:
1231 case ProtoSchemaType::kGroup:
1232 case ProtoSchemaType::kMessage:
1233 PERFETTO_DLOG("Could not store %s as a field in args table.",
1234 ProtoSchemaToString(type));
1235 break;
1236 }
1237 }
1238}
1239
Primiano Tuccia270f012019-01-07 20:01:00 +00001240void ProtoTraceParser::ParseClockSnapshot(TraceBlobView packet) {
1241 ProtoDecoder decoder(packet.data(), packet.length());
1242 int64_t clock_boottime = 0;
1243 int64_t clock_monotonic = 0;
1244 int64_t clock_realtime = 0;
1245
1246 // This loop iterates over the "repeated Clock" entries.
1247 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1248 switch (fld.id) {
1249 case protos::ClockSnapshot::kClocksFieldNumber: {
1250 const size_t fld_off = packet.offset_of(fld.data());
1251 auto clk = ParseClockField(packet.slice(fld_off, fld.size()));
1252 switch (clk.first) {
1253 case protos::ClockSnapshot::Clock::BOOTTIME:
1254 clock_boottime = clk.second;
1255 break;
1256 case protos::ClockSnapshot::Clock::REALTIME:
1257 clock_realtime = clk.second;
1258 break;
1259 case protos::ClockSnapshot::Clock::MONOTONIC:
1260 clock_monotonic = clk.second;
1261 break;
1262 }
1263 break;
1264 }
1265 default:
1266 break;
1267 }
1268 }
1269 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1270
1271 // Usually these snapshots come all together.
1272 PERFETTO_DCHECK(clock_boottime > 0 && clock_monotonic > 0 &&
1273 clock_realtime > 0);
1274
1275 if (clock_boottime <= 0) {
1276 PERFETTO_ELOG("ClockSnapshot has an invalid BOOTTIME (%" PRId64 ")",
1277 clock_boottime);
Primiano Tucci0e38a142019-01-07 20:51:09 +00001278 context_->storage->IncrementStats(stats::invalid_clock_snapshots);
Primiano Tuccia270f012019-01-07 20:01:00 +00001279 return;
1280 }
1281
1282 auto* ct = context_->clock_tracker.get();
1283
1284 // |clock_boottime| is used as the reference trace time.
1285 ct->SyncClocks(ClockDomain::kBootTime, clock_boottime, clock_boottime);
1286
1287 if (clock_monotonic > 0)
1288 ct->SyncClocks(ClockDomain::kMonotonic, clock_monotonic, clock_boottime);
1289
1290 if (clock_realtime > 0)
1291 ct->SyncClocks(ClockDomain::kRealTime, clock_realtime, clock_boottime);
1292}
1293
1294std::pair<int, int64_t> ProtoTraceParser::ParseClockField(
1295 TraceBlobView packet) {
1296 ProtoDecoder decoder(packet.data(), packet.length());
1297 int type = protos::ClockSnapshot::Clock::UNKNOWN;
1298 int64_t value = -1;
1299
1300 // This loop iterates over the |type| and |timestamp| field of each
1301 // clock snapshot.
1302 for (auto fld = decoder.ReadField(); fld.id; fld = decoder.ReadField()) {
1303 switch (fld.id) {
1304 case protos::ClockSnapshot::Clock::kTypeFieldNumber:
1305 type = fld.as_int32();
1306 break;
1307 case protos::ClockSnapshot::Clock::kTimestampFieldNumber:
1308 value = fld.as_int64();
1309 break;
1310 }
1311 }
1312 return std::make_pair(type, value);
1313}
1314
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001315void ProtoTraceParser::ParseAndroidLogPacket(TraceBlobView packet) {
1316 ProtoDecoder decoder(packet.data(), packet.length());
1317 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1318 switch (fld.id) {
1319 case protos::AndroidLogPacket::kEventsFieldNumber: {
1320 const size_t fld_off = packet.offset_of(fld.data());
1321 ParseAndroidLogEvent(packet.slice(fld_off, fld.size()));
1322 break;
1323 }
Primiano Tucci0e38a142019-01-07 20:51:09 +00001324 case protos::AndroidLogPacket::kStatsFieldNumber: {
1325 const size_t fld_off = packet.offset_of(fld.data());
1326 ParseAndroidLogStats(packet.slice(fld_off, fld.size()));
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001327 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001328 }
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001329 }
1330 }
1331 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1332}
1333
1334void ProtoTraceParser::ParseAndroidLogEvent(TraceBlobView event) {
1335 // TODO(primiano): Add events and non-stringified fields to the "raw" table.
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001336 ProtoDecoder decoder(event.data(), event.length());
1337 int64_t ts = 0;
1338 uint32_t pid = 0;
1339 uint32_t tid = 0;
1340 uint8_t prio = 0;
1341 StringId tag_id = 0;
1342 StringId msg_id = 0;
1343 char arg_msg[4096];
1344 char* arg_str = &arg_msg[0];
1345 *arg_str = '\0';
1346 auto arg_avail = [&arg_msg, &arg_str]() {
1347 return sizeof(arg_msg) - static_cast<size_t>(arg_str - arg_msg);
1348 };
1349
1350 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1351 switch (fld.id) {
1352 case protos::AndroidLogPacket::LogEvent::kPidFieldNumber:
1353 pid = fld.as_uint32();
1354 break;
1355 case protos::AndroidLogPacket::LogEvent::kTidFieldNumber:
1356 tid = fld.as_uint32();
1357 break;
1358 case protos::AndroidLogPacket::LogEvent::kTimestampFieldNumber:
1359 ts = fld.as_int64();
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001360 break;
1361 case protos::AndroidLogPacket::LogEvent::kPrioFieldNumber:
1362 prio = static_cast<uint8_t>(fld.as_uint32());
1363 break;
1364 case protos::AndroidLogPacket::LogEvent::kTagFieldNumber:
1365 tag_id = context_->storage->InternString(fld.as_string());
1366 break;
1367 case protos::AndroidLogPacket::LogEvent::kMessageFieldNumber:
1368 msg_id = context_->storage->InternString(fld.as_string());
1369 break;
1370 case protos::AndroidLogPacket::LogEvent::kArgsFieldNumber: {
1371 const size_t fld_off = event.offset_of(fld.data());
1372 TraceBlobView arg_data = event.slice(fld_off, fld.size());
1373 ParseAndroidLogBinaryArg(std::move(arg_data), &arg_str, arg_avail());
1374 break;
1375 }
1376 default:
1377 break;
1378 }
1379 }
1380 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1381
1382 if (prio == 0)
1383 prio = protos::AndroidLogPriority::PRIO_INFO;
1384
1385 if (arg_str != &arg_msg[0]) {
1386 PERFETTO_DCHECK(!msg_id);
1387 // Skip the first space char (" foo=1 bar=2" -> "foo=1 bar=2").
1388 msg_id = context_->storage->InternString(&arg_msg[1]);
1389 }
1390 UniquePid utid = tid ? context_->process_tracker->UpdateThread(tid, pid) : 0;
Hector Dearmanba43f602019-01-29 14:36:11 +00001391 base::Optional<int64_t> opt_trace_time =
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001392 context_->clock_tracker->ToTraceTime(ClockDomain::kRealTime, ts);
Hector Dearmanba43f602019-01-29 14:36:11 +00001393 if (!opt_trace_time)
1394 return;
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001395
1396 // Log events are NOT required to be sorted by trace_time. The virtual table
1397 // will take care of sorting on-demand.
Hector Dearmanba43f602019-01-29 14:36:11 +00001398 context_->storage->mutable_android_log()->AddLogEvent(
1399 opt_trace_time.value(), utid, prio, tag_id, msg_id);
Primiano Tucci2c761ef2019-01-07 20:20:46 +00001400}
1401
1402void ProtoTraceParser::ParseAndroidLogBinaryArg(TraceBlobView arg,
1403 char** str,
1404 size_t avail) {
1405 ProtoDecoder decoder(arg.data(), arg.length());
1406 for (auto fld = decoder.ReadField(); fld.id; fld = decoder.ReadField()) {
1407 switch (fld.id) {
1408 case protos::AndroidLogPacket::LogEvent::Arg::kNameFieldNumber: {
1409 base::StringView name = fld.as_string();
1410 *str += snprintf(*str, avail, " %.*s=", static_cast<int>(name.size()),
1411 name.data());
1412 break;
1413 }
1414 case protos::AndroidLogPacket::LogEvent::Arg::kStringValueFieldNumber: {
1415 base::StringView val = fld.as_string();
1416 *str += snprintf(*str, avail, "\"%.*s\"", static_cast<int>(val.size()),
1417 val.data());
1418 break;
1419 }
1420 case protos::AndroidLogPacket::LogEvent::Arg::kIntValueFieldNumber:
1421 *str += snprintf(*str, avail, "%" PRId64, fld.as_int64());
1422 break;
1423 case protos::AndroidLogPacket::LogEvent::Arg::kFloatValueFieldNumber:
1424 *str +=
1425 snprintf(*str, avail, "%f", static_cast<double>(fld.as_float()));
1426 break;
1427 }
1428 }
1429}
1430
Primiano Tucci0e38a142019-01-07 20:51:09 +00001431void ProtoTraceParser::ParseAndroidLogStats(TraceBlobView packet) {
1432 ProtoDecoder decoder(packet.data(), packet.length());
1433 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1434 switch (fld.id) {
1435 case protos::AndroidLogPacket::Stats::kNumFailedFieldNumber:
1436 context_->storage->SetStats(stats::android_log_num_failed,
1437 fld.as_int64());
1438 break;
1439 case protos::AndroidLogPacket::Stats::kNumSkippedFieldNumber:
1440 context_->storage->SetStats(stats::android_log_num_skipped,
1441 fld.as_int64());
1442 break;
1443 case protos::AndroidLogPacket::Stats::kNumTotalFieldNumber:
1444 context_->storage->SetStats(stats::android_log_num_total,
1445 fld.as_int64());
1446 break;
1447 }
1448 }
1449 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1450}
1451
1452void ProtoTraceParser::ParseTraceStats(TraceBlobView packet) {
1453 ProtoDecoder decoder(packet.data(), packet.length());
1454 int buf_num = 0;
1455 auto* storage = context_->storage.get();
1456 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1457 switch (fld.id) {
1458 case protos::TraceStats::kProducersConnectedFieldNumber:
1459 storage->SetStats(stats::traced_producers_connected, fld.as_int64());
1460 break;
1461 case protos::TraceStats::kProducersSeenFieldNumber:
1462 storage->SetStats(stats::traced_producers_seen, fld.as_int64());
1463 break;
1464 case protos::TraceStats::kDataSourcesRegisteredFieldNumber:
1465 storage->SetStats(stats::traced_data_sources_registered,
1466 fld.as_int64());
1467 break;
1468 case protos::TraceStats::kDataSourcesSeenFieldNumber:
1469 storage->SetStats(stats::traced_data_sources_seen, fld.as_int64());
1470 break;
1471 case protos::TraceStats::kTracingSessionsFieldNumber:
1472 storage->SetStats(stats::traced_tracing_sessions, fld.as_int64());
1473 break;
1474 case protos::TraceStats::kTotalBuffersFieldNumber:
1475 storage->SetStats(stats::traced_total_buffers, fld.as_int64());
1476 break;
1477 case protos::TraceStats::kBufferStatsFieldNumber: {
1478 const size_t fld_off = packet.offset_of(fld.data());
1479 TraceBlobView buf_data = packet.slice(fld_off, fld.size());
1480 ProtoDecoder buf_d(buf_data.data(), buf_data.length());
1481 for (auto fld2 = buf_d.ReadField(); fld2.id; fld2 = buf_d.ReadField()) {
1482 switch (fld2.id) {
Eric Secklerbd8aae52019-01-28 08:57:31 +00001483 case protos::TraceStats::BufferStats::kBufferSizeFieldNumber:
1484 storage->SetIndexedStats(stats::traced_buf_buffer_size, buf_num,
1485 fld2.as_int64());
1486 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001487 case protos::TraceStats::BufferStats::kBytesWrittenFieldNumber:
1488 storage->SetIndexedStats(stats::traced_buf_bytes_written, buf_num,
1489 fld2.as_int64());
1490 break;
Eric Secklerbd8aae52019-01-28 08:57:31 +00001491 case protos::TraceStats::BufferStats::kBytesOverwrittenFieldNumber:
1492 storage->SetIndexedStats(stats::traced_buf_bytes_overwritten,
1493 buf_num, fld2.as_int64());
1494 break;
1495 case protos::TraceStats::BufferStats::kBytesReadFieldNumber:
1496 storage->SetIndexedStats(stats::traced_buf_bytes_read, buf_num,
1497 fld2.as_int64());
1498 break;
1499 case protos::TraceStats::BufferStats::
1500 kPaddingBytesWrittenFieldNumber:
1501 storage->SetIndexedStats(stats::traced_buf_padding_bytes_written,
1502 buf_num, fld2.as_int64());
1503 break;
1504 case protos::TraceStats::BufferStats::
1505 kPaddingBytesClearedFieldNumber:
1506 storage->SetIndexedStats(stats::traced_buf_padding_bytes_cleared,
1507 buf_num, fld2.as_int64());
1508 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001509 case protos::TraceStats::BufferStats::kChunksWrittenFieldNumber:
1510 storage->SetIndexedStats(stats::traced_buf_chunks_written,
1511 buf_num, fld2.as_int64());
1512 break;
Stephen Nuskod13fdf82019-01-15 11:22:58 +00001513 case protos::TraceStats::BufferStats::kChunksRewrittenFieldNumber:
1514 storage->SetIndexedStats(stats::traced_buf_chunks_rewritten,
1515 buf_num, fld2.as_int64());
1516 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001517 case protos::TraceStats::BufferStats::kChunksOverwrittenFieldNumber:
1518 storage->SetIndexedStats(stats::traced_buf_chunks_overwritten,
1519 buf_num, fld2.as_int64());
1520 break;
Primiano Tuccib45a69b2019-01-25 14:32:10 +00001521 case protos::TraceStats::BufferStats::kChunksDiscardedFieldNumber:
1522 storage->SetIndexedStats(stats::traced_buf_chunks_discarded,
1523 buf_num, fld2.as_int64());
1524 break;
Eric Secklerbd8aae52019-01-28 08:57:31 +00001525 case protos::TraceStats::BufferStats::kChunksReadFieldNumber:
1526 storage->SetIndexedStats(stats::traced_buf_chunks_read, buf_num,
1527 fld2.as_int64());
1528 break;
Stephen Nuskod13fdf82019-01-15 11:22:58 +00001529 case protos::TraceStats::BufferStats::
1530 kChunksCommittedOutOfOrderFieldNumber:
1531 storage->SetIndexedStats(
1532 stats::traced_buf_chunks_committed_out_of_order, buf_num,
1533 fld2.as_int64());
1534 break;
Primiano Tucci0e38a142019-01-07 20:51:09 +00001535 case protos::TraceStats::BufferStats::kWriteWrapCountFieldNumber:
1536 storage->SetIndexedStats(stats::traced_buf_write_wrap_count,
1537 buf_num, fld2.as_int64());
1538 break;
1539 case protos::TraceStats::BufferStats::kPatchesSucceededFieldNumber:
1540 storage->SetIndexedStats(stats::traced_buf_patches_succeeded,
1541 buf_num, fld2.as_int64());
1542 break;
1543 case protos::TraceStats::BufferStats::kPatchesFailedFieldNumber:
1544 storage->SetIndexedStats(stats::traced_buf_patches_failed,
1545 buf_num, fld2.as_int64());
1546 break;
1547 case protos::TraceStats::BufferStats::
1548 kReadaheadsSucceededFieldNumber:
1549 storage->SetIndexedStats(stats::traced_buf_readaheads_succeeded,
1550 buf_num, fld2.as_int64());
1551 break;
1552 case protos::TraceStats::BufferStats::kReadaheadsFailedFieldNumber:
1553 storage->SetIndexedStats(stats::traced_buf_readaheads_failed,
1554 buf_num, fld2.as_int64());
1555 break;
1556 }
1557 } // for (buf_fld)
1558 buf_num++;
1559 break;
1560 }
1561 default:
1562 break;
1563 }
1564 }
1565 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1566}
1567
1568void ProtoTraceParser::ParseFtraceStats(TraceBlobView packet) {
1569 ProtoDecoder decoder(packet.data(), packet.length());
1570 size_t phase = 0;
1571 auto* storage = context_->storage.get();
1572 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1573 switch (fld.id) {
1574 case protos::FtraceStats::kPhaseFieldNumber:
1575 phase = fld.int_value == protos::FtraceStats_Phase_END_OF_TRACE ? 1 : 0;
1576
1577 // This code relies on the fact that each ftrace_cpu_XXX_end event is
1578 // just after the corresponding ftrace_cpu_XXX_begin event.
1579 static_assert(stats::ftrace_cpu_read_events_end -
1580 stats::ftrace_cpu_read_events_begin ==
1581 1 &&
1582 stats::ftrace_cpu_entries_end -
1583 stats::ftrace_cpu_entries_begin ==
1584 1,
1585 "ftrace_cpu_XXX stats definition are messed up");
1586 break;
1587 case protos::FtraceStats::kCpuStatsFieldNumber: {
1588 const size_t fld_off = packet.offset_of(fld.data());
1589 TraceBlobView cpu_data = packet.slice(fld_off, fld.size());
1590 ProtoDecoder cpu_d(cpu_data.data(), cpu_data.length());
1591 int cpu_num = -1;
1592 for (auto fld2 = cpu_d.ReadField(); fld2.id; fld2 = cpu_d.ReadField()) {
1593 switch (fld2.id) {
1594 case protos::FtraceCpuStats::kCpuFieldNumber:
1595 cpu_num = fld2.as_int32();
1596 break;
1597 case protos::FtraceCpuStats::kEntriesFieldNumber:
1598 storage->SetIndexedStats(stats::ftrace_cpu_entries_begin + phase,
1599 cpu_num, fld2.as_int64());
1600 break;
1601 case protos::FtraceCpuStats::kOverrunFieldNumber:
1602 storage->SetIndexedStats(stats::ftrace_cpu_overrun_begin + phase,
1603 cpu_num, fld2.as_int64());
1604 break;
1605 case protos::FtraceCpuStats::kCommitOverrunFieldNumber:
1606 storage->SetIndexedStats(
1607 stats::ftrace_cpu_commit_overrun_begin + phase, cpu_num,
1608 fld2.as_int64());
1609 break;
1610 case protos::FtraceCpuStats::kBytesReadFieldNumber:
1611 storage->SetIndexedStats(
1612 stats::ftrace_cpu_bytes_read_begin + phase, cpu_num,
1613 fld2.as_int64());
1614 break;
1615 case protos::FtraceCpuStats::kOldestEventTsFieldNumber:
1616 storage->SetIndexedStats(
1617 stats::ftrace_cpu_oldest_event_ts_begin + phase, cpu_num,
1618 static_cast<int64_t>(fld2.as_double() * 1e9));
1619 break;
1620 case protos::FtraceCpuStats::kNowTsFieldNumber:
1621 storage->SetIndexedStats(
1622 stats::ftrace_cpu_now_ts_begin + phase, cpu_num,
1623 static_cast<int64_t>(fld2.as_double() * 1e9));
1624 break;
1625 case protos::FtraceCpuStats::kDroppedEventsFieldNumber:
1626 storage->SetIndexedStats(
1627 stats::ftrace_cpu_dropped_events_begin + phase, cpu_num,
1628 fld2.as_int64());
1629 break;
1630 case protos::FtraceCpuStats::kReadEventsFieldNumber:
1631 storage->SetIndexedStats(
1632 stats::ftrace_cpu_read_events_begin + phase, cpu_num,
1633 fld2.as_int64());
1634 break;
1635 }
1636 } // for (buf_fld)
1637 break;
1638 }
1639 default:
1640 break;
1641 }
1642 }
1643 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1644}
1645
Hector Dearmandd639792019-01-31 15:04:59 +00001646void ProtoTraceParser::ParseProfilePacket(TraceBlobView packet) {
1647 ProtoDecoder decoder(packet.data(), packet.length());
1648 for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
1649 switch (fld.id) {
1650 case protos::ProfilePacket::kStringsFieldNumber: {
1651 const size_t fld_off = packet.offset_of(fld.data());
1652 TraceBlobView nestedPacket = packet.slice(fld_off, fld.size());
1653 ProtoDecoder nested(nestedPacket.data(), nestedPacket.length());
1654 for (auto sub = nested.ReadField(); sub.id != 0;
1655 sub = nested.ReadField()) {
1656 switch (sub.id) {
1657 case protos::ProfilePacket::InternedString::kIdFieldNumber: {
1658 break;
1659 }
1660 case protos::ProfilePacket::InternedString::kStrFieldNumber: {
1661 context_->storage->InternString(sub.as_string());
1662 break;
1663 }
1664 }
1665 }
1666 break;
1667 }
1668 case protos::ProfilePacket::kFramesFieldNumber: {
1669 break;
1670 }
1671 case protos::ProfilePacket::kCallstacksFieldNumber: {
1672 break;
1673 }
1674 case protos::ProfilePacket::kMappingsFieldNumber: {
1675 break;
1676 }
1677 case protos::ProfilePacket::kProcessDumpsFieldNumber: {
1678 break;
1679 }
1680 case protos::ProfilePacket::kContinuedFieldNumber: {
1681 bool continued = fld.as_bool();
1682 base::ignore_result(continued);
1683 break;
1684 }
1685 case protos::ProfilePacket::kIndexFieldNumber: {
1686 int64_t index = fld.as_int64();
1687 base::ignore_result(index);
1688 break;
1689 }
1690 }
1691 }
1692 PERFETTO_DCHECK(decoder.IsEndOfBuffer());
1693}
1694
Lalit Maganti93b76362018-06-01 03:03:58 +01001695} // namespace trace_processor
1696} // namespace perfetto