让我们只关注 Rect_IsEmpty() 函数。
nm 命令给了我这个输出:

(...)
00021af0 T Rect_IsEmpty
(...)

另一方面,当我启动 gdb 并查看此函数的地址时,我得到:
(gdb) info address Rect_IsEmpty
Symbol "Rect_IsEmpty" is at 0x8057c84 in a file compiled without debugging.

谁能解释一下为什么这些地址不一样? gdb 从哪里得到这个地址?

最佳答案

nm 为您提供损坏的名称符号表的地址偏移量,而 gdb 为您提供每次运行该进程时更改的实际虚拟进程的内存地址。
nm 只是一个工具,它显示您从代码段的开头偏移。在你的情况下:



简单的意思是,在整个代码段中,在所有其他函数中, Rect_IsEmpty 与代码段的偏移量 00021af0 ,因此如果代码段的基址重新定位到 00000000 ,那么偏移量将与地址 00021af0 相同。

在 Linux 上运行可执行文件之前,ASLR 机制用于随机化地址,但不是全部,只是段的开始。因此,在运行可执行文件之前,您不能总是知道或依赖动态符号的地址,您只能从段起始地址获得偏移量。

当使用调试器查找函数的地址时,在 ASLR 已经完成其工作后,您会看到进程代码段内的符号地址。

Here is 来自 IBM 的一篇关于共享库的好文章,another one 关于过程链接表和全局偏移表。

关于c - nm输出和gdb中函数地址不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31293871/

10-17 03:07