• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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