{% set rfcid = "RFC-0007" %} {% include "docs/contribute/governance/rfcs/_common/_rfc_header.md" %}
{{ rfc.name }}: {{ rfc.title }}
概述
过去,zx_task_kill 允许在用户态杀死单个线程。但是,杀死单个线程会为不良做法提供支持,并且很有可能使进程处于不良状态。出于这个原因,应该删除杀死单个线程的能力。
动机与问题陈述
对于用户态而言,杀死单个线程的做法没有合理用途。暴露此类能力会为不良做法提供支持。
在 Fuchsia 上,和其他系统一样,杀死一个线程是异步完成的;对于正在运行的线程,没有实用的方法来确定可安全终止线程的确切位置。对于阻塞(等待)状态的线程,通常更安全且简单的解决方案是添加逻辑,以便在唤醒后线程自行退出。
杀死线程的危险
- 锁可以被保持获取,包括像控制堆这样的全局锁。
- 内存可能会泄漏。至少线程堆栈可能泄漏,但通常还有许多其他部分的内存会泄漏。
- 运行时处于不一致的状态。至少对于 C 和 Go 运行时来说是这样。
- 以系统调用的方式杀死一个线程会使进程处于未知状态。这对内核没有影响,但该进程无法知道发生了什么以及没有发生什么。
- 破坏 RAII 包装器和自动清理。事实上,它破坏了 Fuchsia 使用的高级语言的大多数保证机制。
设计
当将句柄被传递给线程时,以下系统调用将失败并返回ZX_ERR_NOT_SUPPORTED:
进程和作业仍然可以正常地被杀死。
实现
幸运的是,Fuchsia 中并没有太多使用到杀死线程。唯一的用例是在检查线程是否遇到特定异常的测试代码中。此代码将被更新,以便异常线程在异常被处理后自行退出。对于异常无法恢复的代码,可以在线程恢复前,将异常线程的指令指针直接设置为 zx_thread_exit 或运行时的线程退出函数。这些测试可能仍然会泄漏异常线程存储在堆上的内容,但运行时会处于一个更好的状态,并且会在测试的进程退出时收集泄漏的内容。
性能
N/A
安全性考虑
N/A
隐私问题
N/A
测试
Zircon 核心测试将被更新,以确保 zx_task_kill 系统调用按预期运行。可以进行一些静态分析来找到传递线程的 zx_task_kill 的调用点。
将遵循完整的 Fuchsia 大型变更(Large Scale Change,LSC)流程,以确保这一变化被正确测试。
文档
zx_task_kill 的文档将被更新以反映线程不可杀死。
缺点、替代方案和未知因素
该提议的替代方案是当前的现状,即允许线程被杀死。在 Fuchsia 的整个历史中,线程都是可以被杀死的,但是没有任何可接受的用例表明程序依赖于这种行为。出于这个原因,我们相信可以安全地删除线程杀死功能。