blob: a13a2f6a117e0931803fc2b70b0bc131c1b62350 [file] [log] [blame]
Primiano Tucci0d72a312018-08-07 14:42:45 +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
17#include "src/trace_processor/json_trace_parser.h"
18
Hector Dearmane690b2d2018-11-14 10:57:02 +000019#include <inttypes.h>
Primiano Tucci0d72a312018-08-07 14:42:45 +010020#include <json/reader.h>
21#include <json/value.h>
Primiano Tuccib75dcee2018-08-08 12:21:36 +010022
23#include <limits>
Primiano Tucci0d72a312018-08-07 14:42:45 +010024#include <string>
25
26#include "perfetto/base/build_config.h"
27#include "perfetto/base/logging.h"
Deepanjan Roy01994ca2019-04-02 11:05:34 -070028#include "perfetto/base/string_view.h"
Primiano Tucci0d72a312018-08-07 14:42:45 +010029#include "perfetto/base/utils.h"
Deepanjan Roy01994ca2019-04-02 11:05:34 -070030#include "src/trace_processor/json_trace_utils.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
Primiano Tucci7c7f5f52019-01-15 21:47:04 +000035#if !PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD)
Primiano Tucci0d72a312018-08-07 14:42:45 +010036#error The JSON trace parser is supported only in the standalone build for now.
37#endif
38
39namespace perfetto {
40namespace trace_processor {
Hector Dearmane690b2d2018-11-14 10:57:02 +000041
Primiano Tucci7e330292018-08-24 19:10:52 +020042JsonTraceParser::JsonTraceParser(TraceProcessorContext* context)
43 : context_(context) {}
Primiano Tucci0d72a312018-08-07 14:42:45 +010044
45JsonTraceParser::~JsonTraceParser() = default;
46
Deepanjan Roy01994ca2019-04-02 11:05:34 -070047void JsonTraceParser::ParseFtracePacket(uint32_t,
48 int64_t,
49 TraceSorter::TimestampedTracePiece) {
50 PERFETTO_FATAL("Json Trace Parser cannot handle ftrace packets.");
51}
Primiano Tucci0d72a312018-08-07 14:42:45 +010052
Deepanjan Roy01994ca2019-04-02 11:05:34 -070053void JsonTraceParser::ParseTracePacket(int64_t timestamp,
54 TraceSorter::TimestampedTracePiece ttp) {
55 PERFETTO_DCHECK(ttp.json_value != nullptr);
56 const Json::Value& value = *(ttp.json_value);
Primiano Tucci0d72a312018-08-07 14:42:45 +010057
58 ProcessTracker* procs = context_->process_tracker.get();
59 TraceStorage* storage = context_->storage.get();
Hector Dearman947f12a2018-09-11 16:50:36 +010060 SliceTracker* slice_tracker = context_->slice_tracker.get();
Primiano Tucci0d72a312018-08-07 14:42:45 +010061
Deepanjan Roy01994ca2019-04-02 11:05:34 -070062 auto& ph = value["ph"];
63 if (!ph.isString())
64 return;
65 char phase = *ph.asCString();
66
67 base::Optional<uint32_t> opt_pid;
68 base::Optional<uint32_t> opt_tid;
69
70 if (value.isMember("pid"))
71 opt_pid = json_trace_utils::CoerceToUint32(value["pid"]);
72 if (value.isMember("tid"))
73 opt_tid = json_trace_utils::CoerceToUint32(value["tid"]);
74
75 uint32_t pid = opt_pid.value_or(0);
76 uint32_t tid = opt_tid.value_or(pid);
77
78 base::StringView cat = value.isMember("cat")
79 ? base::StringView(value["cat"].asCString())
80 : base::StringView();
81 base::StringView name = value.isMember("name")
82 ? base::StringView(value["name"].asCString())
83 : base::StringView();
84
85 StringId cat_id = storage->InternString(cat);
86 StringId name_id = storage->InternString(name);
87 UniqueTid utid = procs->UpdateThread(tid, pid);
88
89 switch (phase) {
90 case 'B': { // TRACE_EVENT_BEGIN.
91 slice_tracker->Begin(timestamp, utid, cat_id, name_id);
Primiano Tucci0d72a312018-08-07 14:42:45 +010092 break;
Deepanjan Roy01994ca2019-04-02 11:05:34 -070093 }
94 case 'E': { // TRACE_EVENT_END.
95 slice_tracker->End(timestamp, utid, cat_id, name_id);
96 break;
97 }
98 case 'X': { // TRACE_EVENT (scoped event).
99 base::Optional<int64_t> opt_dur =
100 json_trace_utils::CoerceToNs(value["dur"]);
101 if (!opt_dur.has_value())
102 return;
103 slice_tracker->Scoped(timestamp, utid, cat_id, name_id, opt_dur.value());
104 break;
105 }
106 case 'M': { // Metadata events (process and thread names).
107 if (strcmp(value["name"].asCString(), "thread_name") == 0) {
108 const char* thread_name = value["args"]["name"].asCString();
109 auto thrad_name_id = context_->storage->InternString(thread_name);
110 procs->UpdateThread(timestamp, tid, thrad_name_id);
Primiano Tucci0d72a312018-08-07 14:42:45 +0100111 break;
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100112 }
Deepanjan Roy01994ca2019-04-02 11:05:34 -0700113 if (strcmp(value["name"].asCString(), "process_name") == 0) {
114 const char* proc_name = value["args"]["name"].asCString();
115 procs->UpdateProcess(pid, base::nullopt, proc_name);
Primiano Tucci0d72a312018-08-07 14:42:45 +0100116 break;
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100117 }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100118 }
119 }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100120}
121
Primiano Tucci0d72a312018-08-07 14:42:45 +0100122} // namespace trace_processor
123} // namespace perfetto