跳转至

{% 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

zx_status_t zx_task_kill(zx_handle_t handle);

进程和作业仍然可以正常地被杀死。

实现

幸运的是,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 的整个历史中,线程都是可以被杀死的,但是没有任何可接受的用例表明程序依赖于这种行为。出于这个原因,我们相信可以安全地删除线程杀死功能。

现有技术和参考文献


最后更新: 2022 年 12 月 31 日(Saturday) 21:06 CST