Valgrind Memcheck 模糊 /proc/self/maps 中程序的内存段

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

我正在用C编写一个线程模拟程序,它需要知道堆栈段的最低地址,以便它可以读取和写入切换上下文所需的元数据。我通过阅读

proc/self/maps
并查找与模式
[stack]
匹配的行来找到此地址 - 像这样:

7fffa7774000-7fffa7795000 rwxp 00000000 00:00 0                          [stack]

在正常程序执行期间,这一切都很好,堆栈被清楚地标记。但是,当我使用 Valgrind Memcheck 执行程序时,

[stack]
内存段不是我程序的执行堆栈,而是 Valgrind 的,并且我的程序可能使用了 Valgrind 分配的一些匿名段。我的程序不知道它正在由 Valgrind 运行并且没有使用
[stack]
块,盲目地获取 Valgrind 堆栈的最低地址并开始在那里做任何它喜欢做的事情。显然是坏消息。

鉴于这种独特的情况,我不知道如何可靠地获取堆栈的最低地址。如果可能的话,我想通过调整它以解决这种边缘情况来保持当前从

proc/self/maps
读取的方法。我怀疑这可能需要一些关于 Valgrind 如何运行它正在测试的程序的高级知识,但还没有找到关于这方面的好的信息。

不过,我承认这可能不可行或不切实际,因此很想听到任何解决方案,以了解如何可靠地获取程序执行堆栈的最低地址,即使是通过 Valgrind 执行程序时也是如此。

如果相关的话,我正在使用 C17、Valgrind 3.21.0、Fedora Linux 38、Intel x86_64 架构。

谢谢!

c linux memory valgrind memcheck
1个回答
0
投票

Valgrind 尽最大努力使来宾环境看起来就像来宾独立运行一样。不可能有完美的仿真。例如有差异

  • 在文件句柄限制中(因为 Valgrind 使用一些文件句柄)
  • 在辅助向量 auxv 中
  • CPUID指令中

Valgrind 确实尝试掩盖主机和来宾 /proc/self 之间的一些差异。可以处理

path
fd
exe
cmdline
psinfo
(取决于平台)。

Valgrind 在 Linux 和 Solaris 上确实使用了 /proc/self/maps。 Valgrind 将读取自己的调试信息(如果崩溃,它将用于打印自己的调用堆栈)。为此,它需要在内存映射中找到自己,并获取关联的文件和 ELF 信息。

Valgrind 不会尝试清理 /proc/self/maps 来隐藏它自己使用的内存映射。我认为这不是一个好主意。这会给人一种错误的印象,即内存范围可用,而实际上并不可用。

Valgrind 不会将从操作系统获取的堆栈供自己使用。事实上它使用了两个堆栈。 Valgrind 在启动时做的第一件事就是切换到使用大约 1MB 的小型固定大小临时堆栈。这足以让它自我引导。当 Valgrind 准备好启动 VEX(虚拟 CPU)运行来宾代码时,它会传输到另一个堆栈。最终堆栈是动态分配的,大小可以通过命令行参数控制。

Valgrind 需要做大量工作来综合客户端堆栈。它需要构建 argv/auxv/env。至少在 FreeBSD/Linux/Solaris 64 位系统上,客户端堆栈位置硬编码为 128Gbytes 减 1 (0x0000001fffffffff)。

如果您使用

-d -d
运行 Valgrind,您可以获得更多信息,以下内容通过
grep stack

进行管道传输
--46962:2: aspacem   suggested_clstack_end = 0x1ffc000fff (computed)
--46962:1: initimg Setup client stack: size will be 16777216
--46962:2: initimg   Client info: initial_SP=0x1FFC0003E0 max_stack_size=16777216
--46962:2:    main   mark stack inaccessible 1ffbfff000-1ffc00035f
--46962:2:  stacks   register [start-end] [0x1FFBFFF000-0x1FFC000FFF] as stack 0

-d -d
还将在各个阶段(引导、来宾启动和来宾结束)打印各种内存映射。您可以将其与 /proc/self/maps 进行比较。

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