RFC-0074:公开进程开始时间 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 使进程开始时间可从用户空间查询。 |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2021-02-19 |
审核日期(年-月-日) | 2021-03-11 |
摘要
我们重构了 ZX_INFO_PROCESS
,以显示进程的开始时间以及
清理描述其运行时的标志我们称进程具有
出现 ZX_INFO_PROCESS_FLAG_STARTED
标志的时间,并将其定义为
调用 zx_process_start()
的单调时间(如果有效)。
设计初衷
最初提交于 crbug.com/726484,然后是 https://fxbug.dev/42105649,Chromium 请求 该功能,以便为跟踪事件提供基准时间,从而延长 与平台无关的接口,已支持 Linux、macOS 和 Windows。 此外,有人提交了 https://fxbug.dev/42119376,以便利用这一相同功能: 在崩溃报告中纳入拨测
设计
在 ProcessDispatcher
的一个简单而又简单的扩展中,
初始线程的 ProcessDispatcher::AddInitializedThread()
时间
然后在 ProcessDispatcher::GetInfo()
中传递;第一种方法是
主要“开场白”zx_process_start()
的例程,而后者则是
zx_get_object_info()
,表示进程句柄的 ZX_INFO_PROCESS
。
对于由 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
(符合当前系统调用结构体政策),保存一个字节
而且不会增加执行此方法所需的工作量
提案(这样也能避免下一位工程师的麻烦)。
实现
将旧结构体重命名为
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
文档将进行相应更新。
缺点、替代方案和未知问题
此外,我们还考虑了公开“start”比较笼统地介绍
概念(例如在 ZX_INFO_TASK_RUNTIME
下提供)。对于线程,
以缩进方式扩展:线程的开始时间是
调用 zx_thread_start()
。对工作而言,最自然的表述是
“启动”当其第一个子级启动时。由于作业可以嵌套
不过,这会引入遍历任务子树,
这比处理另外两种任务类型要复杂。归根结底,
拒绝了这些扩展程序,因为它们无法满足当前的需求,
这样我们就可以回避对任务层次结构遍历的需求。
先验技术和参考资料
Linux:/proc/[pid]/stat
公开了 starttime
。
FreeBSD:/proc/[pid]/status
在以空格分隔的统计信息列表中公开开始时间。
macOS:proc_pidinfo()
系统调用似乎公开了此问题。