• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/trace_processor/trace_processor_impl.h"
18 
19 #include <algorithm>
20 #include <memory>
21 
22 #include "perfetto/base/logging.h"
23 #include "perfetto/base/status.h"
24 #include "perfetto/base/time.h"
25 #include "perfetto/ext/base/string_splitter.h"
26 #include "perfetto/ext/base/string_utils.h"
27 #include "perfetto/ext/trace_processor/demangle.h"
28 #include "src/trace_processor/dynamic/ancestor_generator.h"
29 #include "src/trace_processor/dynamic/connected_flow_generator.h"
30 #include "src/trace_processor/dynamic/descendant_generator.h"
31 #include "src/trace_processor/dynamic/describe_slice_generator.h"
32 #include "src/trace_processor/dynamic/experimental_annotated_stack_generator.h"
33 #include "src/trace_processor/dynamic/experimental_counter_dur_generator.h"
34 #include "src/trace_processor/dynamic/experimental_flamegraph_generator.h"
35 #include "src/trace_processor/dynamic/experimental_flat_slice_generator.h"
36 #include "src/trace_processor/dynamic/experimental_sched_upid_generator.h"
37 #include "src/trace_processor/dynamic/experimental_slice_layout_generator.h"
38 #include "src/trace_processor/dynamic/thread_state_generator.h"
39 #include "src/trace_processor/export_json.h"
40 #include "src/trace_processor/importers/additional_modules.h"
41 #include "src/trace_processor/importers/ftrace/sched_event_tracker.h"
42 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_parser.h"
43 #include "src/trace_processor/importers/fuchsia/fuchsia_trace_tokenizer.h"
44 #include "src/trace_processor/importers/gzip/gzip_trace_parser.h"
45 #include "src/trace_processor/importers/json/json_trace_parser.h"
46 #include "src/trace_processor/importers/json/json_trace_tokenizer.h"
47 #include "src/trace_processor/importers/proto/metadata_tracker.h"
48 #include "src/trace_processor/importers/systrace/systrace_trace_parser.h"
49 #include "src/trace_processor/iterator_impl.h"
50 #include "src/trace_processor/sqlite/create_function.h"
51 #include "src/trace_processor/sqlite/create_view_function.h"
52 #include "src/trace_processor/sqlite/register_function.h"
53 #include "src/trace_processor/sqlite/scoped_db.h"
54 #include "src/trace_processor/sqlite/span_join_operator_table.h"
55 #include "src/trace_processor/sqlite/sql_stats_table.h"
56 #include "src/trace_processor/sqlite/sqlite3_str_split.h"
57 #include "src/trace_processor/sqlite/sqlite_raw_table.h"
58 #include "src/trace_processor/sqlite/sqlite_table.h"
59 #include "src/trace_processor/sqlite/sqlite_utils.h"
60 #include "src/trace_processor/sqlite/stats_table.h"
61 #include "src/trace_processor/sqlite/window_operator_table.h"
62 #include "src/trace_processor/tp_metatrace.h"
63 #include "src/trace_processor/types/variadic.h"
64 #include "src/trace_processor/util/protozero_to_text.h"
65 #include "src/trace_processor/util/status_macros.h"
66 
67 #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
68 #include "protos/perfetto/trace/trace.pbzero.h"
69 #include "protos/perfetto/trace/trace_packet.pbzero.h"
70 
71 #include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
72 #include "src/trace_processor/metrics/metrics.descriptor.h"
73 #include "src/trace_processor/metrics/metrics.h"
74 #include "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"
75 
76 
77 // In Android and Chromium tree builds, we don't have the percentile module.
78 // Just don't include it.
79 #if PERFETTO_BUILDFLAG(PERFETTO_TP_PERCENTILE)
80 // defined in sqlite_src/ext/misc/percentile.c
81 extern "C" int sqlite3_percentile_init(sqlite3* db,
82                                        char** error,
83                                        const sqlite3_api_routines* api);
84 #endif  // PERFETTO_BUILDFLAG(PERFETTO_TP_PERCENTILE)
85 
86 namespace perfetto {
87 namespace trace_processor {
88 namespace {
89 
90 const char kAllTablesQuery[] =
91     "SELECT tbl_name, type FROM (SELECT * FROM sqlite_master UNION ALL SELECT "
92     "* FROM sqlite_temp_master)";
93 
94 template <typename SqlFunction, typename Ptr = typename SqlFunction::Context*>
RegisterFunction(sqlite3 * db,const char * name,int argc,Ptr context=nullptr,bool deterministic=true)95 void RegisterFunction(sqlite3* db,
96                       const char* name,
97                       int argc,
98                       Ptr context = nullptr,
99                       bool deterministic = true) {
100   auto status = RegisterSqlFunction<SqlFunction>(
101       db, name, argc, std::move(context), deterministic);
102   if (!status.ok())
103     PERFETTO_ELOG("%s", status.c_message());
104 }
105 
InitializeSqlite(sqlite3 * db)106 void InitializeSqlite(sqlite3* db) {
107   char* error = nullptr;
108   sqlite3_exec(db, "PRAGMA temp_store=2", 0, 0, &error);
109   if (error) {
110     PERFETTO_FATAL("Error setting pragma temp_store: %s", error);
111   }
112   sqlite3_str_split_init(db);
113 // In Android tree builds, we don't have the percentile module.
114 // Just don't include it.
115 #if PERFETTO_BUILDFLAG(PERFETTO_TP_PERCENTILE)
116   sqlite3_percentile_init(db, &error, nullptr);
117   if (error) {
118     PERFETTO_ELOG("Error initializing: %s", error);
119     sqlite3_free(error);
120   }
121 #endif
122 }
123 
BuildBoundsTable(sqlite3 * db,std::pair<int64_t,int64_t> bounds)124 void BuildBoundsTable(sqlite3* db, std::pair<int64_t, int64_t> bounds) {
125   char* error = nullptr;
126   sqlite3_exec(db, "DELETE FROM trace_bounds", nullptr, nullptr, &error);
127   if (error) {
128     PERFETTO_ELOG("Error deleting from bounds table: %s", error);
129     sqlite3_free(error);
130     return;
131   }
132 
133   char* insert_sql = sqlite3_mprintf("INSERT INTO trace_bounds VALUES(%" PRId64
134                                      ", %" PRId64 ")",
135                                      bounds.first, bounds.second);
136 
137   sqlite3_exec(db, insert_sql, 0, 0, &error);
138   sqlite3_free(insert_sql);
139   if (error) {
140     PERFETTO_ELOG("Error inserting bounds table: %s", error);
141     sqlite3_free(error);
142   }
143 }
144 
CreateBuiltinTables(sqlite3 * db)145 void CreateBuiltinTables(sqlite3* db) {
146   char* error = nullptr;
147   sqlite3_exec(db, "CREATE TABLE perfetto_tables(name STRING)", 0, 0, &error);
148   if (error) {
149     PERFETTO_ELOG("Error initializing: %s", error);
150     sqlite3_free(error);
151   }
152   sqlite3_exec(db,
153                "CREATE TABLE trace_bounds(start_ts BIG INT, end_ts BIG INT)", 0,
154                0, &error);
155   if (error) {
156     PERFETTO_ELOG("Error initializing: %s", error);
157     sqlite3_free(error);
158   }
159   // Ensure that the entries in power_profile are unique to prevent duplicates
160   // when the power_profile is augmented with additional profiles.
161   sqlite3_exec(db,
162                "CREATE TABLE power_profile("
163                "device STRING, cpu INT, cluster INT, freq INT, power DOUBLE,"
164                "UNIQUE(device, cpu, cluster, freq));",
165                0, 0, &error);
166   if (error) {
167     PERFETTO_ELOG("Error initializing: %s", error);
168     sqlite3_free(error);
169   }
170   sqlite3_exec(db, "CREATE TABLE trace_metrics(name STRING)", 0, 0, &error);
171   if (error) {
172     PERFETTO_ELOG("Error initializing: %s", error);
173     sqlite3_free(error);
174   }
175   // This is a table intended to be used for metric debugging/developing. Data
176   // in the table is shown specially in the UI, and users can insert rows into
177   // this table to draw more things.
178   sqlite3_exec(db,
179                "CREATE TABLE debug_slices (id BIG INT, name STRING, ts BIG INT,"
180                "dur BIG INT, depth BIG INT)",
181                0, 0, &error);
182   if (error) {
183     PERFETTO_ELOG("Error initializing: %s", error);
184     sqlite3_free(error);
185   }
186 
187   // Initialize the bounds table with some data so even before parsing any data,
188   // we still have a valid table.
189   BuildBoundsTable(db, std::make_pair(0, 0));
190 }
191 
CreateBuiltinViews(sqlite3 * db)192 void CreateBuiltinViews(sqlite3* db) {
193   char* error = nullptr;
194   sqlite3_exec(db,
195                "CREATE VIEW counter_definitions AS "
196                "SELECT "
197                "  *, "
198                "  id AS counter_id "
199                "FROM counter_track",
200                0, 0, &error);
201   if (error) {
202     PERFETTO_ELOG("Error initializing: %s", error);
203     sqlite3_free(error);
204   }
205 
206   sqlite3_exec(db,
207                "CREATE VIEW counter_values AS "
208                "SELECT "
209                "  *, "
210                "  track_id as counter_id "
211                "FROM counter",
212                0, 0, &error);
213   if (error) {
214     PERFETTO_ELOG("Error initializing: %s", error);
215     sqlite3_free(error);
216   }
217 
218   sqlite3_exec(db,
219                "CREATE VIEW counters AS "
220                "SELECT * "
221                "FROM counter_values v "
222                "INNER JOIN counter_track t "
223                "ON v.track_id = t.id "
224                "ORDER BY ts;",
225                0, 0, &error);
226   if (error) {
227     PERFETTO_ELOG("Error initializing: %s", error);
228     sqlite3_free(error);
229   }
230 
231   sqlite3_exec(db,
232                "CREATE VIEW slice AS "
233                "SELECT "
234                "  *, "
235                "  category AS cat, "
236                "  id AS slice_id "
237                "FROM internal_slice;",
238                0, 0, &error);
239   if (error) {
240     PERFETTO_ELOG("Error initializing: %s", error);
241     sqlite3_free(error);
242   }
243 
244   sqlite3_exec(db,
245                "CREATE VIEW instants AS "
246                "SELECT "
247                "*, "
248                "0.0 as value "
249                "FROM instant;",
250                0, 0, &error);
251 
252   if (error) {
253     PERFETTO_ELOG("Error initializing: %s", error);
254     sqlite3_free(error);
255   }
256 
257   sqlite3_exec(db,
258                "CREATE VIEW sched AS "
259                "SELECT "
260                "*, "
261                "ts + dur as ts_end "
262                "FROM sched_slice;",
263                0, 0, &error);
264 
265   if (error) {
266     PERFETTO_ELOG("Error initializing: %s", error);
267     sqlite3_free(error);
268   }
269 
270   // Legacy view for "slice" table with a deprecated table name.
271   // TODO(eseckler): Remove this view when all users have switched to "slice".
272   sqlite3_exec(db,
273                "CREATE VIEW slices AS "
274                "SELECT * FROM slice;",
275                0, 0, &error);
276   if (error) {
277     PERFETTO_ELOG("Error initializing: %s", error);
278     sqlite3_free(error);
279   }
280 
281   sqlite3_exec(db,
282                "CREATE VIEW thread AS "
283                "SELECT "
284                "id as utid, "
285                "* "
286                "FROM internal_thread;",
287                0, 0, &error);
288   if (error) {
289     PERFETTO_ELOG("Error initializing: %s", error);
290     sqlite3_free(error);
291   }
292 
293   sqlite3_exec(db,
294                "CREATE VIEW process AS "
295                "SELECT "
296                "id as upid, "
297                "* "
298                "FROM internal_process;",
299                0, 0, &error);
300   if (error) {
301     PERFETTO_ELOG("Error initializing: %s", error);
302     sqlite3_free(error);
303   }
304 
305   // This should be kept in sync with GlobalArgsTracker::AddArgSet.
306   sqlite3_exec(db,
307                "CREATE VIEW args AS "
308                "SELECT "
309                "*, "
310                "CASE value_type "
311                "  WHEN 'int' THEN CAST(int_value AS text) "
312                "  WHEN 'uint' THEN CAST(int_value AS text) "
313                "  WHEN 'string' THEN string_value "
314                "  WHEN 'real' THEN CAST(real_value AS text) "
315                "  WHEN 'pointer' THEN printf('0x%x', int_value) "
316                "  WHEN 'bool' THEN ( "
317                "    CASE WHEN int_value <> 0 THEN 'true' "
318                "    ELSE 'false' END) "
319                "  WHEN 'json' THEN string_value "
320                "ELSE NULL END AS display_value "
321                "FROM internal_args;",
322                0, 0, &error);
323   if (error) {
324     PERFETTO_ELOG("Error initializing: %s", error);
325     sqlite3_free(error);
326   }
327 }
328 
329 struct ExportJson : public SqlFunction {
330   using Context = TraceStorage;
331   static base::Status Run(TraceStorage* storage,
332                           size_t /*argc*/,
333                           sqlite3_value** argv,
334                           SqlValue& /*out*/,
335                           Destructors&);
336 };
337 
Run(TraceStorage * storage,size_t,sqlite3_value ** argv,SqlValue &,Destructors &)338 base::Status ExportJson::Run(TraceStorage* storage,
339                              size_t /*argc*/,
340                              sqlite3_value** argv,
341                              SqlValue& /*out*/,
342                              Destructors&) {
343   FILE* output;
344   if (sqlite3_value_type(argv[0]) == SQLITE_INTEGER) {
345     // Assume input is an FD.
346     output = fdopen(sqlite3_value_int(argv[0]), "w");
347     if (!output) {
348       return base::ErrStatus(
349           "EXPORT_JSON: Couldn't open output file from given FD");
350     }
351   } else {
352     const char* filename =
353         reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
354     output = fopen(filename, "w");
355     if (!output) {
356       return base::ErrStatus("EXPORT_JSON: Couldn't open output file");
357     }
358   }
359   return json::ExportJson(storage, output);
360 }
361 
362 struct Hash : public SqlFunction {
363   static base::Status Run(void*,
364                           size_t argc,
365                           sqlite3_value** argv,
366                           SqlValue& out,
367                           Destructors&);
368 };
369 
Run(void *,size_t argc,sqlite3_value ** argv,SqlValue & out,Destructors &)370 base::Status Hash::Run(void*,
371                        size_t argc,
372                        sqlite3_value** argv,
373                        SqlValue& out,
374                        Destructors&) {
375   base::Hash hash;
376   for (size_t i = 0; i < argc; ++i) {
377     sqlite3_value* value = argv[i];
378     int type = sqlite3_value_type(value);
379     switch (type) {
380       case SQLITE_INTEGER:
381         hash.Update(sqlite3_value_int64(value));
382         break;
383       case SQLITE_TEXT: {
384         const char* ptr =
385             reinterpret_cast<const char*>(sqlite3_value_text(value));
386         hash.Update(ptr, strlen(ptr));
387         break;
388       }
389       default:
390         return base::ErrStatus("HASH: arg %zu has unknown type %d", i, type);
391     }
392   }
393   out = SqlValue::Long(static_cast<int64_t>(hash.digest()));
394   return base::OkStatus();
395 }
396 
397 struct Demangle : public SqlFunction {
398   static base::Status Run(void*,
399                           size_t argc,
400                           sqlite3_value** argv,
401                           SqlValue& out,
402                           Destructors& destructors);
403 };
404 
Run(void *,size_t argc,sqlite3_value ** argv,SqlValue & out,Destructors & destructors)405 base::Status Demangle::Run(void*,
406                            size_t argc,
407                            sqlite3_value** argv,
408                            SqlValue& out,
409                            Destructors& destructors) {
410   if (argc != 1)
411     return base::ErrStatus("Unsupported number of arg passed to DEMANGLE");
412   sqlite3_value* value = argv[0];
413   if (sqlite3_value_type(value) == SQLITE_NULL)
414     return base::OkStatus();
415 
416   if (sqlite3_value_type(value) != SQLITE_TEXT)
417     return base::ErrStatus("Unsupported type of arg passed to DEMANGLE");
418 
419   const char* mangled =
420       reinterpret_cast<const char*>(sqlite3_value_text(value));
421 
422   std::unique_ptr<char, base::FreeDeleter> demangled =
423       demangle::Demangle(mangled);
424   if (!demangled)
425     return base::OkStatus();
426 
427   destructors.string_destructor = free;
428   out = SqlValue::String(demangled.release());
429   return base::OkStatus();
430 }
431 
LastNonNullStep(sqlite3_context * ctx,int argc,sqlite3_value ** argv)432 void LastNonNullStep(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
433   if (argc != 1) {
434     sqlite3_result_error(
435         ctx, "Unsupported number of args passed to LAST_NON_NULL", -1);
436     return;
437   }
438   sqlite3_value* value = argv[0];
439   if (sqlite3_value_type(value) == SQLITE_NULL) {
440     return;
441   }
442   sqlite3_value** ptr = reinterpret_cast<sqlite3_value**>(
443       sqlite3_aggregate_context(ctx, sizeof(sqlite3_value*)));
444   if (ptr) {
445     if (*ptr != nullptr) {
446       sqlite3_value_free(*ptr);
447     }
448     *ptr = sqlite3_value_dup(value);
449   }
450 }
451 
LastNonNullInverse(sqlite3_context * ctx,int argc,sqlite3_value ** argv)452 void LastNonNullInverse(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
453   // Do nothing.
454   base::ignore_result(ctx);
455   base::ignore_result(argc);
456   base::ignore_result(argv);
457 }
458 
LastNonNullValue(sqlite3_context * ctx)459 void LastNonNullValue(sqlite3_context* ctx) {
460   sqlite3_value** ptr =
461       reinterpret_cast<sqlite3_value**>(sqlite3_aggregate_context(ctx, 0));
462   if (!ptr || !*ptr) {
463     sqlite3_result_null(ctx);
464   } else {
465     sqlite3_result_value(ctx, *ptr);
466   }
467 }
468 
LastNonNullFinal(sqlite3_context * ctx)469 void LastNonNullFinal(sqlite3_context* ctx) {
470   sqlite3_value** ptr =
471       reinterpret_cast<sqlite3_value**>(sqlite3_aggregate_context(ctx, 0));
472   if (!ptr || !*ptr) {
473     sqlite3_result_null(ctx);
474   } else {
475     sqlite3_result_value(ctx, *ptr);
476     sqlite3_value_free(*ptr);
477   }
478 }
479 
RegisterLastNonNullFunction(sqlite3 * db)480 void RegisterLastNonNullFunction(sqlite3* db) {
481   auto ret = sqlite3_create_window_function(
482       db, "LAST_NON_NULL", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr,
483       &LastNonNullStep, &LastNonNullFinal, &LastNonNullValue,
484       &LastNonNullInverse, nullptr);
485   if (ret) {
486     PERFETTO_ELOG("Error initializing LAST_NON_NULL");
487   }
488 }
489 
490 struct ValueAtMaxTsContext {
491   bool initialized;
492   int value_type;
493 
494   int64_t max_ts;
495   int64_t int_value_at_max_ts;
496   double double_value_at_max_ts;
497 };
498 
ValueAtMaxTsStep(sqlite3_context * ctx,int,sqlite3_value ** argv)499 void ValueAtMaxTsStep(sqlite3_context* ctx, int, sqlite3_value** argv) {
500   sqlite3_value* ts = argv[0];
501   sqlite3_value* value = argv[1];
502 
503   // Note that sqlite3_aggregate_context zeros the memory for us so all the
504   // variables of the struct should be zero.
505   ValueAtMaxTsContext* fn_ctx = reinterpret_cast<ValueAtMaxTsContext*>(
506       sqlite3_aggregate_context(ctx, sizeof(ValueAtMaxTsContext)));
507 
508   // For performance reasons, we only do the check for the type of ts and value
509   // on the first call of the function.
510   if (PERFETTO_UNLIKELY(!fn_ctx->initialized)) {
511     if (sqlite3_value_type(ts) != SQLITE_INTEGER) {
512       sqlite3_result_error(ctx, "VALUE_AT_MAX_TS: ts passed was not an integer",
513                            -1);
514       return;
515     }
516 
517     fn_ctx->value_type = sqlite3_value_type(value);
518     if (fn_ctx->value_type != SQLITE_INTEGER &&
519         fn_ctx->value_type != SQLITE_FLOAT) {
520       sqlite3_result_error(
521           ctx, "VALUE_AT_MAX_TS: value passed was not an integer or float", -1);
522       return;
523     }
524 
525     fn_ctx->max_ts = std::numeric_limits<int64_t>::min();
526     fn_ctx->initialized = true;
527   }
528 
529   // On dcheck builds however, we check every passed ts and value.
530 #if PERFETTO_DCHECK_IS_ON()
531   if (sqlite3_value_type(ts) != SQLITE_INTEGER) {
532     sqlite3_result_error(ctx, "VALUE_AT_MAX_TS: ts passed was not an integer",
533                          -1);
534     return;
535   }
536   if (sqlite3_value_type(value) != fn_ctx->value_type) {
537     sqlite3_result_error(ctx, "VALUE_AT_MAX_TS: value type is inconsistent",
538                          -1);
539     return;
540   }
541 #endif
542 
543   int64_t ts_int = sqlite3_value_int64(ts);
544   if (PERFETTO_LIKELY(fn_ctx->max_ts <= ts_int)) {
545     fn_ctx->max_ts = ts_int;
546 
547     if (fn_ctx->value_type == SQLITE_INTEGER) {
548       fn_ctx->int_value_at_max_ts = sqlite3_value_int64(value);
549     } else {
550       fn_ctx->double_value_at_max_ts = sqlite3_value_double(value);
551     }
552   }
553 }
554 
ValueAtMaxTsFinal(sqlite3_context * ctx)555 void ValueAtMaxTsFinal(sqlite3_context* ctx) {
556   ValueAtMaxTsContext* fn_ctx =
557       reinterpret_cast<ValueAtMaxTsContext*>(sqlite3_aggregate_context(ctx, 0));
558   if (!fn_ctx) {
559     sqlite3_result_null(ctx);
560     return;
561   }
562   if (fn_ctx->value_type == SQLITE_INTEGER) {
563     sqlite3_result_int64(ctx, fn_ctx->int_value_at_max_ts);
564   } else {
565     sqlite3_result_double(ctx, fn_ctx->double_value_at_max_ts);
566   }
567 }
568 
RegisterValueAtMaxTsFunction(sqlite3 * db)569 void RegisterValueAtMaxTsFunction(sqlite3* db) {
570   auto ret = sqlite3_create_function_v2(
571       db, "VALUE_AT_MAX_TS", 2, SQLITE_UTF8 | SQLITE_DETERMINISTIC, nullptr,
572       nullptr, &ValueAtMaxTsStep, &ValueAtMaxTsFinal, nullptr);
573   if (ret) {
574     PERFETTO_ELOG("Error initializing VALUE_AT_MAX_TS");
575   }
576 }
577 
578 struct ExtractArg : public SqlFunction {
579   using Context = TraceStorage;
580   static base::Status Run(TraceStorage* storage,
581                           size_t argc,
582                           sqlite3_value** argv,
583                           SqlValue& out,
584                           Destructors& destructors);
585 };
586 
Run(TraceStorage * storage,size_t argc,sqlite3_value ** argv,SqlValue & out,Destructors & destructors)587 base::Status ExtractArg::Run(TraceStorage* storage,
588                              size_t argc,
589                              sqlite3_value** argv,
590                              SqlValue& out,
591                              Destructors& destructors) {
592   if (argc != 2)
593     return base::ErrStatus("EXTRACT_ARG: 2 args required");
594 
595   // If the arg set id is null, just return null as the result.
596   if (sqlite3_value_type(argv[0]) == SQLITE_NULL)
597     return base::OkStatus();
598 
599   if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER)
600     return base::ErrStatus("EXTRACT_ARG: 1st argument should be arg set id");
601 
602   if (sqlite3_value_type(argv[1]) != SQLITE_TEXT)
603     return base::ErrStatus("EXTRACT_ARG: 2nd argument should be key");
604 
605   uint32_t arg_set_id = static_cast<uint32_t>(sqlite3_value_int(argv[0]));
606   const char* key = reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
607 
608   base::Optional<Variadic> opt_value;
609   RETURN_IF_ERROR(storage->ExtractArg(arg_set_id, key, &opt_value));
610 
611   if (!opt_value)
612     return base::OkStatus();
613 
614   // This function always returns static strings (i.e. scoped to lifetime
615   // of the TraceStorage thread pool) so prevent SQLite from making copies.
616   destructors.string_destructor = sqlite_utils::kSqliteStatic;
617 
618   switch (opt_value->type) {
619     case Variadic::kNull:
620       return base::OkStatus();
621     case Variadic::kInt:
622       out = SqlValue::Long(opt_value->int_value);
623       return base::OkStatus();
624     case Variadic::kUint:
625       out = SqlValue::Long(static_cast<int64_t>(opt_value->uint_value));
626       return base::OkStatus();
627     case Variadic::kString:
628       out =
629           SqlValue::String(storage->GetString(opt_value->string_value).data());
630       return base::OkStatus();
631     case Variadic::kReal:
632       out = SqlValue::Double(opt_value->real_value);
633       return base::OkStatus();
634     case Variadic::kBool:
635       out = SqlValue::Long(opt_value->bool_value);
636       return base::OkStatus();
637     case Variadic::kPointer:
638       out = SqlValue::Long(static_cast<int64_t>(opt_value->pointer_value));
639       return base::OkStatus();
640     case Variadic::kJson:
641       out = SqlValue::String(storage->GetString(opt_value->json_value).data());
642       return base::OkStatus();
643   }
644   PERFETTO_FATAL("For GCC");
645 }
646 
SanitizeMetricMountPaths(const std::vector<std::string> & mount_paths)647 std::vector<std::string> SanitizeMetricMountPaths(
648     const std::vector<std::string>& mount_paths) {
649   std::vector<std::string> sanitized;
650   for (const auto& path : mount_paths) {
651     if (path.length() == 0)
652       continue;
653     sanitized.push_back(path);
654     if (path.back() != '/')
655       sanitized.back().append("/");
656   }
657   return sanitized;
658 }
659 
660 struct SourceGeq : public SqlFunction {
Runperfetto::trace_processor::__anond8992c3c0111::SourceGeq661   static base::Status Run(void*,
662                           size_t,
663                           sqlite3_value**,
664                           SqlValue&,
665                           Destructors&) {
666     return base::ErrStatus(
667         "SOURCE_GEQ should not be called from the global scope");
668   }
669 };
670 
671 struct Glob : public SqlFunction {
Runperfetto::trace_processor::__anond8992c3c0111::Glob672   static base::Status Run(void*,
673                           size_t,
674                           sqlite3_value** argv,
675                           SqlValue& out,
676                           Destructors&) {
677     const char* pattern =
678         reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
679     const char* text =
680         reinterpret_cast<const char*>(sqlite3_value_text(argv[1]));
681     if (pattern && text) {
682       out = SqlValue::Long(sqlite3_strglob(pattern, text) == 0);
683     }
684     return base::OkStatus();
685   }
686 };
687 
SetupMetrics(TraceProcessor * tp,sqlite3 * db,std::vector<metrics::SqlMetricFile> * sql_metrics,const std::vector<std::string> & extension_paths)688 void SetupMetrics(TraceProcessor* tp,
689                   sqlite3* db,
690                   std::vector<metrics::SqlMetricFile>* sql_metrics,
691                   const std::vector<std::string>& extension_paths) {
692   const std::vector<std::string> sanitized_extension_paths =
693       SanitizeMetricMountPaths(extension_paths);
694   std::vector<std::string> skip_prefixes;
695   skip_prefixes.reserve(sanitized_extension_paths.size());
696   for (const auto& path : sanitized_extension_paths) {
697     skip_prefixes.push_back(kMetricProtoRoot + path);
698   }
699   tp->ExtendMetricsProto(kMetricsDescriptor.data(), kMetricsDescriptor.size(),
700                          skip_prefixes);
701   tp->ExtendMetricsProto(kAllChromeMetricsDescriptor.data(),
702                          kAllChromeMetricsDescriptor.size(), skip_prefixes);
703 
704   // TODO(lalitm): remove this special casing and change
705   // SanitizeMetricMountPaths if/when we move all protos for builtin metrics to
706   // match extension protos.
707   bool skip_all_sql = std::find(extension_paths.begin(), extension_paths.end(),
708                                 "") != extension_paths.end();
709   if (!skip_all_sql) {
710     for (const auto& file_to_sql : metrics::sql_metrics::kFileToSql) {
711       if (base::StartsWithAny(file_to_sql.path, sanitized_extension_paths))
712         continue;
713       tp->RegisterMetric(file_to_sql.path, file_to_sql.sql);
714     }
715   }
716 
717   RegisterFunction<metrics::NullIfEmpty>(db, "NULL_IF_EMPTY", 1);
718   RegisterFunction<metrics::UnwrapMetricProto>(db, "UNWRAP_METRIC_PROTO", 2);
719   RegisterFunction<metrics::RunMetric>(
720       db, "RUN_METRIC", -1,
721       std::unique_ptr<metrics::RunMetric::Context>(
722           new metrics::RunMetric::Context{tp, sql_metrics}));
723 
724   // TODO(lalitm): migrate this over to using RegisterFunction once aggregate
725   // functions are supported.
726   {
727     auto ret = sqlite3_create_function_v2(
728         db, "RepeatedField", 1, SQLITE_UTF8, nullptr, nullptr,
729         metrics::RepeatedFieldStep, metrics::RepeatedFieldFinal, nullptr);
730     if (ret)
731       PERFETTO_FATAL("Error initializing RepeatedField");
732   }
733 }
734 
EnsureSqliteInitialized()735 void EnsureSqliteInitialized() {
736   // sqlite3_initialize isn't actually thread-safe despite being documented
737   // as such; we need to make sure multiple TraceProcessorImpl instances don't
738   // call it concurrently and only gets called once per process, instead.
739   static bool init_once = [] { return sqlite3_initialize() == SQLITE_OK; }();
740   PERFETTO_CHECK(init_once);
741 }
742 
InsertIntoTraceMetricsTable(sqlite3 * db,const std::string & metric_name)743 void InsertIntoTraceMetricsTable(sqlite3* db, const std::string& metric_name) {
744   char* insert_sql = sqlite3_mprintf(
745       "INSERT INTO trace_metrics(name) VALUES('%q')", metric_name.c_str());
746   char* insert_error = nullptr;
747   sqlite3_exec(db, insert_sql, nullptr, nullptr, &insert_error);
748   sqlite3_free(insert_sql);
749   if (insert_error) {
750     PERFETTO_ELOG("Error registering table: %s", insert_error);
751     sqlite3_free(insert_error);
752   }
753 }
754 
IncrementCountForStmt(sqlite3_stmt * stmt,IteratorImpl::StmtMetadata * metadata)755 void IncrementCountForStmt(sqlite3_stmt* stmt,
756                            IteratorImpl::StmtMetadata* metadata) {
757   metadata->statement_count++;
758 
759   // If the stmt is already done, it clearly didn't have any output.
760   if (sqlite_utils::IsStmtDone(stmt))
761     return;
762 
763   // If the statement only has a single column and that column is named
764   // "suppress_query_output", treat it as a statement without output for
765   // accounting purposes. This is done so that embedders (e.g. shell) can
766   // strictly check that only the last query produces output while also
767   // providing an escape hatch for SELECT RUN_METRIC() invocations (which
768   // sadly produce output).
769   if (sqlite3_column_count(stmt) == 1 &&
770       strcmp(sqlite3_column_name(stmt, 0), "suppress_query_output") == 0) {
771     return;
772   }
773 
774   // Otherwise, the statement has output and so increment the count.
775   metadata->statement_count_with_output++;
776 }
777 
PrepareAndStepUntilLastValidStmt(sqlite3 * db,const std::string & sql,ScopedStmt * output_stmt,IteratorImpl::StmtMetadata * metadata)778 base::Status PrepareAndStepUntilLastValidStmt(
779     sqlite3* db,
780     const std::string& sql,
781     ScopedStmt* output_stmt,
782     IteratorImpl::StmtMetadata* metadata) {
783   ScopedStmt prev_stmt;
784   // A sql string can contain several statements. Some of them might be comment
785   // only, e.g. "SELECT 1; /* comment */; SELECT 2;". Here we process one
786   // statement on each iteration. SQLite's sqlite_prepare_v2 (wrapped by
787   // PrepareStmt) returns on each iteration a pointer to the unprocessed string.
788   //
789   // Unfortunately we cannot call PrepareStmt and tokenize all statements
790   // upfront because sqlite_prepare_v2 also semantically checks the statement
791   // against the schema. In some cases statements might depend on the execution
792   // of previous ones (e.e. CREATE VIEW x; SELECT FROM x; DELETE VIEW x;).
793   //
794   // Also, unfortunately, we need to PrepareStmt to find out if a statement is a
795   // comment or a real statement.
796   //
797   // The logic here is the following:
798   //  - We invoke PrepareStmt on each statement.
799   //  - If the statement is a comment we simply skip it.
800   //  - If the statement is valid, we step once to make sure side effects take
801   //    effect.
802   //  - If we encounter a valid statement afterwards, we step internally through
803   //    all rows of the previous one. This ensures that any further side effects
804   //    take hold *before* we step into the next statement.
805   //  - Once no further non-comment statements are encountered, we return an
806   //    iterator to the last valid statement.
807   for (const char* rem_sql = sql.c_str(); rem_sql && rem_sql[0];) {
808     ScopedStmt cur_stmt;
809     {
810       PERFETTO_TP_TRACE("QUERY_PREPARE");
811       const char* tail = nullptr;
812       RETURN_IF_ERROR(sqlite_utils::PrepareStmt(db, rem_sql, &cur_stmt, &tail));
813       rem_sql = tail;
814     }
815 
816     // The only situation where we'd have an ok status but also no prepared
817     // statement is if the statement of SQL we parsed was a pure comment. In
818     // this case, just continue to the next statement.
819     if (!cur_stmt)
820       continue;
821 
822     // Before stepping into |cur_stmt|, we need to finish iterating through
823     // the previous statement so we don't have two clashing statements (e.g.
824     // SELECT * FROM v and DROP VIEW v) partially stepped into.
825     if (prev_stmt)
826       RETURN_IF_ERROR(sqlite_utils::StepStmtUntilDone(prev_stmt.get()));
827 
828     PERFETTO_DLOG("Executing statement: %s", sqlite3_sql(*cur_stmt));
829 
830     // Now step once into |cur_stmt| so that when we prepare the next statment
831     // we will have executed any dependent bytecode in this one.
832     int err = sqlite3_step(*cur_stmt);
833     if (err != SQLITE_ROW && err != SQLITE_DONE)
834       return base::ErrStatus("%s (errcode: %d)", sqlite3_errmsg(db), err);
835 
836     // Increment the neecessary counts for the statement.
837     IncrementCountForStmt(cur_stmt.get(), metadata);
838 
839     // Propogate the current statement to the next iteration.
840     prev_stmt = std::move(cur_stmt);
841   }
842 
843   // If we didn't manage to prepare a single statment, that means everything
844   // in the SQL was treated as a comment.
845   if (!prev_stmt)
846     return base::ErrStatus("No valid SQL to run");
847 
848   // Update the output statment and column count.
849   *output_stmt = std::move(prev_stmt);
850   metadata->column_count =
851       static_cast<uint32_t>(sqlite3_column_count(output_stmt->get()));
852   return base::OkStatus();
853 }
854 
855 }  // namespace
856 
TraceProcessorImpl(const Config & cfg)857 TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
858     : TraceProcessorStorageImpl(cfg) {
859   context_.fuchsia_trace_tokenizer.reset(new FuchsiaTraceTokenizer(&context_));
860   context_.fuchsia_trace_parser.reset(new FuchsiaTraceParser(&context_));
861 
862   context_.systrace_trace_parser.reset(new SystraceTraceParser(&context_));
863 
864   if (util::IsGzipSupported())
865     context_.gzip_trace_parser.reset(new GzipTraceParser(&context_));
866 
867   if (json::IsJsonSupported()) {
868     context_.json_trace_tokenizer.reset(new JsonTraceTokenizer(&context_));
869     context_.json_trace_parser.reset(new JsonTraceParser(&context_));
870   }
871 
872   RegisterAdditionalModules(&context_);
873 
874   sqlite3* db = nullptr;
875   EnsureSqliteInitialized();
876   PERFETTO_CHECK(sqlite3_open(":memory:", &db) == SQLITE_OK);
877   InitializeSqlite(db);
878   CreateBuiltinTables(db);
879   CreateBuiltinViews(db);
880   db_.reset(std::move(db));
881 
882   // New style function registration.
883   RegisterFunction<Glob>(db, "glob", 2);
884   RegisterFunction<Hash>(db, "HASH", -1);
885   RegisterFunction<Demangle>(db, "DEMANGLE", 1);
886   RegisterFunction<SourceGeq>(db, "SOURCE_GEQ", -1);
887   RegisterFunction<ExportJson>(db, "EXPORT_JSON", 1, context_.storage.get(),
888                                false);
889   RegisterFunction<ExtractArg>(db, "EXTRACT_ARG", 2, context_.storage.get());
890   RegisterFunction<CreateFunction>(
891       db, "CREATE_FUNCTION", 3,
892       std::unique_ptr<CreateFunction::Context>(
893           new CreateFunction::Context{db_.get(), &create_function_state_}));
894   RegisterFunction<CreateViewFunction>(
895       db, "CREATE_VIEW_FUNCTION", 3,
896       std::unique_ptr<CreateViewFunction::Context>(
897           new CreateViewFunction::Context{db_.get()}));
898 
899   // Old style function registration.
900   // TODO(lalitm): migrate this over to using RegisterFunction once aggregate
901   // functions are supported.
902   RegisterLastNonNullFunction(db);
903   RegisterValueAtMaxTsFunction(db);
904 
905   SetupMetrics(this, *db_, &sql_metrics_, cfg.skip_builtin_metric_paths);
906 
907   // Setup the query cache.
908   query_cache_.reset(new QueryCache());
909 
910   const TraceStorage* storage = context_.storage.get();
911 
912   SqlStatsTable::RegisterTable(*db_, storage);
913   StatsTable::RegisterTable(*db_, storage);
914 
915   // Operator tables.
916   SpanJoinOperatorTable::RegisterTable(*db_, storage);
917   WindowOperatorTable::RegisterTable(*db_, storage);
918   CreateViewFunction::RegisterTable(*db_, &create_view_function_state_);
919 
920   // New style tables but with some custom logic.
921   SqliteRawTable::RegisterTable(*db_, query_cache_.get(), &context_);
922 
923   // Tables dynamically generated at query time.
924   RegisterDynamicTable(std::unique_ptr<ExperimentalFlamegraphGenerator>(
925       new ExperimentalFlamegraphGenerator(&context_)));
926   RegisterDynamicTable(std::unique_ptr<ExperimentalCounterDurGenerator>(
927       new ExperimentalCounterDurGenerator(storage->counter_table())));
928   RegisterDynamicTable(std::unique_ptr<DescribeSliceGenerator>(
929       new DescribeSliceGenerator(&context_)));
930   RegisterDynamicTable(std::unique_ptr<ExperimentalSliceLayoutGenerator>(
931       new ExperimentalSliceLayoutGenerator(
932           context_.storage.get()->mutable_string_pool(),
933           &storage->slice_table())));
934   RegisterDynamicTable(std::unique_ptr<AncestorGenerator>(
935       new AncestorGenerator(AncestorGenerator::Ancestor::kSlice, &context_)));
936   RegisterDynamicTable(std::unique_ptr<AncestorGenerator>(new AncestorGenerator(
937       AncestorGenerator::Ancestor::kStackProfileCallsite, &context_)));
938   RegisterDynamicTable(std::unique_ptr<AncestorGenerator>(new AncestorGenerator(
939       AncestorGenerator::Ancestor::kSliceByStack, &context_)));
940   RegisterDynamicTable(
941       std::unique_ptr<DescendantGenerator>(new DescendantGenerator(
942           DescendantGenerator::Descendant::kSlice, &context_)));
943   RegisterDynamicTable(
944       std::unique_ptr<DescendantGenerator>(new DescendantGenerator(
945           DescendantGenerator::Descendant::kSliceByStack, &context_)));
946   RegisterDynamicTable(
947       std::unique_ptr<ConnectedFlowGenerator>(new ConnectedFlowGenerator(
948           ConnectedFlowGenerator::Mode::kDirectlyConnectedFlow, &context_)));
949   RegisterDynamicTable(
950       std::unique_ptr<ConnectedFlowGenerator>(new ConnectedFlowGenerator(
951           ConnectedFlowGenerator::Mode::kPrecedingFlow, &context_)));
952   RegisterDynamicTable(
953       std::unique_ptr<ConnectedFlowGenerator>(new ConnectedFlowGenerator(
954           ConnectedFlowGenerator::Mode::kFollowingFlow, &context_)));
955   RegisterDynamicTable(std::unique_ptr<ExperimentalSchedUpidGenerator>(
956       new ExperimentalSchedUpidGenerator(storage->sched_slice_table(),
957                                          storage->thread_table())));
958   RegisterDynamicTable(std::unique_ptr<ThreadStateGenerator>(
959       new ThreadStateGenerator(&context_)));
960   RegisterDynamicTable(std::unique_ptr<ExperimentalAnnotatedStackGenerator>(
961       new ExperimentalAnnotatedStackGenerator(&context_)));
962   RegisterDynamicTable(std::unique_ptr<ExperimentalFlatSliceGenerator>(
963       new ExperimentalFlatSliceGenerator(&context_)));
964 
965   // New style db-backed tables.
966   RegisterDbTable(storage->arg_table());
967   RegisterDbTable(storage->thread_table());
968   RegisterDbTable(storage->process_table());
969 
970   RegisterDbTable(storage->slice_table());
971   RegisterDbTable(storage->flow_table());
972   RegisterDbTable(storage->thread_slice_table());
973   RegisterDbTable(storage->sched_slice_table());
974   RegisterDbTable(storage->instant_table());
975   RegisterDbTable(storage->gpu_slice_table());
976 
977   RegisterDbTable(storage->track_table());
978   RegisterDbTable(storage->thread_track_table());
979   RegisterDbTable(storage->process_track_table());
980   RegisterDbTable(storage->gpu_track_table());
981 
982   RegisterDbTable(storage->counter_table());
983 
984   RegisterDbTable(storage->counter_track_table());
985   RegisterDbTable(storage->process_counter_track_table());
986   RegisterDbTable(storage->thread_counter_track_table());
987   RegisterDbTable(storage->cpu_counter_track_table());
988   RegisterDbTable(storage->irq_counter_track_table());
989   RegisterDbTable(storage->softirq_counter_track_table());
990   RegisterDbTable(storage->gpu_counter_track_table());
991   RegisterDbTable(storage->gpu_counter_group_table());
992   RegisterDbTable(storage->perf_counter_track_table());
993 
994   RegisterDbTable(storage->heap_graph_object_table());
995   RegisterDbTable(storage->heap_graph_reference_table());
996   RegisterDbTable(storage->heap_graph_class_table());
997 
998   RegisterDbTable(storage->symbol_table());
999   RegisterDbTable(storage->heap_profile_allocation_table());
1000   RegisterDbTable(storage->cpu_profile_stack_sample_table());
1001   RegisterDbTable(storage->perf_sample_table());
1002   RegisterDbTable(storage->stack_profile_callsite_table());
1003   RegisterDbTable(storage->stack_profile_mapping_table());
1004   RegisterDbTable(storage->stack_profile_frame_table());
1005   RegisterDbTable(storage->package_list_table());
1006   RegisterDbTable(storage->profiler_smaps_table());
1007 
1008   RegisterDbTable(storage->android_log_table());
1009 
1010   RegisterDbTable(storage->vulkan_memory_allocations_table());
1011 
1012   RegisterDbTable(storage->graphics_frame_slice_table());
1013 
1014   RegisterDbTable(storage->expected_frame_timeline_slice_table());
1015   RegisterDbTable(storage->actual_frame_timeline_slice_table());
1016 
1017   RegisterDbTable(storage->metadata_table());
1018   RegisterDbTable(storage->cpu_table());
1019   RegisterDbTable(storage->cpu_freq_table());
1020   RegisterDbTable(storage->clock_snapshot_table());
1021 
1022   RegisterDbTable(storage->memory_snapshot_table());
1023   RegisterDbTable(storage->process_memory_snapshot_table());
1024   RegisterDbTable(storage->memory_snapshot_node_table());
1025   RegisterDbTable(storage->memory_snapshot_edge_table());
1026 }
1027 
1028 TraceProcessorImpl::~TraceProcessorImpl() = default;
1029 
Parse(TraceBlobView blob)1030 base::Status TraceProcessorImpl::Parse(TraceBlobView blob) {
1031   bytes_parsed_ += blob.size();
1032   return TraceProcessorStorageImpl::Parse(std::move(blob));
1033 }
1034 
GetCurrentTraceName()1035 std::string TraceProcessorImpl::GetCurrentTraceName() {
1036   if (current_trace_name_.empty())
1037     return "";
1038   auto size = " (" + std::to_string(bytes_parsed_ / 1024 / 1024) + " MB)";
1039   return current_trace_name_ + size;
1040 }
1041 
SetCurrentTraceName(const std::string & name)1042 void TraceProcessorImpl::SetCurrentTraceName(const std::string& name) {
1043   current_trace_name_ = name;
1044 }
1045 
NotifyEndOfFile()1046 void TraceProcessorImpl::NotifyEndOfFile() {
1047   if (current_trace_name_.empty())
1048     current_trace_name_ = "Unnamed trace";
1049 
1050   TraceProcessorStorageImpl::NotifyEndOfFile();
1051 
1052   SchedEventTracker::GetOrCreate(&context_)->FlushPendingEvents();
1053   context_.metadata_tracker->SetMetadata(
1054       metadata::trace_size_bytes,
1055       Variadic::Integer(static_cast<int64_t>(bytes_parsed_)));
1056   BuildBoundsTable(*db_, context_.storage->GetTraceTimestampBoundsNs());
1057 
1058   // Create a snapshot of all tables and views created so far. This is so later
1059   // we can drop all extra tables created by the UI and reset to the original
1060   // state (see RestoreInitialTables).
1061   initial_tables_.clear();
1062   auto it = ExecuteQuery(kAllTablesQuery);
1063   while (it.Next()) {
1064     auto value = it.Get(0);
1065     PERFETTO_CHECK(value.type == SqlValue::Type::kString);
1066     initial_tables_.push_back(value.string_value);
1067   }
1068 }
1069 
RestoreInitialTables()1070 size_t TraceProcessorImpl::RestoreInitialTables() {
1071   // Step 1: figure out what tables/views/indices we need to delete.
1072   std::vector<std::pair<std::string, std::string>> deletion_list;
1073   std::string msg = "Resetting DB to initial state, deleting table/views:";
1074   for (auto it = ExecuteQuery(kAllTablesQuery); it.Next();) {
1075     std::string name(it.Get(0).string_value);
1076     std::string type(it.Get(1).string_value);
1077     if (std::find(initial_tables_.begin(), initial_tables_.end(), name) ==
1078         initial_tables_.end()) {
1079       msg += " " + name;
1080       deletion_list.push_back(std::make_pair(type, name));
1081     }
1082   }
1083 
1084   PERFETTO_LOG("%s", msg.c_str());
1085 
1086   // Step 2: actually delete those tables/views/indices.
1087   for (const auto& tn : deletion_list) {
1088     std::string query = "DROP " + tn.first + " " + tn.second;
1089     auto it = ExecuteQuery(query);
1090     while (it.Next()) {
1091     }
1092     // Index deletion can legitimately fail. If one creates an index "i" on a
1093     // table "t" but issues the deletion in the order (t, i), the DROP index i
1094     // will fail with "no such index" because deleting the table "t"
1095     // automatically deletes all associated indexes.
1096     if (!it.Status().ok() && tn.first != "index")
1097       PERFETTO_FATAL("%s -> %s", query.c_str(), it.Status().c_message());
1098   }
1099   return deletion_list.size();
1100 }
1101 
ExecuteQuery(const std::string & sql)1102 Iterator TraceProcessorImpl::ExecuteQuery(const std::string& sql) {
1103   PERFETTO_TP_TRACE("QUERY_EXECUTE");
1104 
1105   uint32_t sql_stats_row =
1106       context_.storage->mutable_sql_stats()->RecordQueryBegin(
1107           sql, base::GetWallTimeNs().count());
1108 
1109   ScopedStmt stmt;
1110   IteratorImpl::StmtMetadata metadata;
1111   base::Status status =
1112       PrepareAndStepUntilLastValidStmt(*db_, sql, &stmt, &metadata);
1113   PERFETTO_DCHECK((status.ok() && stmt) || (!status.ok() && !stmt));
1114 
1115   std::unique_ptr<IteratorImpl> impl(new IteratorImpl(
1116       this, *db_, status, std::move(stmt), std::move(metadata), sql_stats_row));
1117   return Iterator(std::move(impl));
1118 }
1119 
InterruptQuery()1120 void TraceProcessorImpl::InterruptQuery() {
1121   if (!db_)
1122     return;
1123   query_interrupted_.store(true);
1124   sqlite3_interrupt(db_.get());
1125 }
1126 
IsRootMetricField(const std::string & metric_name)1127 bool TraceProcessorImpl::IsRootMetricField(const std::string& metric_name) {
1128   base::Optional<uint32_t> desc_idx =
1129       pool_.FindDescriptorIdx(".perfetto.protos.TraceMetrics");
1130   if (!desc_idx.has_value())
1131     return false;
1132   auto field_idx = pool_.descriptors()[*desc_idx].FindFieldByName(metric_name);
1133   return field_idx != nullptr;
1134 }
1135 
RegisterMetric(const std::string & path,const std::string & sql)1136 base::Status TraceProcessorImpl::RegisterMetric(const std::string& path,
1137                                                 const std::string& sql) {
1138   std::string stripped_sql;
1139   for (base::StringSplitter sp(sql, '\n'); sp.Next();) {
1140     if (strncmp(sp.cur_token(), "--", 2) != 0) {
1141       stripped_sql.append(sp.cur_token());
1142       stripped_sql.push_back('\n');
1143     }
1144   }
1145 
1146   // Check if the metric with the given path already exists and if it does, just
1147   // update the SQL associated with it.
1148   auto it = std::find_if(
1149       sql_metrics_.begin(), sql_metrics_.end(),
1150       [&path](const metrics::SqlMetricFile& m) { return m.path == path; });
1151   if (it != sql_metrics_.end()) {
1152     it->sql = stripped_sql;
1153     return base::OkStatus();
1154   }
1155 
1156   auto sep_idx = path.rfind('/');
1157   std::string basename =
1158       sep_idx == std::string::npos ? path : path.substr(sep_idx + 1);
1159 
1160   auto sql_idx = basename.rfind(".sql");
1161   if (sql_idx == std::string::npos) {
1162     return base::ErrStatus("Unable to find .sql extension for metric");
1163   }
1164   auto no_ext_name = basename.substr(0, sql_idx);
1165 
1166   metrics::SqlMetricFile metric;
1167   metric.path = path;
1168   metric.sql = stripped_sql;
1169 
1170   if (IsRootMetricField(no_ext_name)) {
1171     metric.proto_field_name = no_ext_name;
1172     metric.output_table_name = no_ext_name + "_output";
1173 
1174     auto field_it_and_inserted =
1175         proto_field_to_sql_metric_path_.emplace(*metric.proto_field_name, path);
1176     if (!field_it_and_inserted.second) {
1177       // We already had a metric with this field name in the map. However, if
1178       // this was the case, we should have found the metric in
1179       // |path_to_sql_metric_file_| above if we are simply overriding the
1180       // metric. Return an error since this means we have two different SQL
1181       // files which are trying to output the same metric.
1182       const auto& prev_path = field_it_and_inserted.first->second;
1183       PERFETTO_DCHECK(prev_path != path);
1184       return base::ErrStatus(
1185           "RegisterMetric Error: Metric paths %s (which is already registered) "
1186           "and %s are both trying to output the proto field %s",
1187           prev_path.c_str(), path.c_str(), metric.proto_field_name->c_str());
1188     }
1189 
1190     InsertIntoTraceMetricsTable(*db_, no_ext_name);
1191   }
1192 
1193   sql_metrics_.emplace_back(metric);
1194   return base::OkStatus();
1195 }
1196 
ExtendMetricsProto(const uint8_t * data,size_t size)1197 base::Status TraceProcessorImpl::ExtendMetricsProto(const uint8_t* data,
1198                                                     size_t size) {
1199   return ExtendMetricsProto(data, size, /*skip_prefixes*/ {});
1200 }
1201 
ExtendMetricsProto(const uint8_t * data,size_t size,const std::vector<std::string> & skip_prefixes)1202 base::Status TraceProcessorImpl::ExtendMetricsProto(
1203     const uint8_t* data,
1204     size_t size,
1205     const std::vector<std::string>& skip_prefixes) {
1206   base::Status status =
1207       pool_.AddFromFileDescriptorSet(data, size, skip_prefixes);
1208   if (!status.ok())
1209     return status;
1210 
1211   for (uint32_t i = 0; i < pool_.descriptors().size(); ++i) {
1212     // Convert the full name (e.g. .perfetto.protos.TraceMetrics.SubMetric)
1213     // into a function name of the form (TraceMetrics_SubMetric).
1214     const auto& desc = pool_.descriptors()[i];
1215     auto fn_name = desc.full_name().substr(desc.package_name().size() + 1);
1216     std::replace(fn_name.begin(), fn_name.end(), '.', '_');
1217     RegisterFunction<metrics::BuildProto>(
1218         db_.get(), fn_name.c_str(), -1,
1219         std::unique_ptr<metrics::BuildProto::Context>(
1220             new metrics::BuildProto::Context{this, &pool_, i}));
1221   }
1222   return base::OkStatus();
1223 }
1224 
ComputeMetric(const std::vector<std::string> & metric_names,std::vector<uint8_t> * metrics_proto)1225 base::Status TraceProcessorImpl::ComputeMetric(
1226     const std::vector<std::string>& metric_names,
1227     std::vector<uint8_t>* metrics_proto) {
1228   auto opt_idx = pool_.FindDescriptorIdx(".perfetto.protos.TraceMetrics");
1229   if (!opt_idx.has_value())
1230     return base::Status("Root metrics proto descriptor not found");
1231 
1232   const auto& root_descriptor = pool_.descriptors()[opt_idx.value()];
1233   return metrics::ComputeMetrics(this, metric_names, sql_metrics_, pool_,
1234                                  root_descriptor, metrics_proto);
1235 }
1236 
ComputeMetricText(const std::vector<std::string> & metric_names,TraceProcessor::MetricResultFormat format,std::string * metrics_string)1237 base::Status TraceProcessorImpl::ComputeMetricText(
1238     const std::vector<std::string>& metric_names,
1239     TraceProcessor::MetricResultFormat format,
1240     std::string* metrics_string) {
1241   std::vector<uint8_t> metrics_proto;
1242   base::Status status = ComputeMetric(metric_names, &metrics_proto);
1243   if (!status.ok())
1244     return status;
1245   switch (format) {
1246     case TraceProcessor::MetricResultFormat::kProtoText:
1247       *metrics_string = protozero_to_text::ProtozeroToText(
1248           pool_, ".perfetto.protos.TraceMetrics",
1249           protozero::ConstBytes{metrics_proto.data(), metrics_proto.size()},
1250           protozero_to_text::kIncludeNewLines);
1251       break;
1252     case TraceProcessor::MetricResultFormat::kJson:
1253       // TODO(dproy): Implement this.
1254       PERFETTO_FATAL("Json formatted metrics not supported yet.");
1255       break;
1256   }
1257   return status;
1258 }
1259 
GetMetricDescriptors()1260 std::vector<uint8_t> TraceProcessorImpl::GetMetricDescriptors() {
1261   return pool_.SerializeAsDescriptorSet();
1262 }
1263 
EnableMetatrace()1264 void TraceProcessorImpl::EnableMetatrace() {
1265   metatrace::Enable();
1266 }
1267 
DisableAndReadMetatrace(std::vector<uint8_t> * trace_proto)1268 base::Status TraceProcessorImpl::DisableAndReadMetatrace(
1269     std::vector<uint8_t>* trace_proto) {
1270   protozero::HeapBuffered<protos::pbzero::Trace> trace;
1271   metatrace::DisableAndReadBuffer([&trace](metatrace::Record* record) {
1272     auto packet = trace->add_packet();
1273     packet->set_timestamp(record->timestamp_ns);
1274     auto* evt = packet->set_perfetto_metatrace();
1275     evt->set_event_name(record->event_name);
1276     evt->set_event_duration_ns(record->duration_ns);
1277     evt->set_thread_id(1);  // Not really important, just required for the ui.
1278 
1279     if (record->args_buffer_size == 0)
1280       return;
1281 
1282     base::StringSplitter s(record->args_buffer, record->args_buffer_size, '\0');
1283     for (; s.Next();) {
1284       auto* arg_proto = evt->add_args();
1285       arg_proto->set_key(s.cur_token());
1286 
1287       bool has_next = s.Next();
1288       PERFETTO_CHECK(has_next);
1289       arg_proto->set_value(s.cur_token());
1290     }
1291   });
1292   *trace_proto = trace.SerializeAsArray();
1293   return base::OkStatus();
1294 }
1295 
1296 }  // namespace trace_processor
1297 }  // namespace perfetto
1298