使用调试信息在运行时获取地址的源位置

huangapple go评论73阅读模式
英文:

Get source location for address at runtime using debug information

问题

在我的C程序中,我有一个指令指针,指向虚拟内存中的某个地址,例如一个函数指针。
我想使用运行时执行的二进制文件中的调试信息,将这个地址映射到相应的源代码位置(文件路径、行号)。
我知道GDB实现了类似的功能,但不确定如何在我的项目中实现这一功能。

我知道addr2linellvm-symbolizer,但这两个工具都分析ELF文件中的地址,而不是已加载到虚拟内存中的二进制文件。
类似地,这与如何在我的C++程序中访问addr2line功能?不重复。

英文:

In my C program, I have an instruction pointer that points to some address in virtual memory, e.g., a function pointer.
I would like to map this address to the corresponding source location (file path, line number) using the debug information in the executed binary at runtime.
I know that GDB implements something like this, but am unsure how to approach this for my project.

I'm aware of addr2line and llvm-symbolizer, but both of those tools analyze addresses in ELF files, not binaries that are already loaded into virtual memory.
Similarly, this is not a duplicate of How do I access the addr2line functionality within my C++ program?

答案1

得分: 0

由于Yakov Galka的评论,我找到了解决我想要做的事情的方法:

#define __USE_GNU
#include <dlfcn.h>

// 我想要源位置的指令地址
const void* code_addr = 0xabcdef;

// 调用dladdr来找出虚拟内存中的基地址
Dl_info info;
dladdr(code_addr, &info);

size_t base_address = (size_t) info.dli_fbase;
size_t relative_address = ((size_t) code_addr) - base_address;
// 在我的情况下: relative_address == 0x126c

然后,我可以调用addr2line来确定源位置。在我的情况下,所有内容都链接到a.out,所以我可以直接调用

addr2line --basenames -i -e tasks.out 0x126c

然后会打印出类似以下的内容:

filename.c:42
英文:

Thanks to Yakov Galka's comment, I found a solution for what I want to do:

#define __USE_GNU
#include &lt;dlfcn.h&gt;

// instruction address for which I want the source location
const void* code_addr = 0xabcdef;

// call dladdr to figure out base address in virtual memory
Dl_info info;
dladdr(code_addr, &amp;info);

size_t base_address = (size_t) info.dli_fbase;
size_t relative_address = ((size_t) code_addr) - base_address;
// in my case: relative_address == 0x126c

Then, I can call addr2line to determine the source location. In my case, everything is liked into a.out, so I can just call

addr2line --basenames -i -e tasks.out 0x126c

which then prints something like:

filename.c:42

huangapple
  • 本文由 发表于 2023年6月22日 18:34:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76531014.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定