1 /* 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 #ifndef SRC_TRACE_PROCESSOR_TRACE_PROCESSOR_IMPL_H_ 18 #define SRC_TRACE_PROCESSOR_TRACE_PROCESSOR_IMPL_H_ 19 20 #include <sqlite3.h> 21 #include <atomic> 22 #include <functional> 23 #include <memory> 24 #include <vector> 25 26 #include "perfetto/base/string_view.h" 27 #include "perfetto/trace_processor/basic_types.h" 28 #include "perfetto/trace_processor/trace_processor.h" 29 #include "src/trace_processor/scoped_db.h" 30 #include "src/trace_processor/trace_processor_context.h" 31 32 namespace perfetto { 33 34 namespace trace_processor { 35 36 enum TraceType { 37 kUnknownTraceType, 38 kProtoTraceType, 39 kProtoWithTrackEventsTraceType, 40 kJsonTraceType, 41 kFuchsiaTraceType, 42 }; 43 44 TraceType GuessTraceType(const uint8_t* data, size_t size); 45 46 // Coordinates the loading of traces from an arbitrary source and allows 47 // execution of SQL queries on the events in these traces. 48 class TraceProcessorImpl : public TraceProcessor { 49 public: 50 explicit TraceProcessorImpl(const Config&); 51 52 ~TraceProcessorImpl() override; 53 54 bool Parse(std::unique_ptr<uint8_t[]>, size_t) override; 55 56 void NotifyEndOfFile() override; 57 58 Iterator ExecuteQuery(const std::string& sql, 59 int64_t time_queued = 0) override; 60 61 int ComputeMetric(const std::vector<std::string>& metric_names, 62 std::vector<uint8_t>* metrics) override; 63 64 void InterruptQuery() override; 65 66 private: 67 // Needed for iterators to be able to delete themselves from the vector. 68 friend class IteratorImpl; 69 70 ScopedDb db_; // Keep first. 71 TraceProcessorContext context_; 72 bool unrecoverable_parse_error_ = false; 73 74 std::vector<IteratorImpl*> iterators_; 75 76 // This is atomic because it is set by the CTRL-C signal handler and we need 77 // to prevent single-flow compiler optimizations in ExecuteQuery(). 78 std::atomic<bool> query_interrupted_{false}; 79 80 const Config cfg_; 81 }; 82 83 // The pointer implementation of TraceProcessor::Iterator. 84 class TraceProcessor::IteratorImpl { 85 public: 86 IteratorImpl(TraceProcessorImpl* impl, 87 sqlite3* db, 88 ScopedStmt, 89 uint32_t column_count, 90 base::Optional<std::string> error, 91 uint32_t sql_stats_row); 92 ~IteratorImpl(); 93 94 IteratorImpl(IteratorImpl&) noexcept = delete; 95 IteratorImpl& operator=(IteratorImpl&) = delete; 96 97 IteratorImpl(IteratorImpl&&) noexcept = default; 98 IteratorImpl& operator=(IteratorImpl&&) = default; 99 100 // Methods called by TraceProcessor::Iterator. Next()101 bool Next() { 102 // Delegate to the cc file to prevent trace_storage.h include in this 103 // file. 104 if (!called_next_) { 105 RecordFirstNextInSqlStats(); 106 called_next_ = true; 107 } 108 109 if (PERFETTO_UNLIKELY(error_.has_value())) 110 return false; 111 112 int ret = sqlite3_step(*stmt_); 113 if (PERFETTO_UNLIKELY(ret != SQLITE_ROW && ret != SQLITE_DONE)) { 114 error_ = base::Optional<std::string>(sqlite3_errmsg(db_)); 115 return false; 116 } 117 return ret == SQLITE_ROW; 118 } 119 Get(uint32_t col)120 SqlValue Get(uint32_t col) { 121 auto column = static_cast<int>(col); 122 auto col_type = sqlite3_column_type(*stmt_, column); 123 SqlValue value; 124 switch (col_type) { 125 case SQLITE_INTEGER: 126 value.type = SqlValue::kLong; 127 value.long_value = sqlite3_column_int64(*stmt_, column); 128 break; 129 case SQLITE_TEXT: 130 value.type = SqlValue::kString; 131 value.string_value = 132 reinterpret_cast<const char*>(sqlite3_column_text(*stmt_, column)); 133 break; 134 case SQLITE_FLOAT: 135 value.type = SqlValue::kDouble; 136 value.double_value = sqlite3_column_double(*stmt_, column); 137 break; 138 case SQLITE_NULL: 139 value.type = SqlValue::kNull; 140 break; 141 } 142 return value; 143 } 144 GetColumnName(uint32_t col)145 std::string GetColumnName(uint32_t col) { 146 return sqlite3_column_name(stmt_.get(), static_cast<int>(col)); 147 } 148 ColumnCount()149 uint32_t ColumnCount() { return column_count_; } 150 GetLastError()151 base::Optional<std::string> GetLastError() { return error_; } 152 153 // Methods called by TraceProcessorImpl. 154 void Reset(); 155 156 private: 157 void RecordFirstNextInSqlStats(); 158 159 TraceProcessorImpl* trace_processor_; 160 sqlite3* db_ = nullptr; 161 ScopedStmt stmt_; 162 uint32_t column_count_ = 0; 163 base::Optional<std::string> error_; 164 165 uint32_t sql_stats_row_ = 0; 166 bool called_next_ = false; 167 }; 168 169 } // namespace trace_processor 170 } // namespace perfetto 171 172 #endif // SRC_TRACE_PROCESSOR_TRACE_PROCESSOR_IMPL_H_ 173