我想在完成执行后转储进程的内存页面。我正在尝试使用gdb,首先我在exit和_exit设置断点,然后我在gdb中运行进程,一旦进程中断,我使用info proc mappings
来获取进程的内存映射。它看起来如下:
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x415000 0x15000 0x0 /path/workspace/freqmine
0x614000 0x615000 0x1000 0x14000 /path/workspace/freqmine
0x615000 0x616000 0x1000 0x15000 /path/workspace/freqmine
0x616000 0x129b000 0xc85000 0x0 [heap]
0x7ffff71f4000 0x7ffff720a000 0x16000 0x0 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff720a000 0x7ffff7409000 0x1ff000 0x16000 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff7409000 0x7ffff740a000 0x1000 0x15000 /lib/x86_64-linux-gnu/libgcc_s.so.1
0x7ffff740a000 0x7ffff750f000 0x105000 0x0 /lib/x86_64-linux-gnu/libm-2.19.so
0x7ffff750f000 0x7ffff770e000 0x1ff000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7ffff770e000 0x7ffff770f000 0x1000 0x104000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7ffff770f000 0x7ffff7710000 0x1000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
0x7ffff7710000 0x7ffff78cb000 0x1bb000 0x0 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff78cb000 0x7ffff7acb000 0x200000 0x1bb000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7acb000 0x7ffff7acf000 0x4000 0x1bb000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7acf000 0x7ffff7ad1000 0x2000 0x1bf000 /lib/x86_64-linux-gnu/libc-2.19.so
0x7ffff7ad1000 0x7ffff7ad6000 0x5000 0x0
0x7ffff7ad6000 0x7ffff7bbc000 0xe6000 0x0 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7ffff7bbc000 0x7ffff7dbb000 0x1ff000 0xe6000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7ffff7dbb000 0x7ffff7dc3000 0x8000 0xe5000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7ffff7dc3000 0x7ffff7dc5000 0x2000 0xed000 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
0x7ffff7dc5000 0x7ffff7dda000 0x15000 0x0
0x7ffff7dda000 0x7ffff7dfd000 0x23000 0x0 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7fce000 0x7ffff7fd3000 0x5000 0x0
0x7ffff7ff7000 0x7ffff7ffa000 0x3000 0x0
0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x22000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x23000 /lib/x86_64-linux-gnu/ld-2.19.so
0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
0x7ffffffdd000 0x7ffffffff000 0x22000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
现在我有两个问题,第一个:我的机器上的getconf PAGESIZE
返回4096
,它等于0x1000
,但其中一些内存空间大小不同。怎么可能?这些空间是内存页还是逻辑空间?如果这些不是内存页面,我如何查看内存页面的地址,甚至直接将内存页面转储到文件?
我的第二个问题如下:这些地址应该是程序查看的虚拟地址(不是物理地址),为什么程序空间不能从0开始?如果我尝试从地址0开始转储内存,我会收到以下错误:Cannot access memory at address 0x0
。还有为什么这些内存空间之间存在一些无法访问的区域(例如堆之后的区域)?进程的虚拟空间不应该是连续的吗?
答案 0 :(得分:2)
但是,其中一些内存空间有不同的大小。怎么可能?
简单:它们跨越多个页面(请注意,它们的所有大小都是倍数 0x1000)。
这些空间是内存页还是逻辑空间?
它们是一个或多个页面的跨度,具有相同的底层映射(相同的文件)和相同的保护。我不确定你究竟称之为“逻辑空间”,但你可以称之为“逻辑空间”。
这些地址应该是程序查看的虚拟地址(不是物理地址),
正确。
那么为什么程序空间不能从0开始?
因为很久以前VAX机器用于在地址0处映射某些东西,并且这使得查找NULL指针解除引用很难(它们没有崩溃)。这被认为是坏主意,因此后来的UNIX变体不映射零页面,并且任何取消引用NULL
指针的尝试都会导致{{1} },帮助您调试程序。