The Trace Processor is a C++ library (/src/trace_processor) that is able to ingest traces of various format and expose them in a massaged, higher level format, queryable through SQL queries. The trace processor is used:
trace_processor_shell
target (ninja -C out/xxx trace_processor_shell
).Supported input formats:
/sys/kernel/debug/tracing/trace
.Traces are raw because they are optimized for fast & low overhead writing. Despite being protos, their output is not ideal for being consumed by third parties as-is. Some data massaging is required.
Examples:
ts
Timestamp of the scheduling event, in nanoseconds. This comes from the CLOCK_BOOTTIME, when available.
dur
Duration of the scheduling event, in nanoseconds.
utid
ID of the thread. This is NOT the UNIX pid/tid (see below). This can be used to joined the thread
and process
tables.
cpu
CPU number where the scheduling event happened.
cycles
[WIP] Number of CPU cycles. This keeps into account cpu frequency changes that happened during the dur
interval. This is available only if the cpufreq
ftrace category has been enabled in the trace config.
upid
Unique process ID. This is NOT the UNIX pid. This is a sequence number generated by the trace processor to uniquely identify a process in the trace. This is to deal with the fact that UNIX pids can be recycled and two distinct processes which lifetimes don't overlap can be assigned the same pid.
name
Process name, as per /proc/pid/cmdline.
pid
The UNIX pid (also known as Thread Group ID in Linux). This also matches the tid of the process' main thread.
Example:
upid | name | pid |
---|---|---|
1 | /system/bin/logd | 601 |
2 | rcu_preempt | 7 |
3 | rcuop/4 | 44 |
4 | rcuop/6 | 60 |
utid
Unique thread ID. This is NOT the Linux pid or tid. Like the above, this is a sequence number generated by the trace processor to uniquely identify a thread in the trace.
upid
ID of the parent process in the process
table. This can be used to JOIN a thread with its process.
name
Threaf name, as per /proc/pid/task/tid/comm.
tid
The Linux thread id (confusingly named “pid” in the Linux-world). For the process' main thread tid
== tgid
== pid
.
Example:
utid | upid | name | tid |
---|---|---|---|
1 | 1 | logd.klogd | 632 |
2 | 2 | rcu_preempt | 7 |
3 | 4 | rcuop/6 | 60 |
4 | 6 | rcuop/3 | 36 |
5 | 8 | sugov:0 | 588 |
6 | 9 | kworker/u16:6 | 9283 |
7 | 12 | sensors@1.0-ser | 1021 |
8 | 12 | HwBinder:797_1 | 1626 |
sched
(sched_switch events) tableselect ((select max(ts) from sched) - (select min(ts) from sched)) / 1e9 as duration_sec
select cpu, sum(dur)/1e9 as cpu_time_sec from sched group by cpu order by cpu
select process.name, pid from process limit 100
select process.name as proc_name, pid, thread.name as thread_name, tid from thread left join process using(upid) limit 100
select thread.name as thread_name, tid, cpu_sec from (select utid, sum(dur)/1e9 as cpu_sec from sched group by utid order by dur desc limit 100) inner join thread using(utid)
With matching process names
select thread.name as thread_name, process.name as proc_name, tid, pid, cpu_sec from (select utid, sum(dur)/1e9 as cpu_sec from sched group by utid order by dur desc limit 100) left outer join thread using(utid) left outer join process using(upid)
select process.name, tot_proc/1e9 as cpu_sec from (select upid, sum(tot_thd) as tot_proc from (select utid, sum(dur) as tot_thd from sched group by utid) join thread using(utid) group by upid) join process using(upid) order by cpu_sec desc limit 100;
select proc_name, cpu, cpu_sec from (select process.name as proc_name, upid, cpu, cpu_sec from (select cpu, utid, sum(dur)/1e9 as cpu_sec from sched group by utid) left join thread using(utid) left join process using(upid)) group by upid, cpu order by cpu_sec desc limit 100