RFC-0007:移除了 Zircon 中的线程终止 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 本文档介绍了线程终止功能的移除以及移除该功能的原因。 |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2020-09-25 |
审核日期(年-月-日) | 2020-10-06 |
摘要
过去,zx_task_kill
允许用户模式终止单个线程。不过,终止单个线程会助长不良做法,并且很可能会导致进程处于不良状态。因此,应移除终止单个线程的功能。
动机和问题陈述
用户模式没有合理的用途来终止单个线程。公开此类设施会鼓励不良做法。
与其他系统一样,在 Fuchsia 上,终止线程是异步进行的;对于正在运行的线程,没有实用的方法来确定可以安全终止线程的确切位置。对于阻塞(等待)线程,更安全且通常更简单的解决方案是添加逻辑,以便在唤醒时线程自行退出。
终止线程的危险性
- 可以保留已获取的锁,包括控制堆的全局锁。
- 可能会发生内存泄漏。至少要包含线程堆栈,但通常还包含许多其他部分。
- 运行时处于不一致状态。至少对于 C 和 Go 运行时而言,这是正确的。
- 在线程执行系统调用时终止该线程会导致进程处于未知状态。内核没有问题,但进程无法知道发生了什么以及没有发生什么。
- 会破坏 RAII 封装容器和自动清理。事实上,它可以击败 Fuchsia 使用的高级语言提供的大多数保证。
设计
向线程传递句柄时,以下系统调用将失败并返回 ZX_ERR_NOT_SUPPORTED
:
zx_status_t zx_task_kill(zx_handle_t handle);
进程和作业仍可照常终止。
实现
幸运的是,Fuchsia 中不太常使用线程终止。唯一的用例是在用于检查线程是否遇到特定异常的测试代码中。我们将更新此代码,以便异常处理完毕后,发生异常的线程自行退出。对于无法恢复异常的代码,可以在线程恢复之前将发生异常的线程的指令指针直接设置为 zx_thread_exit 或运行时的线程退出函数。这些测试可能仍会泄露异常线程存储在堆上的内存,但运行时处于更好的状态,并且在测试进程退出时会收集泄露的内存。
性能
不适用
安全注意事项
不适用
隐私注意事项
不适用
测试
我们将更新 Zircon 核心测试,以确保 zx_task_kill 系统调用按预期运行。 可以进行一些静态分析,以查找传递线程的 zx_task_kill 的调用点。
我们将遵循完整的 Fuchsia 大规模更改 (LSC) 流程,以确保对此更改进行适当的测试。
文档
zx_task_kill 的文档将更新,以反映线程不可杀死。
缺点、替代方案和未知
此提案的替代方案是当前的现状,即允许终止线程。在 Fuchsia 的整个历史中,线程一直是可终止的,但没有任何可接受的用例是程序依赖于此行为的。因此,我们认为可以放心地移除线程终止功能。