nm 输出和 gdb 中的函数地址不同
Function address is different in nm output and gdb
我们只关注 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
给你错位的名称符号 table 的地址偏移量,而 gdb
给你实际的虚拟进程的内存地址,每次你 运行 进程都会改变.
nm
只是一个工具,它显示您从代码段的开头偏移。你的情况:
00021af0 T Rect_IsEmpty
简单的意思是,在整个代码段中,在所有其他函数中,Rect_IsEmpty
一个从代码段偏移00021af0
,所以如果代码段的基址被重新定位到00000000
,则偏移量将与地址相同,00021af0
。
在 运行 在 Linux 上执行 table 之前,ASLR 机制用于随机化地址,但不是全部,只是段的开始。因此,在 运行 执行 table 之前,您不能总是知道或依赖动态符号的地址,您只能从段起始地址开始偏移。
使用调试器查找函数地址时,您会在 ASLR 完成其工作后看到进程代码段内的符号地址。
Here is a good article from IBM about shared libraries and another one 关于过程链接 Table 和全局偏移 Table。
可执行文件将从不同的内存位置开始,使得其中的任何分配都不同。因此,任何函数都将具有与其之前执行时不同的内存地址。
关于你的问题,GDB 从调试信息中获取地址 - 它会显示绝对内存地址。
我们只关注 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
给你错位的名称符号 table 的地址偏移量,而 gdb
给你实际的虚拟进程的内存地址,每次你 运行 进程都会改变.
nm
只是一个工具,它显示您从代码段的开头偏移。你的情况:
00021af0 T Rect_IsEmpty
简单的意思是,在整个代码段中,在所有其他函数中,Rect_IsEmpty
一个从代码段偏移00021af0
,所以如果代码段的基址被重新定位到00000000
,则偏移量将与地址相同,00021af0
。
在 运行 在 Linux 上执行 table 之前,ASLR 机制用于随机化地址,但不是全部,只是段的开始。因此,在 运行 执行 table 之前,您不能总是知道或依赖动态符号的地址,您只能从段起始地址开始偏移。
使用调试器查找函数地址时,您会在 ASLR 完成其工作后看到进程代码段内的符号地址。
Here is a good article from IBM about shared libraries and another one 关于过程链接 Table 和全局偏移 Table。
可执行文件将从不同的内存位置开始,使得其中的任何分配都不同。因此,任何函数都将具有与其之前执行时不同的内存地址。
关于你的问题,GDB 从调试信息中获取地址 - 它会显示绝对内存地址。