perfetto-sql
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGuidelines and Hints
指南与提示
-
Idempotency: Ensure queries are idempotent to prevent "already exists" errors during multiple executions.
- For Perfetto objects, always use :
CREATE OR REPLACE,CREATE OR REPLACE PERFETTO TABLE,CREATE OR REPLACE PERFETTO VIEW,CREATE OR REPLACE PERFETTO FUNCTION.CREATE OR REPLACE PERFETTO MACRO - For SQLite Virtual Tables (such as ),
SPAN_JOINis not supported. Explicitly drop them first:CREATE OR REPLACEDROP TABLE IF EXISTS my_table; CREATE VIRTUAL TABLE my_table USING SPAN_JOIN(...); - For standard SQLite indexes, prepend .
DROP INDEX IF EXISTS index_name;
- For Perfetto objects, always use
-
will crash if intervals within the same input table overlap. Always use the
SPAN_JOIN(for example,PARTITIONED {column}) clause to isolate intervals.PARTITIONED upid -
Intermediate tables fed into amust be materialized using
SPAN_JOIN, notCREATE PERFETTO TABLE.CREATE VIEW -
Trace Boundaries (): Slices or thread states that don't finish before the trace ends are recorded with
dur = -1. When calculating a bounding box (for example,dur = -1) or summing durations (ts + dur), handle incomplete durations using:SUM(dur).IIF(dur = -1, trace_end() - ts, dur) -
Robust State Transitions: Avoid manual timestamp arithmetic (for example,) to join adjacent events. Rely on standard library modules (for example,
ts + dur = next.ts,sched.runnable,linux.perf.counters) which safely handle trace gaps and preemptions.intervals.overlap -
Unique Identifiers: When writing SQL queries in Perfetto, you must join tables using(unique thread ID) or
utid(unique process ID) instead of the regularupidortid. Why it's useful : The operating system recyclespidandTIDs, whilePIDsandUTIDsremain unique for the lifetime of the trace, which prevents incorrect joins.UPIDs -
Safe Argument Extraction: Useto extract dictionary or JSON-like properties from slices or tracks. Don't attempt string parsing.
EXTRACT_ARG(arg_set_id, 'key') -
String Matching (Always use GLOB): Useinstead of
GLOB.LIKEcauses performance bottlenecks and treats underscores (LIKE) as wildcards, leading to bugs._- Exact matches: Use .
= - Substring matches: Use with
GLOB(for example,*).name GLOB '*RenderThread*' - Case-insensitive matches: Use and make sure the search string is fully lowercase (for example,
LOWER(name) GLOB). Use this when dealing with inconsistent trace capitalization (for example,LOWER(name) GLOB '*renderthread*'versusWakeLock).wakelock
- Exact matches: Use
-
Calculating Time Overlaps: To calculate the overlap duration between two time intervalsand
[start1, end1]:[start2, end2]Precedence Rule: Always prefer usingor standard library functions (for example,SPAN_JOIN) to calculate overlaps between two different sets of intervals . Avoid manual arithmetic if a standard library feature orintervals.overlapcan achieve the same result. Use the following logic if no built-in alternative exists.SPAN_JOIN-
Condition: The intervals overlap ifand
start1 < end2.start2 < end1 -
Duration: The overlap duration is calculated as
MIN(end1, end2) - MAX(start1, start2)Important: Incomplete Perfetto slices have a duration of -1 (). Always calculate the effective end time usingdur = -1before applying this logic.ts + IIF(dur = -1, trace_end() - ts, dur)
-
-
Queryfor app startup requests.
android_thread_slices_for_all_startups -
Joinwith
counter_trackto get values of counter with a specific name.counter -
When querying for a CPU frequency counter, include themodule and use the
linux.cpu.frequencytable.cpu_frequency_counters -
When looking for events around a specific timestamp, start with 100ms as the window size.
-
Always prefix column names with table or view alias, that is:.
{alias}.{column_name} -
To calculate the total time spent in slices matching a specific name pattern (for example,), you must sum their durations. Why it's useful : This helps quantify the total impact of a specific function or feature on performance across multiple calls. Here is an example query (note the safe handling of incomplete slices):
*{name_pattern}*sql SELECT count(*) as total_count, sum(IIF(slice.dur = -1, trace_end() - slice.ts, slice.dur)) / 1000000.0 as total_dur_ms FROM slice WHERE slice.name GLOB '*{name_pattern}*';
-
幂等性:确保查询具备幂等性,避免多次执行时出现"已存在"错误。
- 对于Perfetto对象,始终使用:
CREATE OR REPLACE,CREATE OR REPLACE PERFETTO TABLE,CREATE OR REPLACE PERFETTO VIEW,CREATE OR REPLACE PERFETTO FUNCTION.CREATE OR REPLACE PERFETTO MACRO - 对于SQLite虚拟表(如),不支持
SPAN_JOIN。需先显式删除:CREATE OR REPLACEDROP TABLE IF EXISTS my_table; CREATE VIRTUAL TABLE my_table USING SPAN_JOIN(...); - 对于标准SQLite索引,前置.
DROP INDEX IF EXISTS index_name;
- 对于Perfetto对象,始终使用
-
会在同一输入表内的时间区间重叠时崩溃。务必使用
SPAN_JOIN子句(例如PARTITIONED {column})来隔离区间。PARTITIONED upid -
传入的中间表必须使用
SPAN_JOIN实现物化,而非CREATE PERFETTO TABLE。CREATE VIEW -
跟踪边界():在跟踪结束前未完成的切片或线程状态会被记录为
dur = -1。计算边界框(例如dur = -1)或求和时长(ts + dur)时,需使用以下方式处理未完成的时长:SUM(dur).IIF(dur = -1, trace_end() - ts, dur) -
可靠状态转换:避免手动进行时间戳运算(例如)来关联相邻事件。依赖标准库模块(如
ts + dur = next.ts,sched.runnable,linux.perf.counters),这些模块可安全处理跟踪间隙和抢占情况。intervals.overlap -
唯一标识符:在Perfetto中编写SQL查询时,必须使用(唯一线程ID)或
utid(唯一进程ID)来关联表,而非常规的upid或tid。作用:操作系统会回收pid和TIDs,而PIDs和UTIDs在整个跟踪周期内保持唯一,可避免错误关联。UPIDs -
安全参数提取:使用从切片或轨迹中提取字典或类JSON属性。不要尝试字符串解析。
EXTRACT_ARG(arg_set_id, 'key') -
字符串匹配(始终使用GLOB):使用而非
GLOB。LIKE会导致性能瓶颈,且会将下划线(LIKE)视为通配符,引发bug。_- 精确匹配:使用.
= - 子串匹配:结合使用
*(例如GLOB).name GLOB '*RenderThread*' - 不区分大小写匹配:使用,并确保搜索字符串全为小写(例如
LOWER(name) GLOB)。当跟踪数据大小写不一致时(如LOWER(name) GLOB '*renderthread*'与WakeLock),可使用此方法。wakelock
- 精确匹配:使用
-
计算时间重叠:计算两个时间区间和
[start1, end1]的重叠时长:[start2, end2]优先级规则:计算两组不同区间之间的重叠时,始终优先使用或标准库函数(如SPAN_JOIN)。若标准库功能或intervals.overlap可实现相同结果,避免手动运算。若无内置替代方案,可使用以下逻辑:SPAN_JOIN-
条件:当且
start1 < end2时,区间存在重叠。start2 < end1 -
时长:重叠时长计算公式为
MIN(end1, end2) - MAX(start1, start2)重要提示:未完成的Perfetto切片时长为-1()。应用此逻辑前,务必使用dur = -1计算有效结束时间。ts + IIF(dur = -1, trace_end() - ts, dur)
-
-
查询获取应用启动请求数据。
android_thread_slices_for_all_startups -
关联与
counter_track表,获取特定名称计数器的值。counter -
查询CPU频率计数器时,需包含模块,并使用
linux.cpu.frequency表。cpu_frequency_counters -
查找特定时间戳附近的事件时,初始窗口大小设为100ms。
-
始终为列名添加表或视图别名前缀,即:.
{alias}.{column_name} -
计算匹配特定名称模式(例如)的切片总耗时,需对其时长求和。作用:这有助于量化特定函数或功能在多次调用中对性能的总体影响。以下是示例查询(注意对未完成切片的安全处理):
*{name_pattern}*sql SELECT count(*) as total_count, sum(IIF(slice.dur = -1, trace_end() - slice.ts, slice.dur)) / 1000000.0 as total_dur_ms FROM slice WHERE slice.name GLOB '*{name_pattern}*';
Resources
资源
- Documentation: The Perfetto Standard Library documentation is in . Use this file as a reference to discover available modules, find schemas (columns and types) for specific tables or views, or determine the
perfetto-stdlib.mdstatements required before drafting SQL query.INCLUDE PERFETTO MODULE - Execution Tool: Queries are executed using the official wrapper script downloaded directly from Perfetto. Output is returned in pure CSV format.
trace_processor
- 文档:Perfetto标准库文档位于。可参考此文件了解可用模块、查找特定表或视图的Schema(列和类型),或确定编写SQL查询前所需的
perfetto-stdlib.md语句。INCLUDE PERFETTO MODULE - 执行工具:查询通过直接从Perfetto下载的官方包装脚本执行。输出为纯CSV格式。
trace_processor
Execution Protocol
执行流程
You must follow these steps sequentially, mirroring a multi-agent pipeline:
你必须按顺序遵循以下步骤,模拟多Agent流水线:
Step 0: Tool Setup
步骤0:工具设置
Fetch the Wrapper: You must use the top level of the current project workspace ().
./trace_processorCRITICAL GUARDRAIL: NEVER use filesystem search tools (,find,find_by_name,grep,dir /s) across the home directory or workspace to locateGet-ChildItem— unconstrained searches across entire workspaces will stop responding or time out.trace_processor
Perform a direct file check at the top level of your workspace (e.g., ). If missing, download directly into the root workspace (), make it executable on macOS/Linux (), and ensure is added to . Execute queries directly via (on Windows, explicitly invoke ).
ls trace_processorhttps://get.perfetto.dev/trace_processorcurl -LOchmod +xtrace_processor.gitignore./trace_processorpython trace_processorImportant: The file served at this URL is aPython wrapper script. Don't assume the download failed because it is human-readable text. This is the intended behavior. This script handles lazy-loading the precompiled binary automatically on its first run. Use it directly.~10KB
获取包装脚本:必须使用当前项目工作区的顶层目录()。
./trace_processor关键约束:绝不要使用文件系统搜索工具(,find,find_by_name,grep,dir /s)在主目录或整个工作区中查找Get-ChildItem——无限制的全工作区搜索会导致响应停止或超时。trace_processor
直接检查工作区顶层目录的文件(例如)。若缺失,直接将下载到工作区根目录(使用),在macOS/Linux上设置可执行权限(),并确保被添加到中。通过直接执行查询(在Windows上,显式调用)。
ls trace_processorhttps://get.perfetto.dev/trace_processorcurl -LOchmod +xtrace_processor.gitignore./trace_processorpython trace_processor重要提示:该URL提供的文件是一个约10KB的Python包装脚本。不要因它是人类可读的文本就认为下载失败,这是预期行为。该脚本会在首次运行时自动延迟加载预编译二进制文件。直接使用即可。
Step 1: Dissection and Schema Research
步骤1:拆解与Schema研究
- Identify the core question, required data points, and filtering conditions.
- Precedence Rule: If the user's request contains a SQL query, use it without modification and skip to Step 2 for validation.
- Mandatory Schema and Module Search: For every table or view you plan to use, you MUST find its schema in . Don't read the entire documentation file --- it consumes the context window. Follow this precise workflow:
perfetto-stdlib.md- Discovery and Search: Use available search tools (,
grepor file search) with line limits to discover relevant views, tables or modules based on your problem domain and high-level intents (for example, 'CPU time', 'running time', 'overlap', 'jank').read_file- Why: Searching solely for exact table names misses comprehensive, pre-computed views built for these analyses.
- Note: You must verify if a Standard Library module already provides the needed abstraction before drafting manual arithmetic or custom functions.
- Targeted Bounded Reads: Once you identify the relevant modules, efficiently read the tables and views within that module section.
- Extract: Extract only the schema, columns, and the exact statements for the required object from the documentation.
INCLUDE PERFETTO MODULE - Verify: Review the columns, types, and descriptions to ensure the table matches your needs.
- Discovery and Search: Use available search tools (
- Print the research results before drafting the query:
- Tables/Views: listing columns and types.
Schema for {name}:
- 确定核心问题、所需数据点和过滤条件。
- 优先级规则:若用户请求中包含SQL查询,请勿修改直接使用,并跳至步骤2进行验证。
- 强制Schema与模块搜索:对于计划使用的每个表或视图,必须在中找到其Schema。不要通读整个文档文件——这会占用上下文窗口。请遵循以下精确流程:
perfetto-stdlib.md- 发现与搜索:使用可用的搜索工具(,
grep或文件搜索)并设置行数限制,根据问题领域和高层意图(例如'CPU时间', '运行时间', '重叠', '卡顿')查找相关视图、表或模块。read_file- 原因:仅搜索确切表名会错过为这些分析构建的全面预计算视图。
- 注意:编写手动运算或自定义函数前,必须验证标准库模块是否已提供所需的抽象。
- 定向有限读取:确定相关模块后,高效读取该模块部分内的表和视图。
- 提取:仅从文档中提取所需对象的Schema、列和确切的语句。
INCLUDE PERFETTO MODULE - 验证:检查列、类型和描述,确保表符合需求。
- 发现与搜索:使用可用的搜索工具(
- 编写查询前打印研究结果:
- 表/视图:列出列和类型。
{name}的Schema:
Step 2: Draft and Validate Loop (Max 3 Iterations)
步骤2:编写与验证循环(最多3次迭代)
Draft the SQL query in SQLite syntax using only the schemas retrieved in
Step 1. After drafting, you must validate against this checklist:
-
[ ] SQLite Syntax: Does the query parse successfully without syntax errors?
-
[ ] Idempotency: Are all object creations safe to re-run? (Did you useand
CREATE OR REPLACE PERFETTOfor virtual tables?)DROP TABLE IF EXISTS -
[ ] Existence: Were all tables found in the documentation?
-
[ ] Intent Check: Is there a pre-existing standard library table or view that will fulfill this intent before instead of writing manual arithmetic?
-
[ ] Column Accuracy: Do columns match the retrieved schemas?
-
[ ] Alias Check: Are ALL column names prefixed with their table or view alias (for example,)?
alias.column_name -
[ ] Module Check: Arestatements included for all non-prelude modules? You must use the exact module names provided in the documentation.
INCLUDE PERFETTO MODULE -
[ ] Span Join Check: If using, are tables safely
SPAN_JOINto prevent overlapping interval crashes? Are intermediate tables materialized withPARTITIONED?CREATE PERFETTO TABLE -
[ ] No LIKE Constraint: Did you map string matches usingor
GLOBinstead of prohibited=?LIKE -
[ ] Execution Check: You MUST run queries using the standalonewrapper with the
./trace_processorflag:--query-string../trace_processor --query-string "QUERY" {trace_file}Execution Rules:- File Usage : If you must create a SQL file to execute queries (for example, due to query length or escaping issues), you must create them in the directory.
/tmp/ - State: The execution is purely ephemeral. Database state does not persist across turns. You cannot share state (like views or tables) across queries in different turns. Every query must be standalone and fully self-contained.
- Failure Resilience: Debug and fix SQL syntax and logic errors when query fails.Don't simplify the analytical intent to pass validation. For example, if requested to calculate an overlap or intersection, you must fix the intersection math. Don't substitute with disjoint queries (for example, returning independent total durations) as a workaround.
- File Usage : If you must create a SQL file to execute queries (for example, due to query length or escaping issues), you must create them in the
使用仅在步骤1中获取的Schema,以SQLite语法编写SQL查询。编写完成后,必须对照以下清单进行验证:
-
[ ] SQLite语法:查询能否成功解析,无语法错误?
-
[ ] 幂等性:所有对象创建操作是否可安全重复执行?(是否对Perfetto对象使用了,对虚拟表使用了
CREATE OR REPLACE PERFETTO?)DROP TABLE IF EXISTS -
[ ] 存在性:所有表是否都在文档中找到?
-
[ ] 意图检查:是否存在预先定义的标准库表或视图可满足该意图,无需编写手动运算?
-
[ ] 列准确性:列是否与获取的Schema匹配?
-
[ ] 别名检查:是否所有列名都添加了表或视图别名前缀(例如)?
alias.column_name -
[ ] 模块检查:是否为所有非预加载模块添加了语句?必须使用文档中提供的确切模块名称。
INCLUDE PERFETTO MODULE -
[ ] SPAN_JOIN检查:若使用,是否已通过
SPAN_JOIN安全处理表以避免重叠区间崩溃?中间表是否使用PARTITIONED实现物化?CREATE PERFETTO TABLE -
[ ] 无LIKE约束:是否使用或
GLOB进行字符串匹配,而非禁用的=?LIKE -
[ ] 执行检查:必须使用独立的包装脚本,通过
./trace_processor标志执行查询:--query-string../trace_processor --query-string "QUERY" {trace_file}执行规则:- 文件使用:若因查询长度或转义问题必须创建SQL文件执行,必须将其创建在目录下。
/tmp/ - 状态:执行是纯临时的。数据库状态不会在多轮会话中保留。无法在不同轮次的查询之间共享状态(如视图或表)。每个查询必须独立且完全自包含。
- 故障恢复:查询失败时,调试并修复SQL语法和逻辑错误。不要为通过验证而简化分析意图。例如,若要求计算重叠或交集,必须修复交集运算逻辑。不要用替代方案(如返回独立的总时长)作为变通方法。
- 文件使用:若因查询长度或转义问题必须创建SQL文件执行,必须将其创建在
Step 3: Final Output
步骤3:最终输出
- Explicitly return and state the final validated SQL and explain the results to the user.
- Before finishing your response, delete all temporary SQL files you created in directory.
/tmp/
- 明确返回并说明最终验证后的SQL,并向用户解释结果。
- 结束响应前,删除所有在目录下创建的临时SQL文件。
/tmp/