如何分析在用户模式和内核模式下进行的虚拟内存访问?

如何分析在用户模式和内核模式下进行的虚拟内存访问?

我想生成由于运行某些程序而在用户模式和内核模式下执行的所有虚拟内存访问的日志。

除了收集内存访问位置之外,我还想捕获其他状态信息(例如,指令指针、线程标识符)。我预计我无法使用任何开箱即用的工具收集所有我想要的统计数据。

我打算离线进行此分析,因此我不担心性能影响。事实上,根据可用的内容,了解哪些工具可以记录所有内存访问以及哪些工具只能采样会很有帮助。

我原本打算增强 Valgrind 这个不足的工具,直到我意识到它只记录用户模式内存访问。在研究我可能使用的其他工具时,我不知道如何快速确定哪个工具能够捕获我想要的信息。

以下是我发现的一些帮助我入门的资源:

答案1

我想用我发现的信息更新我的问题,以防其他人有类似的问题。

我对 Linux 跟踪工具的理解是,大多数使用探针(我用它来描述动态插入到可执行文件的二进制文件中的检测)和跟踪点(我用它来描述编译成可以启用或禁用的代码的检测)追踪更大缩放事件(例如,函数调用)。因此,这些工具对于跟踪像内存访问这样的细粒度的东西没有帮助。

Valgrind 对于跟踪所有内存访问非常有用用户代码(但不是内核代码因为它在合成 CPU 上执行程序)。来自文档:

然后,您的程序将在 Valgrind 核心提供的合成 CPU 上运行。当新代码第一次执行时,核心将代码交给选定的工具。该工具将自己的检测代码添加到其中,并将结果返回给核心,核心协调该检测代码的继续执行。

这似乎表明需要在传递每条要执行的指令的组件级别收集此类跟踪信息。因此,在不使用模拟器的情况下,似乎没有一种方法可以在执行时获得这种深度和广度的信息用户和内核代码

这让我找到了我找到的唯一解决方案:perf_event_open()。它可以使用处理器的性能监控单元 (PMU) 对内存访问进行采样。perf_event_open()可以提供足够深度的信息(例如,指令指针、内存地址、程序寄存器),但不能提供广度(因为它只能样本内存访问)。

(此外,perf mem前端是开始收集有关内存访问的此类信息的良好且简单的地方。然后可以使用 离线处理样本perf script。)

相关内容