功能地址在nm输出和gdb中不同

时间:2015-07-08 13:16:46

标签: c linux gdb nm

让我们只关注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从哪里获取此地址?

2 个答案:

答案 0 :(得分:8)

nm为您提供错位的名称符号表的地址偏移量,而gdb为您提供实际虚拟进程的内存地址,每次运行该进程时都会更改该地址。

nm只是一个工具,可以显示您偏离代码段的开头。在你的情况下:

  

00021af0 T Rect_IsEmpty

只是意味着,在整个代码段中,在所有其他函数中,Rect_IsEmpty一个从代码段中偏移00021af0,因此如果代码段的基础重新定位到{{1然后,偏移量将与地址00000000相同。

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

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

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

答案 1 :(得分:2)

可执行文件将从不同的内存位置开始,使其中的任何分配都不同。因此,任何函数都具有与之前执行的不同的内存地址。

关于你的问题,GDB从调试信息中获取地址 - 它将显示绝对内存地址。