转储常见问题解答

本文解答了有关在 .NET 中收集转储的常见问题。

为什么在 Linux 上转储收集失败?

为了实现转储收集,.NET 进程生成名为 createdump 的子进程。 此子进程使用 Linux API ptrace() 并从 /proc 文件系统读取,以访问写入转储文件的线程和内存数据。 尽管许多 Linux 发行版上的默认安全设置允许使用 API,但有时不太常见的安全配置会拒绝访问。 你可能会看到在正在转储的应用程序控制台上写入的 createdump 进程的输出,例如:

[createdump] The process or container does not have permissions or access: open(/proc/1234/mem) FAILED Permission denied (13)

访问被拒绝的一个原因是,如果安全沙盒使用 seccomp BPF 筛选器截获调用。 对于使用开放容器计划技术在容器中运行的应用程序,配置文件 seccomp 必须允许调用 ptrace。 例如, Docker使用后台 容器作为容器运行时。 初始化时,它指定默认的 seccomp 配置文件,仅当容器主机的内核版本高于 4.8 或容器上指定了该功能时才CAP_SYS_PTRACE允许ptrace

如果未截获调用,则内核会执行各种内置访问检查。 ptrace() 的文档包括末尾的详细说明,标题为“Ptrace 访问模式检查”,描述这些作的完成方式。 访问 /proc 文件系统也使用相同的跟踪访问模式检查的变体。 下面是执行的安全检查的缩写摘要,并放置了可能拒绝访问的位置:

  • 调用进程需要具有与目标进程相同的用户 ID,或者调用进程需要具有CAP_SYS_PTRACE。 如果这两个都不是真的,则拒绝访问。 由于 .NET 运行时在启动 createdump 时不会执行任何作来更改用户帐户,因此用户 ID 应匹配,此步骤应成功。
  • 如果 createdump 没有CAP_SYS_PTRACE(默认情况下不),则需要将要转储的目标进程标记为“可转储”。 默认情况下,Linux 上的大多数进程都是可转储的,但可以通过使用 PR_SET_DUMPABLE 选项调用 prctl() 来更改此设置。 如果使用 setcap 工具向进程添加功能,这也可能导致进程停止可转储。 有关可转储设置及其禁用原因的更详细说明,请参阅 Linux 文档
  • 枚举所有已启用的 Linux 安全模块 (LSM),每个模块都必须批准访问。 遗憾的是,如果 LSM 拒绝访问,则没有统一的 Linux 报告机制来知道哪一个负责。 相反,你需要确定哪些系统已启用,然后逐个调查。 可以通过运行:确定哪些 LSM 处于活动状态。 cat /sys/kernel/security/lsm 尽管任何 LSM 都可以负责, 但 YamaSELinuxAppArmor 通常是相关的。

AppArmor 和 SELinux 都具有丰富的配置和报告机制,因此,如果需要了解如何使用它们,最好查看每个项目自己的文档。 Yama 只有一个配置设置,可以通过运行来显示:

cat /proc/sys/kernel/yama/ptrace_scope

此命令输出一个数字,指示当前的 Yama ptrace 安全策略:

  • 0:经典 ptrace 权限。
  • 1:受限的 ptrace。
  • 2:仅限管理员的附加。
  • 3:无附加。

Yama 应在策略 0 和 1 下授予 createdump 的访问权限,但预期在策略 2 和 3 下将拒绝访问。 策略 3 始终拒绝访问,策略 2 默认不起作用,因为 createdump 通常没有CAP_SYS_PTRACE的功能。

为什么仅当 dotnet-dump 或崩溃进程正在运行提升时,才能在 Linux 上获取转储?

某些基于 Linux 的系统配置了安全策略,这些策略要求任何进程收集转储才能CAP_SYS_PTRACE。 通常,进程没有此功能,但运行提升是启用此功能的一种方法。 有关 Linux 安全策略如何影响转储收集的更完整说明,请参阅“为什么 Linux 上的转储收集失败?

为什么在容器内运行时无法收集转储?

对于在任何开放容器计划技术下运行的应用程序,配置文件seccomp必须允许调用 ptrace()。 例如, Docker使用后台 容器作为容器运行时。 初始化运行时时,它指定默认的 seccomp 配置文件,仅当容器主机的内核版本高于 4.8 或指定了该功能时才CAP_SYS_PTRACE允许ptrace

有关 Linux 安全策略如何影响转储收集的更完整说明,请参阅问题“为什么在 Linux 上转储收集失败?

为什么无法在 macOS 上收集转储?

在 macOS ptrace 上使用时,要求目标进程的主机获得适当的授权。 有关最低所需权利的信息,请参阅 默认权利

在哪里可以详细了解如何利用转储来帮助诊断 .NET 应用程序中的问题?

下面是一些其他资源:

如何解决“找不到任何兼容的框架版本”

在 Linux 上, DOTNET_ROOT 环境变量必须在设置时指向正确的文件夹。 当它指向另一个 .NET 版本时, dotnet-dump 始终生成此错误。 DOTNET_ROOT如果未设置环境变量,则会生成其他错误(“必须安装 .NET 才能运行此应用程序”)。