让我们只关注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从哪里获取此地址?
答案 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从调试信息中获取地址 - 它将显示绝对内存地址。