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