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