Chromium Trace and Perfetto使用詳解

2023-10-27 21:00:36

1. Trace

chromium 在 base 庫中提供了 base::trace_event::TraceLog 類,該類是 TRACE_EVENT* , TRACE_COUNTER* 等宏的底層實現,關於這些宏定義見 base/trace_event/common/trace_event_common.h 。

使用 TraceLog 的流程:

  1. 建立 TraceLog 的 設定 TraceConfig;
  2. 開啟 TraceLog: base::trace_event::TraceLog::GetInstance()->SetEnabled(...) ;
  3. 使用 TRACE_EVENT* 等宏記錄 Trace: TRACE_EVENT0("test", "main") ;
  4. 如果設定了輸出到 console, 則不需要後續步驟了;
  5. 如果想要在程式中獲取到 Trace 的結果可以使用: base::trace_event::TraceLog::GetInstance()->Flush(...) ;

當使用 TRACE_EVENT(...) 來記錄 Trace 時,預設情況下 Trace 資料會記錄到 TraceLog::logged_events_ 中,流程如下:

TraceLog 只支援將 Trace 輸出到 console 或者返回給到程式中,不支援寫檔案或者多程序,但是它提供了 hook 介面 base::trace_event::TraceLog::SetAddTraceEventOverrides() , 允許外部 hook trace 的流程,從而實現自己的處理。在 chromium 中就使用了這種方式來支援多程序的 Trace。 如果有註冊 trace hook,則在 TraceLog::AddTraceEventWithThreadIdAndTimestamp 中會將資料發給之前註冊的 hook。

當用戶呼叫 Flush 的時候會將 TraceLog::logged_events_ 中的資料轉換為 json, 處理流程如下:

 直接使用 TraceLog 的 demo 見 demo_tracing_console.cc 

2. TracingService/Perfetto

chromium 使用 TraceLog 的 hook 機制擴充套件了 TraceLog, 如果程式啟動時新增了 --trace-startup=... 引數或者通過 chrome://tracing 來啟動 trace,則會向 TraceLog 註冊 3 個 TraceLog 的回撥, TraceEventDataSource::OnAddTraceEvent, TraceEventDataSource::FlushCurrentThread, TraceEventDataSource::OnUpdateDuration,流程如下:

 

註冊 hook 後,所有新的 Trace 都會被傳送給 hook 函數,也就是 tracing::TraceEventDataSource 類,這個類由 //services/tracing 服務提供,用來將 TraceLog 對接到 Perfetto 。 Perfetto 是一個跨平臺的 tracing 元件,包括一個可嵌入到其他程式中的 tracing 庫以及用來視覺化展示 trace 的工具 (https://ui.perfetto.dev/和<chrome://tracing>)。 關於 Perfetto 的詳細資訊見 https://perfetto.dev/.

在 chromium 中,Perfetto 被包裝進 TracingService,以便支援多程序的 Trace 追蹤,TracingService 的程式碼在 //services/tracing 目錄中。 直接使用 TracingService 的 demo 見 demo_tracing_perfetto.cc 。

下面的類圖反應了 TracingService 是如何支援多程序的:

 本來 Perfetto 也是支援多程序的,但是是使用自己定義的 IPC 通訊,chromium 使用 mojo 替換掉了原本的 IPC 機制,以便讓它更貼近 chromium, 並且可以支援 chromium 的沙箱機制。

3. Trace Viewer

獲取到的 Trace 資料可以使用 TraceViewer 進行視覺化,在 chromium 中使用 --trace-startup=... 或者 chrome://tracing 來獲得 Trace 檔案後可以使用 chrome://tracing 或者 https://ui.perfetto.dev/ 來檢視。 這兩個 Trace Viewer 不僅支援 json 格式的 Trace 檔案也支援 Android systrace 和 ftrace 格式。

如果你想使用 TraceViewer 但是又不想引入 Perfetto 的庫,可以自己將資料生成為 chrome json trace event 格式,在 base 庫中以及 swiftshader 中都採用了這種方式,因為這種 trace 資料格式並不複雜,例如以下格式就是合法的 Trace 格式:

TraceViewer 的一個例子:

 4. TracingService 的執行流程追蹤

啟動 TracingService 的時候會同時啟動 TraceLog,如下:

 

 首次收到 Trace,初始化 TraceWriter 用於記錄 Trace:

 將 Trace 儲存到 TraceWriter:

 結束 TracingSerivce 的時候會將 Trace 的結果轉換為 Json 格式:

 5. 參考資料