RFC-0007:通过 Zircon 移除线程终止 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 本文档讨论了移除线程终止功能及其背后的原因。 |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2020-09-25 |
审核日期(年-月-日) | 2020-10-06 |
总结
过去,zx_task_kill
允许用户模式终止各个线程。但是,终止单个线程会引发不良做法,并且很可能会导致进程处于不良状态。因此,应移除终止单个线程的功能。
动机和问题陈述
usermode 没有合理的用途来终止各个线程。公开此类设施会鼓励不良做法。
与其他系统一样,在 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 Large Scale Change (LSC) 流程,以确保对此变更进行正确测试。
文档
zx_task_kill 的文档将更新,以反映线程不可终止。
缺点、替代方案和未知情况
该方案的替代方案是当前的现状,即允许终止线程。在 Fuchsia 的整个历史中,线程都是可终止的,但没有任何程序依赖于此行为的可接受的用例。因此,我们认为线程终止可以安全地移除。