一、原理和基本流程

Systrace是android性能調試優化的常用工具,它可以收集進程的活動信息,如界面佈局、UI渲染、binder通信等;也可以收集內核信息,如cpu調度、IO活動、中斷等;這些信息會統一時間軸,在Chrome瀏覽器中顯示出來,非常方便工程師性能調試、優化卡頓等工作。

簡易的流程圖如下,systrace是基於ftrace實現的,而ftrace 是 Linux 內核中的調試跟蹤機制。

  1. 首先systrace指定抓取trace的類別等參數,然後觸發手機端的/system/bin/atrace 開啓對應文件節點的信息記錄,接着atrace會讀取 ftrace 的緩存,生成只包含ftrace信息的atrace_raw。

  2. Systrace會進一步收集系統的ps、task等信息,這些信息是爲了協助解析atrace_raw中的ftrace信息,比如ps信息可以得到進程的名稱,而不是難記的pid號。處理後的ftrace信息將和systrace目錄下的prefix.html、systrace_trace_viewer.html、suffix.html整合爲一體,成爲單個的html文件。

  3. 當瀏覽systrace信息時,Chrome瀏覽器藉助systrace解析器(通過chrome://tracing訪問),解析上面生成的trace.html文件,把其中原始的ftrace信息分門別類,再按照時間軸聚合排列,繪製出不同色塊,簡潔可觀的顯示在html頁面上。

二、具體實現

Systrace是怎麼把系統多種多樣的信息都整合進ftrace中的呢?請看下圖:

Systrace抓取的trace數據,總體上可以分爲兩類,一類是Java和Native在用戶層發生的函數調用,一類是內核態的事件信息。

用戶層的函數調用,其實最終事件記錄都是同一個文件節點/sys/kernel/debug/tracing/trace_marker。

此節點允許用戶層寫入字符串,ftrace會記錄該寫入操作時的時間戳,當用戶在上層調用不同函數時,寫入不同的調用信息,比如函數進入和退出分別寫入,那麼ftrace就可以記錄跟蹤函數的運行時間。

atrace在處理用戶層的多種trace類別時,僅僅是激活不同的TAG,如用戶選擇了Input類別,則激活ATRACE_TAG_INPUT;選中Graphics則激活ATRACE_TAG_GRAPHICS,記錄調用的流程都是一樣的,最終都是記錄到trace_marker。

內核態的事件信息,則不是統一的,需要激活各自對應的事件節點,讓ftrace記錄下不同事件的tracepoint。例如激活進程調度信息記錄,需要激活如下相關節點:

events/sched/sched_switch/enable

events/sched/sched_wakeup/enable

內核在運行時,根據節點的使能狀態,會往ftrace緩衝中打點記錄事件。

最終,上述兩類事件記錄都彙集到同一緩衝中,然後atrace工具會回讀抓取,保存下來就是原始的systrace信息。

三、顯示定製信息

Systrace的參數設置和使用方法,網絡上內容已經不勝枚舉,就不再累述。下面講解一下較少闡述的顯示定製信息功能。

一般情況下,默認的systrace各種trace類別已經涵蓋了系統的各個方面,足夠工程師分析調試了。但某些特定情況下,工程師需要增加自定義的trace類別,並同樣集成到systrace中。比如工程師需要觀察到內核各個run queue的隊列深度,那麼他應該怎麼做呢?

1.新加定製的trace類別

既然原有的systrace trace不能滿足,需要新增一項。可以去frameworks/native/cmds/atrace/atrace.cpp中增加一類category, 如

2.內核增加對應的tracepoint

Systrace是基於ftrace的,那麼上面的類別需要在內核中增加對應節點。

在新建的sched_rq_running event中實現輸出新增的trace類別的信息,通過上面的1、2兩個步驟,在抓取systrace時選中新建類別kernel_runqueue, 則抓取的trace.html將包含sched_rq_running的信息。

假設新的信息如下:

3.顯示出sched_rq_running的信息

如果sched_rq_running.html 在 chrome裏面打開,我們並沒能發現自定義的任何信息顯示出來。這個是由於默認的chrome://tracing 解析器並不知道如何解析sched_rq_running的信息。

Systrace能夠解析顯示出進程調度的sched_wakeup、sched_switch等信息,那是因爲chrome://tracing 解析器知道如何解析進程調度信息,如下面格式的內容。

但是並不知道如何解析自定義的sched_rq_running信息。

這時候,我們就需要尋根溯源了,我們先找到systrace的生母,谷歌開源項目https://chromium.googlesource.com/catapult。

正是catapult生成了systrace及其解析器的工具。在catapult中,谷歌採用javascript實現了一個跨平臺的trace解析工具,我們可以參考tracing/tracing/extras/importer/linux_perf目錄下的各種解析器,比如sched_parser.html是用於解析進程調度信息的,power_parser是用於解析cpu頻率等信息的,學以致用生成自己定製的sched_rq_running_parser.html。

Catapult的各種解析器,可以理解爲先按照trace的類型分類處理,然後加入各個時段的採樣值。

如tracing/tracing/extras/importer/linux_perf/power_parser.html

實現瞭如何解析出cpu頻率信息:

<idle>-0     (-----) [001] d.Hb   948.300084: cpu_frequency: state=1344000 cpu_id=2

1)power_parser.html註冊了cpu_frequency信息由函數cpuFrequencyEvent處理

2) cpuFrequencyEvent分解cpu_frequency信息

3) 把cpu頻率採樣值加入Clock Frequency信息欄

在我們加入額外的sched_rq_running_parser.html解析器之後,需要使用tracing/tracing_build/generate_about_tracing_contents.py重新生成about_tracing.html和tracing.js(這裏需要改名,使之和about_tracing.html中的script腳本名稱相同)。

然後使用about_tracing.html作爲新的systrace解析器,代替默認的chrome://tracing,這時再把sched_rq_running.html放進來解析,我們就終於可以看到自定義的systrace信息了。

參考文獻

1、android源代碼

2、catapult源代碼

長按關注

內核工匠微信

Linux 內核黑科技 | 技術文章 | 精選教程

相關文章