
Perfetto 轨迹查询实战trace_processor 会话模式、PerfettoSQL 与标准库模块【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto本文基于 Perfetto 仓库中的轨迹查询参考文档 ai/skills/perfetto/infra-references/querying.md系统讲解如何用trace_processor命令行工具和 PerfettoSQL 从各类轨迹文件.pftrace、.perfetto-trace、.pb、systrace、ftrace 文本、Chrome JSON中提取数据。读完后你将掌握“加载一次、查询多次”的命名后台会话工作流、通过__intrinsic_stdlib_objects进行标准库发现的方法以及避免常见陷阱的 PerfettoSQL 编写规则utid/upid 关联、dur -1语义、区间求交等。背景trace_processor 与 PerfettoSQLTrace Processor 是 Perfetto 的 C 库位于 src/trace_processor它导入多种格式的轨迹并暴露一套一致的 SQL 表接口供查询同时负责计算轨迹摘要、为轨迹事件附加人类可读的描述、从轨迹内容派生出新事件。大多数用户通过trace_processorshell 与它交互——这是一个命令行封装可以打开交互式 PerfettoSQL 提示符详见 docs/analysis/trace-processor.md。PerfettoSQL 则是把轨迹内容当作数据库来查询的 SQL 方言是 Perfetto 轨迹分析的基础详见 docs/analysis/perfetto-sql-getting-started.md。查询工作开始前需要保证trace_processor在PATH中。在仓库的 skill 环境里做法见 ai/skills/perfetto/environment-references/setup.md该环境把trace_processor打包在$SKILL_ROOT/bin/trace_processor首次调用时会自动下载并缓存宿主机平台的预编译二进制缓存于~/.local/share/perfetto/prebuilts/。注意不要单独下载另一个版本的trace_processor——该环境的包装脚本固定了与技能构建匹配的发布版本Windows 上则以python $SKILL_ROOT/bin/trace_processor方式调用。加载一次查询多次解析轨迹是慢的部分——大轨迹可能要数秒到数分钟。因此推荐做法是把轨迹加载进一个命名的后台会话之后所有查询都用--remote打向该会话trace_processor server unix --name mysession --daemonize TRACE_FILE trace_processor query --remote mysession SELECT ts, dur, name FROM slice WHERE dur 5e8 LIMIT 5 trace_processor query --remote mysession -f queries.sql # 长 SQL 从文件读取 trace_processor server kill mysession # 完全结束后这套用法有几个关键细节会话状态在多次调用之间持久化某次调用中执行的CREATE PERFETTO TABLE或INCLUDE PERFETTO MODULE在下一次--remote调用中依然可用。一次调用可包含多条以;分隔的语句。每个结果集都以 CSV 输出连续的结果集之间用一个空行分隔query子命令的帮助文本在 src/trace_processor/shell/query_subcommand.cc 中也有同样说明。轨迹加载类标志如--full-sort、--add-sql-package等要放在server unix的启动命令上而不是query --remote上——因为轨迹只在服务端加载一次。TRACE_FILE可以是本地路径、http(s)://URL 或 Perfetto UI 分享链接gzip 压缩的轨迹可以直接加载。空闲会话会在 30 分钟后被回收用完记得手动 kill。不带会话的trace_processor query TRACE_FILE ...每次调用都会重新解析轨迹只适合回答一个简单的一次性问题。源码印证会话与慢解析提示从源码结构看上述行为在 src/trace_processor/shell/server_subcommand.cc 中有完整实现server子命令支持http、stdio、unix、kill四种模式unix模式通过 AF_UNIX socket 按名称寻址让轨迹保持“温热”状态供重复的query --remote name调用。相关命令行标志包括--name会话名缺省自动生成、--path显式 socket 路径与--name互斥、--daemonizePOSIX 下脱离到后台、--idle-timeout例如30m、90sauto对 unix 模式即 30 分钟等定义见 server_subcommand.cc。30 分钟空闲回收默认值由常量kUnixDefaultIdleMs 30 * 60 * 1000给出见 server_subcommand.cc。server kill通过 socket 旁边的 pid 文件定位进程并发送SIGTERM若 pid 已失效则视为崩溃残留并清理KillServer。同时src/trace_processor/shell/query_subcommand.cc 实现了一个很实用的“自提示”机制一次性query TRACE调用每次都重新解析轨迹当解析耗时超过 1 秒时工具会向 stderr 打印一条提示告诉你如何改为“加载一次、复用会话”的用法Tip: parsing took %.1fs and query TRACE re-parses on every call. To run many queries, load once and reuse the session: trace_processor server unix --name S --daemonize %s trace_processor query --remote S SELECT ... trace_processor server kill S源码注释里还提到这一行提示是面向脚本和编码智能体它们读 stderr 不读--help设计的——“在智能体上的实测中正是这一行让 warm-session 用法从 0% 提升到超过 80%”。发现而不是猜测写查询前先弄清“数据在哪里”。参考文档给出四个发现手段-- 1) 精确查看任意表、视图或查询的列不扫描行 SELECT * FROM slice LIMIT 0; -- 2) 按关键词搜索标准库表、视图、函数、宏 SELECT qualified_name, object_type, short_description FROM __intrinsic_stdlib_objects WHERE exposed 1 AND regexp(startup|launch, summary, i) LIMIT 20; -- 3) 查看单个对象的完整文档参数、列、描述 SELECT summary FROM __intrinsic_stdlib_objects WHERE qualified_name android.startup.startups.android_startups; -- 4) 然后加载对应模块并使用 INCLUDE PERFETTO MODULE android.startup.startups; SELECT package, startup_type, dur / 1e6 AS ms FROM android_startups;从源码结构看__intrinsic_stdlib_objects是标准库文档插件注册的一个零参数、表形式的 intrinsic其表名与查询逻辑在 src/trace_processor/plugins/stdlib_docs/stdlib_docs.cc 中定义。参考文档同时提醒它是实现细节交互式使用时没问题但不要把它写进提交到仓库的脚本里。标准库为大多数常见问题提供了现成表且其视图已经把 thread 和 process 关联到了事件上——优先使用标准库而不是在原始表上手写 join。如果查询因 no such table 失败较新的trace_processor版本会在错误信息中直接指出应该INCLUDE哪个模块否则就按上面第 2 步搜索该表名。值得知道的原始表slice任何有持续时间的东西、thread、process、thread_state每线程 Running / Runnable / Sleeping、sched每 CPU 的在 CPU 区间、counter、track、args。常见问题的标准库模块速查表问题模块INCLUDE PERFETTO MODULE ...主表带线程/进程名的 sliceslices.with_contextthread_slice、process_slice、thread_or_process_slice每线程/进程的 CPU 时间sched.with_contextsched_with_thread_process应用启动及其阶段android.startup.startups、android.startup.startup_breakdownsandroid_startups、android_startup_opinionated_breakdown帧与卡顿android.frames.timelineandroid_framesANRandroid.anrsandroid_anrsBinder 事务android.binderandroid_binder_txns低内存杀进程、进程 RSSandroid.memory.lmk、linux.memory.processandroid_lmk_events、memory_rss_and_swap_per_processCPU 频率、集群linux.cpu.frequency、android.cpu.cluster_typecpu_frequency_counters、android_cpu_cluster_mappingJava 堆保留大小android.memory.heap_graph.dominator_tree见 heap_dump.mdCPU 采样调用栈stacks.cpu_profilingcpu_profiling_samples区间重叠 / 求交intervals.intersect、intervals.overlap_interval_intersect!、interval_merge_overlapping!、intervals_overlap_count!需要说明的是表中带!后缀的是标准库宏macro而非普通表。更完整的语言导览和表参考可参考仓库内的 PerfettoSQL 入门文档与 Trace Processor 参考仓库还提供 tools/gen_stdlib_docs_json.py 用来生成标准库文档数据。PerfettoSQL 编写规则参考文档总结了 11 条实战规则逐条展开如下用utid/upid关联不要用tid/pid。前者在整个轨迹内唯一后者是操作系统回收的标识。id、utid、track_id这类列可以作为 join 键但跨次运行不稳定向用户报告结论时应使用名字thread.name、process.name、slice.name。dur -1表示该 slice 在轨迹结束时仍未关闭dur 0表示瞬时事件。求和或取上界时使用IIF(dur -1, trace_end() - ts, dur)。字符串匹配用、GLOB *Render*或regexp(render, name, i)不要用LIKE——它慢而且_是通配符。优先聚合COUNT、SUM、GROUP BY、LIMIT不要倾倒原始行——一个轨迹可能有数百万行。让语句可重跑使用CREATE OR REPLACE PERFETTO TABLE|VIEW|FUNCTION|MACRO。虚拟表如SPAN_JOIN不支持OR REPLACE需要先DROP TABLE IF EXISTS x;。用CREATE PERFETTO TABLE物化昂贵的中间结果SPAN_JOIN的输入也要求是物化表。区间求交优先使用intervals.*模块或SPAN_JOIN。SPAN_JOIN要求整数PARTITIONED列且同一分区内 span 不能重叠否则会静默产生错误行。只有两者都不适用时才退回到手工算术overlap iff start1 end2 AND start2 end1交集时长dur MIN(end1, end2) - MAX(start1, start2)。事件属性用EXTRACT_ARG(arg_set_id, key)而不是手工 joinargs表。查询慢时执行EXPLAIN QUERY PLANslice/counter在ts和track_id上有索引其他过滤条件会触发扫描。逐行调用CREATE PERFETTO FUNCTION的开销很大优先使用普通 SQL、CTE 和标准库视图。标准工作循环参考文档把整个查询过程归纳为四步循环先陈述问题并判断哪张表/哪个模块能回答它写自定义 join 之前先搜索标准库。检查 schema对要用的每张表执行LIMIT 0查询确认列然后起草查询并对着会话运行。出错时读错误信息里的提示修改查询后重跑。不要用“把问题改小”的方式让查询通过例如把一次区间求交替换成两个独立的总量统计。把验证过的 SQL 与结果一起呈现并解释这些数字的含义明确区分“轨迹显示的事实”与“你推断出的结论”。这套循环也与仓库 skill 环境的报告规范一致多轮查询或按工作流执行的分析应把问题、轨迹文件、带具体数字的发现、可复跑的验证查询和待解问题写入 markdown 报告见 SKILL-template.md 的 Reporting 一节。小结Perfetto 轨迹查询的最佳实践可以浓缩为三句话用命名后台会话避免重复解析用LIMIT 0和__intrinsic_stdlib_objects做 schema 发现而不是凭记忆猜列名用utid/upid关联、dur -1归一化、聚合优先等 PerfettoSQL 规则保证查询既正确又快。结合仓库源码中 query_subcommand.cc 与 server_subcommand.cc 的实现可以清楚看到这些约定不是纸面条款而是工具链内建支撑会话生命周期管理、空闲回收、慢解析提示的工作方式。【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考