• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1-- Copyright 2023 The Chromium Authors
2-- Use of this source code is governed by a BSD-style license that can be
3-- found in the LICENSE file.
4
5-- Checks if slice has an ancestor with provided name.
6CREATE PERFETTO FUNCTION _has_parent_slice_with_name(
7  -- Id of the slice to check parents of.
8  id LONG,
9  -- Name of potential ancestor slice.
10  parent_name STRING)
11-- Whether `parent_name` is a name of an ancestor slice.
12RETURNS BOOL AS
13SELECT EXISTS(
14  SELECT 1
15  FROM ancestor_slice($id)
16  WHERE name = $parent_name
17  LIMIT 1
18);
19
20-- Returns the mojo ipc hash for a given task, looking it up from the
21-- argument of descendant ScopedSetIpcHash slice.
22-- This is relevant only for the older Chrome traces, where mojo IPC
23-- hash was reported in a separate ScopedSetIpcHash slice.
24CREATE PERFETTO FUNCTION _extract_mojo_ipc_hash(slice_id LONG)
25RETURNS LONG AS
26SELECT EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash")
27FROM descendant_slice($slice_id)
28WHERE name="ScopedSetIpcHash"
29ORDER BY id
30LIMIT 1;
31
32-- Returns the frame type (main frame vs subframe) for key navigation tasks
33-- which capture the associated RenderFrameHost in an argument.
34CREATE PERFETTO FUNCTION _extract_frame_type(slice_id LONG)
35RETURNS LONG AS
36SELECT EXTRACT_ARG(arg_set_id, "render_frame_host.frame_type")
37FROM descendant_slice($slice_id)
38WHERE name IN (
39  "RenderFrameHostImpl::BeginNavigation",
40  "RenderFrameHostImpl::DidCommitProvisionalLoad",
41  "RenderFrameHostImpl::DidCommitSameDocumentNavigation",
42  "RenderFrameHostImpl::DidStopLoading"
43)
44LIMIT 1;
45
46-- Human-readable aliases for a few key navigation tasks.
47CREATE PERFETTO FUNCTION _human_readable_navigation_task_name(
48  task_name STRING)
49RETURNS STRING AS
50SELECT
51  CASE
52    WHEN $task_name = "content.mojom.FrameHost message (hash=2168461044)"
53      THEN "FrameHost::BeginNavigation"
54    WHEN $task_name = "content.mojom.FrameHost message (hash=3561497419)"
55      THEN "FrameHost::DidCommitProvisionalLoad"
56    WHEN $task_name = "content.mojom.FrameHost message (hash=1421450774)"
57      THEN "FrameHost::DidCommitSameDocumentNavigation"
58    WHEN $task_name = "content.mojom.FrameHost message (hash=368650583)"
59      THEN "FrameHost::DidStopLoading"
60  END;
61
62-- Takes a task name and formats it correctly for scheduler tasks.
63CREATE PERFETTO FUNCTION _format_scheduler_task_name(task_name STRING)
64RETURNS STRING AS
65SELECT printf("RunTask(posted_from=%s)", $task_name);
66
67-- Takes the category and determines whether it is "Java" only, as opposed to
68-- "toplevel,Java".
69CREATE PERFETTO FUNCTION _java_not_top_level_category(category STRING)
70RETURNS BOOL AS
71SELECT $category GLOB "*Java*" AND $category not GLOB "*toplevel*";
72
73-- Takes the category and determines whether is any valid
74-- toplevel category or combination of categories.
75CREATE PERFETTO FUNCTION _any_top_level_category(category STRING)
76RETURNS BOOL AS
77SELECT $category IN ("toplevel", "toplevel,viz", "toplevel,Java");
78
79-- TODO(altimin): the situations with kinds in this file is a bit of a mess.
80-- The idea is that it should work as `type` in the `slice` table, pointing to
81-- a "child" table with more information about the task (e.g. posted_from for
82-- scheduler tasks). Currently this is not the case and needs a cleanup.
83-- Also we should align this with how table inheritance should work for
84-- `CREATE PERFETTO TABLE`.
85
86-- Get task type for a given task kind.
87CREATE PERFETTO FUNCTION _get_java_views_task_type(kind STRING)
88RETURNS STRING AS
89SELECT
90  CASE $kind
91    WHEN "Choreographer" THEN "choreographer"
92    WHEN "SingleThreadProxy::BeginMainFrame" THEN "ui_thread_begin_main_frame"
93  END;
94
95-- All slices corresponding to receiving mojo messages.
96-- On the newer Chrome versions, it's just "Receive mojo message" and
97-- "Receive mojo reply" slices (or "Receive {mojo_message_name}" if
98-- built with `extended_tracing_enabled`. On legacy Chrome versions,
99-- other appropriate messages (like "Connector::DispatchMessage") are used.
100--
101-- @column STRING interface_name    Name of the IPC interface.
102-- @column INT ipc_hash             Hash of a message name.
103-- @column STRING message_type      Either 'message' or 'reply'.
104-- @column INT id                   Slice id.
105--
106-- Note: this might include messages received within a sync mojo call.
107-- TODO(altimin): This should use EXTEND_TABLE when it becomes available.
108CREATE PERFETTO TABLE _chrome_mojo_slices AS
109WITH
110-- Select all new-style (post crrev.com/c/3270337) mojo slices and
111-- generate |task_name| for them.
112-- If extended tracing is enabled, the slice name will have the full method
113-- name (i.e. "Receive content::mojom::FrameHost::DidStopLoading") and we
114-- should use it as a full name.
115-- If extended tracing is not enabled, we should include the interface name
116-- and method hash into the full name.
117new_mojo_slices AS (
118  SELECT
119    EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
120    EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
121    CASE name
122      WHEN "Receive mojo message" THEN "message"
123      WHEN "Receive mojo reply" THEN "reply"
124    END AS message_type,
125    id
126  FROM slice
127  WHERE
128    category GLOB '*toplevel*'
129    AND name GLOB 'Receive *'
130),
131-- Select old-style slices for channel-associated mojo events.
132old_associated_mojo_slices AS (
133  SELECT
134    name AS interface_name,
135    _extract_mojo_ipc_hash(id) AS ipc_hash,
136    "message" AS message_type,
137    id
138  FROM slice
139  WHERE
140    category GLOB "*mojom*"
141    AND name GLOB '*.mojom.*'
142),
143-- Select old-style slices for non-(channel-associated) mojo events.
144old_non_associated_mojo_slices AS (
145  SELECT
146    COALESCE(
147      EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.watcher_notify_interface_tag"),
148      EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag")
149    ) AS interface_name,
150    _extract_mojo_ipc_hash(id) AS ipc_hash,
151    "message" AS message_type,
152    id
153  FROM slice
154  WHERE
155    category GLOB "*toplevel*" AND name = "Connector::DispatchMessage"
156),
157merged AS (
158-- Merge all mojo slices.
159SELECT * FROM new_mojo_slices
160UNION ALL
161SELECT * FROM old_associated_mojo_slices
162UNION ALL
163SELECT * FROM old_non_associated_mojo_slices
164)
165SELECT * FROM merged ORDER BY id;
166
167-- This table contains a list of slices corresponding to the _representative_
168-- Chrome Java view operations.
169-- These are the outermost Java view slices after filtering out generic framework views
170-- (like FitWindowsLinearLayout) and selecting the outermost slices from the remaining ones.
171--
172-- @column id INT                       Slice id.
173-- @column ts INT                       Timestamp.
174-- @column dur INT                      Duration.
175-- @column name STRING                  Name of the view.
176-- @column is_software_screenshot BOOL  Whether this slice is a part of non-accelerated
177--                                      capture toolbar screenshot.
178-- @column is_hardware_screenshot BOOL  Whether this slice is a part of accelerated
179--                                      capture toolbar screenshot.
180CREATE PERFETTO TABLE _chrome_java_views AS
181WITH
182-- .draw, .onLayout and .onMeasure parts of the java view names don't add much, strip them.
183java_slices_with_trimmed_names AS (
184  SELECT
185    id,
186    REPLACE(
187      REPLACE(
188        REPLACE(
189          REPLACE(
190            REPLACE(
191              s1.name,
192              ".draw", ""),
193            ".onLayout", ""),
194          ".onMeasure", ""),
195        ".Layout", ""),
196      ".Measure", "") AS name,
197      ts,
198      dur
199    FROM
200      slice s1
201    -- Ensure that toplevel Java slices are not included, as they may be logged
202    -- with either category = "toplevel" or category = "toplevel,Java".
203    -- Also filter out the zero duration slices as an attempt to reduce noise as
204    -- "Java" category contains misc events (as it's hard to add new categories).
205    WHERE _java_not_top_level_category(category) AND dur > 0
206  ),
207  -- We filter out generic slices from various UI frameworks which don't tell us much about
208  -- what exactly this view is doing.
209  interesting_java_slices AS (
210    SELECT
211      id, name, ts, dur
212    FROM java_slices_with_trimmed_names
213    WHERE NOT name IN (
214      -- AndroidX.
215      "FitWindowsFrameLayout",
216      "FitWindowsLinearLayout",
217      "ContentFrameLayout",
218      "CoordinatorLayout",
219      -- Other non-Chrome UI libraries.
220      "ComponentHost",
221      -- Generic Chrome frameworks.
222      "CompositorView:finalizeLayers",
223      "CompositorViewHolder",
224      "CompositorViewHolder:layout",
225      "CompositorViewHolder:updateContentViewChildrenDimension",
226      "CoordinatorLayoutForPointer",
227      "OptimizedFrameLayout",
228      "ViewResourceAdapter:getBitmap",
229      "ViewResourceFrameLayout",
230      -- Non-specific Chrome slices.
231      "AppCompatImageButton",
232      "ScrollingBottomViewResourceFrameLayout",
233      -- Screenshots get their custom annotations below.
234      "ViewResourceAdapter:captureWithHardwareDraw",
235      "ViewResourceAdapter:captureWithSoftwareDraw",
236      -- Non-bytecode generated slices.
237      "LayoutDriver:onUpdate"
238    )
239)
240SELECT
241  s1.*,
242  -- While the parent slices are too generic to be used by themselves,
243  -- they can provide some useful metadata.
244  _has_parent_slice_with_name(
245    s1.id,
246    "ViewResourceAdapter:captureWithSoftwareDraw"
247  ) AS is_software_screenshot,
248  _has_parent_slice_with_name(
249    s1.id,
250    "ViewResourceAdapter:captureWithHardwareDraw"
251  ) AS is_hardware_screenshot
252FROM interesting_java_slices s1
253-- We select "outermost" interesting slices: interesting slices which
254-- do not another interesting slice in their parent chain.
255WHERE (SELECT count()
256  FROM ancestor_slice(s1.id) s2
257  JOIN interesting_java_slices s3 ON s2.id = s3.id) = 0;
258
259-- A list of slices corresponding to operations on interesting (non-generic)
260-- Chrome Java views. The view is considered interested if it's not a system
261-- (ContentFrameLayout) or generic library (CompositorViewHolder) views.
262--
263-- TODO(altimin): Add "columns_from slice" annotation.
264-- TODO(altimin): convert this to EXTEND_TABLE when it becomes available.
265CREATE PERFETTO VIEW chrome_java_views(
266  -- Name of the view.
267  filtered_name STRING,
268  -- Whether this slice is a part of non-accelerated capture toolbar screenshot.
269  is_software_screenshot BOOL,
270  -- Whether this slice is a part of accelerated capture toolbar screenshot.
271  is_hardware_screenshot BOOL,
272  -- Slice id.
273  slice_id LONG
274) AS
275SELECT
276  java_view.name AS filtered_name,
277  java_view.is_software_screenshot,
278  java_view.is_hardware_screenshot,
279  slice.id as slice_id
280FROM _chrome_java_views java_view
281JOIN slice USING (id);
282
283-- A list of Choreographer tasks (Android frame generation) in Chrome.
284CREATE PERFETTO VIEW _chrome_choreographer_tasks
285AS
286SELECT
287  id,
288  "Choreographer" AS kind,
289  ts,
290  dur,
291  name
292FROM slice
293WHERE name GLOB "Looper.dispatch: android.view.Choreographer$FrameHandler*";
294
295-- Extract task's posted_from information from task's arguments.
296CREATE PERFETTO FUNCTION _get_posted_from(arg_set_id LONG)
297RETURNS STRING AS
298WITH posted_from as (
299  SELECT
300    EXTRACT_ARG($arg_set_id, "task.posted_from.file_name") AS file_name,
301    EXTRACT_ARG($arg_set_id, "task.posted_from.function_name") AS function_name
302)
303SELECT file_name || ":" || function_name as posted_from
304FROM posted_from;
305
306-- Selects the BeginMainFrame slices (which as posted from ScheduledActionSendBeginMainFrame),
307-- used for root-level processing. In top-level/Java based slices, these will correspond to the
308-- ancestor of descendant slices; in long-task tracking, these tasks will be
309-- on a custom track and will need to be associated with children by timestamp
310-- and duration. Corresponds with the Choreographer root slices in
311-- chrome_choreographer_tasks below.
312--
313-- Schema:
314-- @column is            The slice id.
315-- @column kind          The type of Java slice.
316-- @column ts            The timestamp of the slice.
317-- @column name          The name of the slice.
318CREATE PERFETTO FUNCTION _select_begin_main_frame_java_slices(
319  name STRING)
320RETURNS TABLE(id LONG, kind STRING, ts TIMESTAMP, dur DURATION, name STRING) AS
321SELECT
322  id,
323  "SingleThreadProxy::BeginMainFrame" AS kind,
324  ts,
325  dur,
326  name
327FROM slice
328WHERE
329  (name = $name
330    AND _get_posted_from(arg_set_id) =
331        "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame");
332
333-- A list of Chrome tasks which were performing operations with Java views,
334-- together with the names of these views.
335-- @column id INT            Slice id.
336-- @column kind STRING       Type of the task.
337-- @column java_views STRING Concatenated names of Java views used by the task.
338CREATE PERFETTO VIEW _chrome_slices_with_java_views AS
339WITH
340  -- Select UI thread BeginMainFrames (which are Chrome scheduler tasks) and
341  -- Choreographer frames (which are looper tasks).
342  root_slices AS (
343    SELECT id, kind
344    FROM _SELECT_BEGIN_MAIN_FRAME_JAVA_SLICES('ThreadControllerImpl::RunTask')
345    UNION ALL
346    SELECT id, kind FROM _chrome_choreographer_tasks
347  ),
348  -- Intermediate step to allow us to sort java view names.
349  root_slice_and_java_view_not_grouped AS (
350    SELECT
351      root.id, root.kind, java_view.name AS java_view_name
352    FROM root_slices root
353    JOIN descendant_slice(root.id) child
354    JOIN _chrome_java_views java_view ON java_view.id = child.id
355  )
356SELECT
357  root.id,
358  root.kind,
359  GROUP_CONCAT(DISTINCT java_view.java_view_name) AS java_views
360FROM root_slices root
361LEFT JOIN root_slice_and_java_view_not_grouped java_view USING (id)
362GROUP BY root.id;
363
364-- A list of tasks executed by Chrome scheduler.
365CREATE PERFETTO TABLE _chrome_scheduler_tasks AS
366SELECT
367  id
368FROM slice
369WHERE
370  category GLOB "*toplevel*"
371  AND (name = "ThreadControllerImpl::RunTask" OR name = "ThreadPool_RunTask")
372ORDER BY id;
373
374-- A list of tasks executed by Chrome scheduler.
375CREATE PERFETTO VIEW chrome_scheduler_tasks(
376  -- Slice id.
377  id LONG,
378  -- Type.
379  type STRING,
380  -- Name of the task.
381  name STRING,
382  -- Timestamp.
383  ts TIMESTAMP,
384  -- Duration.
385  dur DURATION,
386  -- Utid of the thread this task run on.
387  utid LONG,
388  -- Name of the thread this task run on.
389  thread_name STRING,
390  -- Upid of the process of this task.
391  upid LONG,
392  -- Name of the process of this task.
393  process_name STRING,
394  -- Same as slice.track_id.
395  track_id LONG,
396  -- Same as slice.category.
397  category STRING,
398  -- Same as slice.depth.
399  depth LONG,
400  -- Same as slice.parent_id.
401  parent_id LONG,
402  -- Same as slice.arg_set_id.
403  arg_set_id LONG,
404  -- Same as slice.thread_ts.
405  thread_ts TIMESTAMP,
406  -- Same as slice.thread_dur.
407  thread_dur DURATION,
408  -- Source location where the PostTask was called.
409  posted_from STRING
410) AS
411SELECT
412  task.id,
413  "chrome_scheduler_tasks" as type,
414  _format_scheduler_task_name(
415    _get_posted_from(slice.arg_set_id)) as name,
416  slice.ts,
417  slice.dur,
418  thread.utid,
419  thread.name as thread_name,
420  process.upid,
421  process.name as process_name,
422  slice.track_id,
423  slice.category,
424  slice.depth,
425  slice.parent_id,
426  slice.arg_set_id,
427  slice.thread_ts,
428  slice.thread_dur,
429  _get_posted_from(slice.arg_set_id) as posted_from
430FROM _chrome_scheduler_tasks task
431JOIN slice using (id)
432JOIN thread_track ON slice.track_id = thread_track.id
433JOIN thread using (utid)
434JOIN process using (upid)
435ORDER BY task.id;
436
437-- Select the slice that might be the descendant mojo slice for the given task
438-- slice if it exists.
439CREATE PERFETTO FUNCTION _get_descendant_mojo_slice_candidate(
440  slice_id LONG
441)
442RETURNS LONG AS
443SELECT
444  id
445FROM descendant_slice($slice_id)
446WHERE
447  -- The tricky case here is dealing with sync mojo IPCs: we do not want to
448  -- pick up sync IPCs when we are in a non-IPC task.
449  -- So we look at all toplevel events and pick up the first one:
450  -- for sync mojo messages, it will be "Send mojo message", which then
451  -- will fail.
452  -- Some events are excluded as they can legimately appear under "RunTask"
453  -- before "Receive mojo message".
454  category GLOB "*toplevel*" AND
455  name NOT IN (
456    "SimpleWatcher::OnHandleReady",
457    "MessagePipe peer closed")
458ORDER by depth, ts
459LIMIT 1;
460
461CREATE PERFETTO FUNCTION _descendant_mojo_slice(slice_id LONG)
462RETURNS TABLE(task_name STRING) AS
463SELECT
464  printf("%s %s (hash=%d)",
465    mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
466FROM slice task
467JOIN _chrome_mojo_slices mojo
468  ON mojo.id = _get_descendant_mojo_slice_candidate($slice_id)
469WHERE task.id = $slice_id;
470
471-- A list of "Chrome tasks": top-level execution units (e.g. scheduler tasks /
472-- IPCs / system callbacks) run by Chrome. For a given thread, the tasks
473-- will not intersect.
474--
475-- @column task_name STRING  Name for the given task.
476-- @column task_type STRING  Type of the task (e.g. "scheduler").
477-- @column scheduling_delay LONG
478CREATE PERFETTO TABLE _chrome_tasks AS
479WITH
480-- Select slices from "toplevel" category which do not have another
481-- "toplevel" slice as ancestor. The possible cases include sync mojo messages
482-- and tasks in nested runloops. Toplevel events may also be logged as with
483-- the Java category.
484non_embedded_toplevel_slices AS (
485  SELECT * FROM slice
486  WHERE
487    _any_top_level_category(category)
488    AND (SELECT count() FROM ancestor_slice(slice.id) anc
489      WHERE anc.category GLOB "*toplevel*" or anc.category GLOB "*toplevel.viz*") = 0
490),
491-- Select slices from "Java" category which do not have another "Java" or
492-- "toplevel" slice as parent. In the longer term they should probably belong
493-- to "toplevel" category as well, but for now this will have to do. Ensure
494-- that "Java" slices do not include "toplevel" slices as those would be
495-- handled elsewhere.
496non_embedded_java_slices AS (
497  SELECT
498    id,
499    name AS task_name,
500    "java" as task_type
501  FROM slice s
502  WHERE
503    _java_not_top_level_category(category)
504    AND (SELECT count()
505      FROM ancestor_slice(s.id) s2
506      WHERE s2.category GLOB "*toplevel*" OR s2.category GLOB "*Java*") = 0
507),
508-- Generate full names for tasks with java views.
509java_views_tasks AS (
510  SELECT
511    id,
512    printf('%s(java_views=%s)', kind, java_views) AS task_name,
513    _get_java_views_task_type(kind) AS task_type
514  FROM _chrome_slices_with_java_views
515),
516scheduler_tasks AS (
517  SELECT
518    id,
519    name as task_name,
520    "scheduler" as task_type
521  FROM chrome_scheduler_tasks
522),
523-- Select scheduler tasks which are used to run mojo messages and use the mojo names
524-- as full names for these slices.
525-- We restrict this to specific scheduler tasks which are expected to run mojo
526-- tasks due to sync mojo events, which also emit similar events.
527scheduler_tasks_with_mojo AS (
528  SELECT
529    -- We use the "RunTask" as the task, and pick up the name from its child
530    -- "Receive mojo message" event.
531    task.id,
532    receive_message.task_name,
533    "mojo" AS task_type
534  FROM
535    chrome_scheduler_tasks task
536  JOIN _DESCENDANT_MOJO_SLICE(task.id) receive_message
537  WHERE
538    task.posted_from IN (
539      "mojo/public/cpp/system/simple_watcher.cc:Notify",
540      "mojo/public/cpp/system/simple_watcher.cc:ArmOrNotify",
541      "mojo/public/cpp/bindings/lib/connector.cc:PostDispatchNextMessageFromPipe",
542      "ipc/ipc_mojo_bootstrap.cc:Accept")
543),
544navigation_tasks AS (
545  WITH tasks_with_readable_names AS (
546    SELECT
547      id,
548      _human_readable_navigation_task_name(task_name) as readable_name,
549      IFNULL(_extract_frame_type(id), 'unknown frame type') as frame_type
550    FROM
551      scheduler_tasks_with_mojo
552  )
553  SELECT
554    id,
555    printf("%s (%s)", readable_name, frame_type) as task_name,
556    'navigation_task' AS task_type
557  FROM tasks_with_readable_names
558  WHERE readable_name IS NOT NULL
559),
560-- Add scheduler and mojo full names to non-embedded slices from
561-- the "toplevel" category, with mojo ones taking precedence.
562non_embedded_toplevel_slices_with_task_name AS (
563  SELECT
564    task.id AS id,
565    COALESCE(
566        navigation.task_name,
567        java_views.task_name,
568        mojo.task_name,
569        scheduler.task_name,
570        task.name
571    ) AS name,
572    COALESCE(
573        navigation.task_type,
574        java_views.task_type,
575        mojo.task_type,
576        scheduler.task_type,
577        "other"
578    ) AS task_type
579  FROM non_embedded_toplevel_slices task
580  LEFT JOIN scheduler_tasks_with_mojo mojo ON mojo.id = task.id
581  LEFT JOIN scheduler_tasks scheduler ON scheduler.id = task.id
582  LEFT JOIN java_views_tasks java_views ON java_views.id = task.id
583  LEFT JOIN navigation_tasks navigation ON navigation.id = task.id
584)
585-- Merge slices from toplevel and Java categories.
586SELECT * FROM non_embedded_toplevel_slices_with_task_name
587UNION ALL
588SELECT * FROM non_embedded_java_slices
589ORDER BY id;
590
591-- A list of "Chrome tasks": top-level execution units (e.g. scheduler tasks /
592-- IPCs / system callbacks) run by Chrome. For a given thread, the slices
593-- corresponding to these tasks will not intersect.
594CREATE PERFETTO VIEW chrome_tasks(
595  -- Id for the given task, also the id of the slice this task corresponds to.
596  id LONG,
597  -- Name for the given task.
598  name STRING,
599  -- Type of the task (e.g. "scheduler").
600  task_type STRING,
601  -- Thread name.
602  thread_name STRING,
603  -- Utid.
604  utid LONG,
605  -- Process name.
606  process_name STRING,
607  -- Upid.
608  upid LONG,
609  -- Alias of |slice.ts|.
610  ts TIMESTAMP,
611  -- Alias of |slice.dur|.
612  dur DURATION,
613  -- Alias of |slice.track_id|.
614  track_id LONG,
615  -- Alias of |slice.category|.
616  category STRING,
617  -- Alias of |slice.arg_set_id|.
618  arg_set_id LONG,
619  -- Alias of |slice.thread_ts|.
620  thread_ts TIMESTAMP,
621  -- Alias of |slice.thread_dur|.
622  thread_dur DURATION,
623  -- STRING    Legacy alias for |name|.
624  full_name STRING
625) AS
626SELECT
627  cti.id,
628  cti.name,
629  task_type,
630  thread.name AS thread_name,
631  thread.utid,
632  process.name AS process_name,
633  thread.upid,
634  s.ts,
635  s.dur,
636  s.track_id,
637  s.category,
638  s.arg_set_id,
639  s.thread_ts,
640  s.thread_dur,
641  cti.name as full_name
642FROM _chrome_tasks cti
643JOIN slice s ON cti.id = s.id
644JOIN thread_track tt ON s.track_id = tt.id
645JOIN thread USING (utid)
646JOIN process USING (upid);
647