Home > IT > Article

Android Perfetto 系列 15:Boot Trace、长Time现场 Trace 与偶发问题抓取

2026-10-30  ·  Views: 255

现场长 Trace 调优时才考虑 ftrace_config.buffer_size_kb、buffer_size_lower_bound、drain_period_ms、drain_buffer_percent; 这些字段要先在短 Trace 里验证开销和设备兼容性。drain_buffer_percent 的当前语义从 Perfetto v48 引入,官方 proto 注释注明 Linux 内核低于 6.9 时不生效; 不要把它当作旧内核上替代 drain_period_ms 的General开关。

如果 ftrace 写入 2MB/s,64MB 只能留下约 32 秒; 如果现场打开 log、Track Event、camera/audio 事件,窗口还会缩短。要保留状况前 2 分钟,就要么减数据源,要么增大 Buffer,要么换成周期写文件。STOP trigger 未命中时不会返回 trace 统计结果,手动停止也不能绕过这个门槛。需要人工兜底时,应激活预先允许的人工 trigger,或另起不受该 trigger 限制的命名 snapshot/fallback session; snapshot 能否读取触发前数字也必须按版本验证。

UI jank preset 抓完后,先确认 FrameTimeline 真的存在:

1
2
3
4
5
SELECT 'expected' AS table_name, COUNT(*) AS rows
FROM expected_frame_timeline_slice
UNION ALL
SELECT 'actual' AS table_name, COUNT(*) AS rows
FROM actual_frame_timeline_slice;

再确认目标窗口内 App 和 SurfaceFlinger 都有帧记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
WITH target_window AS (
SELECT trace_start() AS ts, trace_dur() AS dur
),
frame_process AS (
SELECT
p.name AS process_name,
COUNT(*) AS frame_count,
MIN(a.ts) / 1e9 AS first_frame_s,
MAX(a.ts) / 1e9 AS last_frame_s
FROM actual_frame_timeline_slice a
JOIN process p USING (upid)
JOIN target_window tw
WHERE a.ts BETWEEN tw.ts AND tw.ts + tw.dur
AND (
p.name = 'com.example.app'
OR p.name = 'surfaceflinger'
OR p.name = '/system/bin/surfaceflinger'
OR p.cmdline LIKE '%surfaceflinger%'
)
GROUP BY p.name
)
SELECT
process_name,
frame_count,
first_frame_s,
last_frame_s
FROM frame_process
ORDER BY frame_count DESC;

如果怀疑 hardirq、softirq 或 kworker 抢 CPU,不要把这些事件放GF默认长 Trace。先做短窗口专项 preset,再按结果决定是否GF入现场方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data_sources {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "irq/irq_handler_entry"
ftrace_events: "irq/irq_handler_exit"
ftrace_events: "irq/softirq_entry"
ftrace_events: "irq/softirq_exit"
ftrace_events: "irq/softirq_raise"
ftrace_events: "workqueue/workqueue_queue_work"
ftrace_events: "workqueue/workqueue_execute_start"
ftrace_events: "workqueue/workqueue_execute_end"
}
}
}

长录制要周期写文件

几小时难题不能只靠内存 Buffer。这个片段只展示长录制相关字段,实际使用时再加数据源:

1
2
3
4
5
6
7
8
9
10
11
duration_ms: 3600000
prefer_suspend_clock_for_duration: true
write_into_file: true
file_write_period_ms: 10000
max_file_size_bytes: 2147483648
flush_period_ms: 30000

buffers {
size_kb: 32768
fill_policy: RING_BUFFER
}

duration_ms 默认不计算操作操作系统 suspend 时段。亮灭屏、待机、车机休眠这类按 wall-clock 看的现场问题,应该考虑 prefer_suspend_clock_for_duration: true; 它也会作用 trigger stop_delay_ms 的时段语义。

官方 buffers 文档给出的 Android scheduler tracing 典型值约 1 到 2 MB/s; 实际要以当前 preset 实测写入速率为准。可录制秒数按 max_file_size_bytes / 实测写入速率 估算。2GB 上限在 1 到 2 MB/s 下只有约 17 到 34 分钟,撑不到 1 小时; 要抓 1 小时,就要缩窄统计结果源、提高文件上限,或改成 summary/snapshot 策略。

log、syscall、page fault、camera/audio、过宽的 Track Event 都可能把写入速率放大一个数量级。flush_period_ms 对长 Trace 有价值,它能减少低频 data source 长时刻不Submit导致的乱序和导入问题; 高频 flush 会增加 producer 唤醒和 I/O 压力,现场 preset 通常从 10 到 30 秒试起,并把 Perfetto/Android 版本、write_flush_mode、实测写入速率写GF报告。

后台运行和安全性停止

This article is published by News for reference only.
123456789
Loading comments…

LinksApply

Alliance Network53