RFC-0007:移除线程终止

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 的整个历史记录中,线程一直都是可终止的,但还没有任何可接受的用例表明程序依赖于此行为。因此,我们认为可以安全地移除线程终止。

在先技术和参考资料