1 /*
2 * Copyright (C) 2019 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/importers/common/metadata_tracker.h"
18
19 #include "perfetto/ext/base/crash_keys.h"
20 #include "src/trace_processor/importers/common/process_tracker.h"
21 #include "src/trace_processor/storage/metadata.h"
22 #include "src/trace_processor/types/trace_processor_context.h"
23
24 namespace perfetto {
25 namespace trace_processor {
26
27 namespace {
28
29 base::CrashKey g_crash_key_uuid("trace_uuid");
30
31 }
32
MetadataTracker(TraceStorage * storage)33 MetadataTracker::MetadataTracker(TraceStorage* storage) : storage_(storage) {
34 for (uint32_t i = 0; i < kNumKeys; ++i) {
35 key_ids_[i] = storage->InternString(metadata::kNames[i]);
36 }
37 for (uint32_t i = 0; i < kNumKeyTypes; ++i) {
38 key_type_ids_[i] = storage->InternString(metadata::kKeyTypeNames[i]);
39 }
40 }
41
SetMetadata(metadata::KeyId key,Variadic value)42 MetadataId MetadataTracker::SetMetadata(metadata::KeyId key, Variadic value) {
43 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
44 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
45
46 // When the trace_uuid is set, store a copy in a crash key, so in case of
47 // a crash in the pipelines we can tell which trace caused the crash.
48 if (key == metadata::trace_uuid && value.type == Variadic::kString) {
49 auto uuid_string_view = storage_->GetString(value.string_value);
50 g_crash_key_uuid.Set(uuid_string_view);
51 }
52
53 auto* metadata_table = storage_->mutable_metadata_table();
54 uint32_t key_idx = static_cast<uint32_t>(key);
55 std::optional<uint32_t> opt_row =
56 metadata_table->name().IndexOf(metadata::kNames[key_idx]);
57 if (opt_row) {
58 WriteValue(*opt_row, value);
59 return metadata_table->id()[*opt_row];
60 }
61
62 tables::MetadataTable::Row row;
63 row.name = key_ids_[key_idx];
64 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
65
66 auto id_and_row = metadata_table->Insert(row);
67 WriteValue(id_and_row.row, value);
68 return id_and_row.id;
69 }
70
GetMetadata(metadata::KeyId key)71 SqlValue MetadataTracker::GetMetadata(metadata::KeyId key) {
72 // KeyType::kMulti not yet supported by this method:
73 PERFETTO_CHECK(metadata::kKeyTypes[key] == metadata::KeyType::kSingle);
74
75 auto* metadata_table = storage_->mutable_metadata_table();
76 uint32_t key_idx = static_cast<uint32_t>(key);
77 uint32_t row =
78 metadata_table->name().IndexOf(metadata::kNames[key_idx]).value();
79
80 auto value_type = metadata::kValueTypes[key];
81 switch (value_type) {
82 case Variadic::kInt:
83 return metadata_table->mutable_int_value()->Get(row);
84 case Variadic::kString:
85 return metadata_table->mutable_str_value()->Get(row);
86 case Variadic::kNull:
87 return SqlValue();
88 case Variadic::kJson:
89 case Variadic::kUint:
90 case Variadic::kPointer:
91 case Variadic::kReal:
92 case Variadic::kBool:
93 PERFETTO_FATAL("Invalid metadata value type %zu", value_type);
94 }
95 PERFETTO_FATAL("For GCC");
96 }
97
AppendMetadata(metadata::KeyId key,Variadic value)98 MetadataId MetadataTracker::AppendMetadata(metadata::KeyId key,
99 Variadic value) {
100 PERFETTO_DCHECK(key < metadata::kNumKeys);
101 PERFETTO_DCHECK(metadata::kKeyTypes[key] == metadata::KeyType::kMulti);
102 PERFETTO_DCHECK(value.type == metadata::kValueTypes[key]);
103
104 uint32_t key_idx = static_cast<uint32_t>(key);
105 tables::MetadataTable::Row row;
106 row.name = key_ids_[key_idx];
107 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kMulti)];
108
109 auto* metadata_table = storage_->mutable_metadata_table();
110 auto id_and_row = metadata_table->Insert(row);
111 WriteValue(id_and_row.row, value);
112 return id_and_row.id;
113 }
114
SetDynamicMetadata(StringId key,Variadic value)115 MetadataId MetadataTracker::SetDynamicMetadata(StringId key, Variadic value) {
116 tables::MetadataTable::Row row;
117 row.name = key;
118 row.key_type = key_type_ids_[static_cast<size_t>(metadata::KeyType::kSingle)];
119
120 auto* metadata_table = storage_->mutable_metadata_table();
121 auto id_and_row = metadata_table->Insert(row);
122 WriteValue(id_and_row.row, value);
123 return id_and_row.id;
124 }
125
WriteValue(uint32_t row,Variadic value)126 void MetadataTracker::WriteValue(uint32_t row, Variadic value) {
127 auto* metadata_table = storage_->mutable_metadata_table();
128 switch (value.type) {
129 case Variadic::Type::kInt:
130 metadata_table->mutable_int_value()->Set(row, value.int_value);
131 break;
132 case Variadic::Type::kString:
133 metadata_table->mutable_str_value()->Set(row, value.string_value);
134 break;
135 case Variadic::Type::kJson:
136 metadata_table->mutable_str_value()->Set(row, value.json_value);
137 break;
138 case Variadic::Type::kBool:
139 case Variadic::Type::kPointer:
140 case Variadic::Type::kUint:
141 case Variadic::Type::kReal:
142 case Variadic::Type::kNull:
143 PERFETTO_FATAL("Unsupported value type");
144 }
145 }
146
147 } // namespace trace_processor
148 } // namespace perfetto
149