RFC-0074:公開程序開始時間 | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 請確保可透過使用者空間查詢程序開始時間。 |
更小鳥 | |
作者 | |
審查人員 | |
提交日期 (年月分) | 2021-02-19 |
審查日期 (年-月-日) | 2021-03-11 |
摘要
我們重構 ZX_INFO_PROCESS
,以公開程序的開始時間,以及清除描述其執行階段的標記。假設有 ZX_INFO_PROCESS_FLAG_STARTED
標記存在,程序的開始時間有效,且將該程序定義為有效時呼叫 zx_process_start()
的單聲道時間。
提振精神
Chromium 首次在 crbug.com/726484 和 https://fxbug.dev/42105649 時要求這項功能,以便預留追蹤事件的基本時間,並擴充已支援 Linux、macOS 和 Windows 的各平台通用介面。 此外,我們也提交了 https://fxbug.dev/42119376,利用此項功能將運作時間納入當機報告。
設計
在簡單簡單的 ProcessDispatcher
延伸中,我們會記錄初始執行緒在 ProcessDispatcher::AddInitializedThread()
的時間,然後傳入 ProcessDispatcher::GetInfo()
;前者是 zx_process_start()
的主要「啟動」處理常式,後者則是用於處理 ZX_INFO_PROCESS
處理程序的 zx_get_object_info()
。
針對由 zx_object_get_info()
填入的結構,目前我們已經:
typedef struct zx_info_process {
// The process's return code; only valid if |exited| is true.
// If the process was killed, it will be one of the ZX_TASK_RETCODE values.
int64_t return_code;
// True if the process has ever left the initial creation state,
// even if it has exited as well.
bool started;
// If true, the process has exited and |return_code| is valid.
bool exited;
// True if a debugger is attached to the process.
bool debugger_attached;
uint8_t padding1[5];
} zx_info_process_t;
我們將其演化為:
typedef struct zx_info_process {
// The process's return code; only valid if the
// |ZX_PROCESS_INFO_FLAG_EXITED| flag is set. If the process was killed, it
// will be one of the |ZX_TASK_RETCODE| values.
int64_t return_code;
// The monotonic time at which zx_process_start() was called, only valid
// if the |ZX_INFO_PROCESS_FLAG_STARTED| flag is set.
zx_time_t start_time;
// Bitwise OR of ZX_INFO_PROCESS_FLAG_* values.
uint32_t flags;
uint8_t padding1[4];
} zx_info_process_t;
且會導入下列旗標值:
// Whether the process has started. zx_process_info_t::start_time is only
// valid if this flag is set.
#define ZX_INFO_PROCESS_FLAG_STARTED (1u << 0)
// Whether the process has exited.
#define ZX_INFO_PROCESS_FLAG_EXITED (1u << 1)
// Whether a debugger is attached to the process.
#define ZX_INFO_PROCESS_FLAG_DEBUGGER_ATTACHED (1u << 2)
布林值重構並非絕對必要,但這會讓 zx_info_process_t
符合目前的 Scall struct 政策,儲存邊框間距的位元組,而且不會增加執行此提案所需的工作量 (而且還能用相當多費的心力,為下一位工程師省下大量麻煩)。
實作
將舊的結構重新命名為
zx_info_process_v1_t
,並建立一個別名,以使用舊名稱參照 (zx_info_process_t
->zx_info_process_v1_t
)。將主題ZX_INFO_PROCESS
重新命名為ZX_INFO_PROCESS_V1
,並建立一個舊名稱的別名 (ZX_INFO_PROCESS
->ZX_INFO_PROCESS_V1
)。新增結構 (
zx_info_process_v2_t
) 和主題 (ZX_INFO_PROCESS_V2
)。變更核心以追蹤程序開始時間,並識別新的主題和結構。更新所有程式碼 (樹狀結構內和樹狀結構外) 以使用
ZX_INFO_PROCESS_V2
。變更
ZX_INFO_PROCESS
和zx_info_process_t
別名以參照 v2 主題和結構。等待先前的變更全面推出。
更新所有程式碼 (樹狀結構內和樹狀結構外) 以再次使用
ZX_INFO_PROCESS
。移除 v1 主題和結構,以及 v2 別名。
此外,這些類型的 Rust 和 Go 版本也會有所更新。
效能
新增的邏輯應該會產生可忽略的執行階段成本,特別是會在個別程序的生命週期內分攤費用。
安全性考量
如果程式已有處理程序的控制代碼,則它可以做到,且比程序啟動的時間還多。此外,在一些其他作業系統中已公開開始時間,沒有問題。
隱私權注意事項
請參閱上方的安全性考量。
測試
Zircon 的程序相關核心測試會延伸至斷言,例如,在 zx_process_start()
前後取得的樣本確實會記錄開始時間,而尚未啟動的程序未設定 ZX_INFO_PROCESS_FLAG_STARTED
。
說明文件
ZX_INFO_PROCESS
說明文件也會據此更新。
缺點、替代項目和未知
同時,也考慮將「開始」時間公開為更通用的工作層級概念 (如 ZX_INFO_TASK_RUNTIME
下方公開)。對執行緒來說,執行緒的開始時間就是呼叫 zx_thread_start()
的時間點。對工作來說,當第一個子項啟動時,通常會認為它「啟動」。不過,由於工作可以建立巢狀結構,因此會導致行走工作子樹狀結構,這比處理其他兩種工作類型更複雜。最終是決定停用擴充功能,因為這些擴充功能不符合目前的需求,讓我們可以避開工作階層步行的必要性。
優先藝術與參考資料
Linux:/proc/[pid]/stat
會公開 starttime
。FreeBSD:/proc/[pid]/status
會在以空格分隔的統計資料清單中公開開始時間。macOS:proc_pidinfo()
系統呼叫似乎曝露了這個情況。