如何在较新的 Linux 内核中查找堆栈内存段

问题描述 投票:0回答:2

我有一个小库,它写出一个“瘦核心”,其中仅包含堆栈信息(以及有效核心所需的其他位),但不包含任何堆。这并不总是有用,但核心比完整核心小得多,有时人们不想提供堆的内容。

这个库通过读取

/proc/<PID>/maps
并定位
[stack]
[stack:<tid>]
段来工作(这个进程有很多线程)。例如,我会看到这样的输出:

  ...
7fe848000000-7fe848021000 rw-p 00000000 00:00 0 
7fe848021000-7fe84c000000 ---p 00000000 00:00 0 
7fe84c1ff000-7fe84c200000 ---p 00000000 00:00 0 
7fe84c200000-7fe84ca00000 rw-p 00000000 00:00 0    [stack:25672]
7fe84ca00000-7fe84cc00000 rw-p 00000000 00:00 0 
7fe84cdff000-7fe84ce00000 ---p 00000000 00:00 0 
7fe84ce00000-7fe84d600000 rw-p 00000000 00:00 0    [stack:25534]
7fe84d600000-7fe84d800000 rw-p 00000000 00:00 0 
7fe84d9ff000-7fe84da00000 ---p 00000000 00:00 0 
7fe84da00000-7fe84e200000 rw-p 00000000 00:00 0    [stack:25532]
7fe84e200000-7fe84e600000 rw-p 00000000 00:00 0 
7fe84e7fd000-7fe84e7fe000 ---p 00000000 00:00 0 
7fe84e7fe000-7fe84effe000 rw-p 00000000 00:00 0    [stack:25531]
7fe84effe000-7fe84efff000 ---p 00000000 00:00 0 
7fe84efff000-7fe84f7ff000 rw-p 00000000 00:00 0    [stack:25530]
7fe84f7ff000-7fe84f800000 ---p 00000000 00:00 0 
7fe84f800000-7fe850000000 rw-p 00000000 00:00 0    [stack:25529]
7fe850000000-7fe850021000 rw-p 00000000 00:00 0 
7fe850021000-7fe854000000 ---p 00000000 00:00 0 
7fe854000000-7fe854400000 rw-p 00000000 00:00 0 
7fe8545ff000-7fe854600000 ---p 00000000 00:00 0
  ...
7fff5ce1d000-7fff5ce3e000 rw-p 00000000 00:00 0    [stack]
  ...

等等。这在 3.5 (Ubuntu 12.04) 和 3.13 (Ubuntu 14.04) 等较旧的 Linux 内核上运行良好。

但是,对于较新的内核(例如 Ubuntu 16.04 中的 4.4),

/proc/<PID>/maps
文件似乎不再包含每线程堆栈段的任何条目。我只看到主堆栈
[stack]
;所有看起来像堆栈段的内存段都有一个空的路径名部分。

这意味着我的“瘦核心”太薄了,只提供了主线程的堆栈。

我尝试在较新的内核中检查

/proc/<PID>/smaps
,但在新的更有限的格式中,我找不到一种方法来确定哪些段与线程堆栈关联,哪些不与线程堆栈关联。

我还检查了 procfs(5) 手册页,它仍然列出了

[stack:<tid>]
格式作为我应该看到的东西,但我没有看到它......

任何人都知道这些信息去了哪里以及我是否可以从其他一些可用信息中推断出它?

linux multithreading ubuntu-16.04 procfs
2个回答
0
投票

我还没有找到解决这个问题的真正方法。为了以后,我将描述我短期内所做的事情:我使用

pthread_attr_getstacksize()
获得了线程堆栈的大小,然后当我查看未命名的内存段以决定向“瘦核心”写入什么时,我保留了具有精确大小的段并忽略其余部分。

这是一个相当狡猾的启发式方法,但这是我能想到的所有方法,而且从我有限的测试来看,它似乎还有效。

我仍然希望有人能提供更可靠/更强大的替代方案。


0
投票

看这个proc手册,解释了从4.4以上的linux版本开始不再提供堆栈标识:

[stack:tid](从 Linux 3.4 到 Linux 4.4)
线程的堆栈(其中 tid 是线程 ID)。 它对应于/proc/pid/task/tid/路径。 该字段在 Linux 4.5 中被删除,因为 为具有大型进程的进程提供此信息 线程数量很昂贵。

© www.soinside.com 2019 - 2024. All rights reserved.