如何使用 /proc/<pid>/maps 找到子任务(线程)的堆栈?

How can I locate the stacks of child tasks (threads) using /proc/<pid>/maps?

提问人:vykt 提问时间:10/15/2023 更新时间:10/15/2023 访问量:35

问:

目的:

我正在研究如何在 Linux 环境中创建指针扫描仪。

免責聲明:

我的发现已经在Debian Bookworm(当前稳定版)和带有自定义内核的Gentoo系统上进行了测试。没有观察到任何差异。

问题:

在不将调试器附加到目标进程的情况下,我希望能够识别每个线程/子任务的堆栈的 VMA。这应该可以使用 proc 伪文件系统来实现

讨论:

在 Linux 4.5 之前,会在路径名字段中标记父任务的堆栈区域,并使用 标记每个子任务的堆栈区域。/proc/[parent_tid]/maps[STACK][STACK:child_tid]

在 Linux 4.5 之后,只有父任务的堆栈区域维护其标签。子任务堆栈区域现在没有标签。在此更改的提交消息(参见链接 1)中,Johannes Weiner 指出,子任务堆栈 VMA 仍可以通过观察其流程图来查看。[STACK]/proc/[parent_tid]/task/[child_tid]/maps

事实证明,这对我来说是无效的。内存区域映射在父任务和子任务之间是相同的。 ≡ .这最终意味着标签附加到同一区域。/proc/[parent_tid]/maps/proc/[parent_tid]/task/[child_tid*]/maps[STACK]

/proc/[tid]/stat可用于查找给定任务的堆栈底部的 VMA。它是第 28 个值(参见 man 5 proc)。再一次,≡.显然,子任务不会与流程中的所有其他任务共享堆栈的开始。/proc/[parent_tid]/stat/proc/[parent_tid]/task/[child_tid*]/stat

clone(2),用于创建新子任务的系统调用将堆栈指针作为参数。获取堆栈内存的最明显方法是通过匿名 .匿名内存映射在 中没有标签。通过观察一些单线程和多线程进程,匿名内存映射的数量与程序的线程之间存在直接关联。虽然这种映射不仅用于线程堆栈,但我非常希望线程堆栈以这种方式分配。每个内存映射在 中都有自己的条目。当然有一种方法可以确定其中哪些充当子任务堆栈?mmap(2)/proc/[tid]/maps/proc/[tid]/maps

我在这里做错了什么?


相关链接:

  1. 用于从以下位置删除标签的提交:
    https://lists.ubuntu.com/archives/kernel-team/2016-March/074681.html
    [STACK:tid]/proc/[tid]/maps

  2. 在我的系统上,基于 Chromium 的浏览器 qutebrowser 的所有任务的堆栈起始地址值列表:
    https://pastebin.com/5RRdrNbk

Linux 多线程 堆栈 procfs

评论

0赞 Solomon Slow 10/15/2023
“通过观察一些......过程,有直接的相关性......”仅仅因为这是大多数流程的典型特征,这不一定是所有流程的规则。
0赞 Solomon Slow 10/15/2023
“肯定有一种方法可以确定这些[映射]中的哪些充当子任务堆栈?”假设每个线程都必须有一个专用于其调用堆栈的单独 VM 区域。但同样,仅仅因为它是习惯,并不意味着它必须是规则。Linux 中断和系统调用在进入特权模式时会使用内核内存中的地址加载堆栈指针,那么为什么线程在“用户模式”下运行时必须有任何传统堆栈呢?或者,如果它有一个,为什么它必须位于单独的专用 VM 区域中?
0赞 vykt 10/15/2023
@Solomon 慢 我承认是的,例如,可以为单个匿名映射或堆上的所有线程分配堆栈空间。即使是这种情况,人们仍然希望每个任务具有不同的堆栈开始地址。然而,它们都是一样的。我不确定你所说的“为什么线程在用户模式下运行时必须有任何传统堆栈”是什么意思。您能举例说明什么时候不需要堆栈吗?/proc/[parent_tid]/task/[child_tid]/stat
1赞 Solomon Slow 10/16/2023
很久以前,我曾经做过一份暑期工作,为 IBM 1130 计算机编写 Fortran II 代码。没有堆栈。该语言不允许可重入函数调用,并且硬件没有堆栈指令。功能激活记录是静态分配的。我听说过(但未使用过)实验性编程语言,其中激活记录是从堆而不是从硬件堆栈中分配的。现代 Java 编程语言可能正在通过其“虚拟线程”向这种模式发展,但我还没有阅读足够多的关于它的信息来确定。

答: 暂无答案