RFC-0007:移除线程终止

RFC-0007:通过 Zircon 移除线程终止
状态已接受
领域
  • 内核
说明

本文档讨论了移除线程终止功能及其背后的原因。

Gerrit 更改
  • 431174
作者
审核人
提交日期(年-月-日)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 的整个历史中,线程都是可终止的,但没有任何程序依赖于此行为的可接受的用例。因此,我们认为线程终止可以安全地移除。

早期技术和参考资料