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

Memory 如何转储进程的内存页?,memory,memory-management,gdb,dump,Memory,Memory Management,Gdb,Dump,我想在进程完成执行后转储它的内存页。我正试图使用gdb实现这一点,首先我在exit和_exit设置断点,然后在gdb内部运行进程,一旦进程中断,我使用info proc mappings获取进程的内存映射。如下所示: Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0x415000 0x15

我想在进程完成执行后转储它的内存页。我正试图使用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开始的内存,则会出现以下错误:
无法访问地址0x0处的内存。另外,为什么在这些内存空间之间有一些无法访问的区域(例如堆之后的区域)?进程的虚拟空间不应该是连续的吗

不过,其中一些内存空间的大小不同。这怎么可能

简单:它们跨越多个页面(请注意,它们的大小都是0x1000的倍数)

这些空间是内存页还是逻辑空间

它们是具有相同基础映射(相同文件)和相同保护的一个或多个页面的跨距。我不确定你到底把什么叫做“逻辑空间”,但你很可能会这样称呼它们

这些地址应该是程序查看的虚拟地址(不是物理地址)

那么为什么程序空间不从0开始呢

因为很久以前,VAX机器用于映射地址0处的内容,这使得查找空指针解引用变得很困难(它们没有崩溃)。这被认为是一个坏主意,因此后来的UNIX变体不会映射零页,任何尝试取消引用
NULL
指针的行为都会导致
SIGSEGV
,从而帮助您调试程序