Valgrind 如何能够访问已编译的 C 程序中内存分配的行号,我该怎么做?

How is Valgrind able to access line number of memory allocation in compiled C program, how I can I do the same?

当我运行一个简单的Valgrind命令时,例如...

valgrind --leak-check=yes ./my_program

...Valgrind 产生的错误输出显示了源代码中内存分配的位置和释放位置。 Valgrind 如何做到这一点?我怎么能在程序代码中自己做到这一点?如果有帮助,我的 GCC makefile 中为编译定义的 CFLAGS 参数是:

CFLAGS=-c -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable -g -Og -std=c11 -pedantic

...访问已编译的C程序中内存分配的行号,我该怎么做?

预定义的宏,例如__FILE__, __FUNCTION__ and __LINE__can be used in C source to output information about where something is happening. The number and variety of macros are somewhat environment dependent. __FUNCTION__ for example is an extension, and is not among the predefined macros specified by the standard as pointed out in the comments. You can read about GCC macro usage and extensions here。 (有关使用的其他提示,请参阅上面的链接。)

在此示例中,这些宏用于显示事件发生在哪个文件、函数和哪一行#:

char buf[100];
sprintf(buf, "%p (%s() %s() line# %d)\n", malloc(10), __FILE__, __FUNCTION__, __LINE__);
printf(buf);//(Or more likely usage, write to a log file)

请注意,此示例没有错误 checking/handling,例如检查 malloc() 的 return 值,始终 是个好主意.

the error output Valgrind produces shows where in the source code a memory allocation was made and where it was freed. How is Valgrind able to do this?

当您使用 valgrind 时,您不会直接启动您的程序。取而代之的是,valgrind 在一个允许它首先进行监控的环境中并通过方式来做到这一点。这包括但不限于用它自己的分配函数代替标准库的正常实现。正是这些替代分配函数使 Valgrind 能够跟踪二进制中分配和释放发生的位置

当您使用 -g 选项编译时,将源行号与已编译二进制文件中的特定指令相关联的必要信息是二进制文件中包含的调试信息的一部分。如果省略 -g,您会发现 Valgrind 的输出关于错误位置的信息较少。

How I could I do this myself, in the code of the program?

您也可以提供自己的 malloc 。和 free 功能。您可以使它们在整个程序中使用,而不是标准库的版本,尽管细节可能部分取决于您的 C 实现。正确地做到这一点非常重要,细节取决于系统。

这些函数可以用来识别调用它们的点的方法更加重要且依赖于系统。 C 语言没有定义任何类型的内省功能,因此您需要自己提供。

标准 C 也没有定义程序可以从它自己的二进制文件访问调试信息的任何方式,甚至没有任何可靠的方法来 定位 它自己的二进制文件,也没有,因为那很重要,"debug information"。 Valgrind 在这方面比程序本身有明显的优势:因为 valgrind 启动程序,valgrind 能够知道它正在启动什么二进制文件。

总的来说,答案是,如果你必须首先提出问题,那么你可能根本没有能力去做你提出的问题。相反,您应该寻找一个与您想要的功能足够接近的现有工具(可能是 valgrind 本身),或者更改您的要求。特别是,您应该考虑@ryyker 的回答中描述的基于预处理器的机制是否提供了一种方法来足够接近您的想法。