如何转储进程的内存页面?

4

我希望在进程执行完毕后转储内存页。我正在尝试使用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。此外,为什么这些内存空间之间会有一些不能访问的区域(例如堆之后的区域)?进程的虚拟空间不应该连续吗?
1个回答

3
一些内存空间的大小不同,这是怎么可能的?
很简单:它们跨越多个页面(请注意,它们的所有大小都是0x1000的倍数)。
这些空间是内存页面还是逻辑空间?
它们是一个或多个具有相同底层映射(相同的文件)和相同保护的页面范围。我不确定您所谓的“逻辑空间”到底是什么,但很可能您可以这样称呼它们。
这些地址应该是程序查看的虚拟地址(而不是物理地址),那么为什么程序空间不从0开始呢?
因为很久以前的VAX机器会在地址0处映射某些内容,这使得找到NULL指针解引用变得困难(它们不会崩溃)。后来,人们认为这是一个不好的想法,因此后来的UNIX变体不映射零页,任何尝试解引用NULL指针的操作都会导致SIGSEGV,帮助您调试程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接