能否简要说明一下Valgrind的工作原理?例如:它是如何知道内存何时被分配和释放的?
Valgrind基本上在“沙箱”中运行您的应用程序。在这个沙箱中运行时,它能够插入自己的指令来进行高级调试和分析。
根据手册:
然后,在Valgrind核心提供的合成CPU上运行您的程序。当新代码第一次执行时,核心将代码交给所选工具。工具会向其中添加自己的计算机代码,并将结果交还给核心,核心协调继续执行这些被检测的代码。
所以,基本上,valgrind提供了一个虚拟处理器来执行您的应用程序。但是,在处理您的应用程序指令之前,它们会传递给工具(例如memcheck)。这些工具有点像插件,它们可以在处理器上运行您的应用程序之前修改它。
这种方法的好处在于,您无需修改或重新链接程序就可以在valgrind中运行它。然而,这确实会使您的程序运行变慢,但是valgrind并不旨在衡量性能或在应用程序的正常执行期间运行,因此这并不是真正的问题。
Valgrind是一种动态二进制分析(DPA)工具,它使用动态二进制插装(DPI)框架来检查内存分配、检测死锁并对应用程序进行分析。DPI框架具有自己的低级内存管理器、调度程序、线程处理程序和信号处理程序。Valgrind工具套件包括以下工具:
Valgrind工具使用反汇编和重合成机制,将应用程序加载到进程中,反汇编应用程序代码,添加用于分析的插装代码,重新组合代码并执行应用程序。它使用即时编译器(JIT)将应用程序嵌入插装代码中。
Valgrind Tool = Valgrind Core + Tool Plugin
Valgrind Core会反汇编应用程序代码并将代码片段传递给工具插件进行仪器化。 工具插件添加分析代码并重新组装它。 因此,Valgrind提供了在Valgrind框架之上编写我们自己的工具的灵活性。 Valgrind使用影子寄存器和影子内存来仪器化读/写指令、读/写系统调用、堆栈和堆分配。
Valgrind为系统调用和寄存器提供包装器,用于每个系统调用的前后回调以跟踪作为系统调用一部分访问的内存。 因此,Valgrind是操作系统与客户端应用程序之间的操作系统抽象层。
该图说明了Valgrind的8个阶段:
在这里,您可以找到一些有用的信息:
此外,请了解LD_PRELOAD。
Valgrind是一个介于您的程序和操作系统之间的层,拦截对操作系统请求内存(释放)的调用,并记录在实际分配内存并返回等效内容之前正在进行的操作。它基本上是大多数代码分析器的工作方式,只是在更低的级别上(系统调用而不是程序函数调用)。
Valgrind基本上是一个执行程序的虚拟机。它是一个虚拟体系结构,拦截每个内存分配/释放调用。