我编译了一个简单的代码,然后由GDB运行。
当我在GDB中运行简单程序时,GDB向我展示了该程序的虚拟地址(在我的程序的可执行对象文件中定义)给我。
GDB也是一个程序。因此,GDB有自己的虚拟地址。因为GDB有自己的虚拟地址,所以当GDB MMAP我的简单程序以获得虚拟地址时,我的简单程序将在GDB的虚拟地址空间中具有不同的虚拟地址。
,但GDB没有向我展示该地址。相反,GDB向我展示我的简单程序的虚拟地址,该地址在我的简单程序的可执行对象文件中定义。
这是怎么发生的?GDB是否具有虚拟地址表?
GDB也是一个程序。因此,GDB有自己的虚拟地址。因为GDB有自己的虚拟地址,所以当GDB运行我的简单程序时,我的简单程序将在GDB的虚拟地址空间中具有不同的虚拟地址。
你是非常困惑。
在任何现代OS,GDB和您的程序上以不同的(虚拟)地址空间运行,它们彼此无关,并且可以以任意方式重叠。
对于非位置独立的可执行文件,GDB和您的程序都将在它们链接的要加载的虚拟地址上加载。您可以将该地址视为readelf -l /path/to/a.out
输出中第一个PT_LOAD
段的VirtAddr
。在linux/x86_64上,该地址(默认情况下)0x400000
。
对于独立于位置的可执行文件,第一个PT_LOAD
段的地址通常为0,并且可执行文件被重新定位。
如果您的二进制和GDB都是PIE,它们都将被重新定位,但是它们又不会共享地址空间,因此可以将其重新定位到完全相同的(虚拟)地址。