【问题标题】:How to dump memory pages of a process?如何转储进程的内存页?
【发布时间】:2015-02-17 23:39:31
【问题描述】:

我想在完成执行后转储进程的内存页面。我正在尝试为此使用 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。还有为什么在这些内存空间之间有一些无法访问的区域(例如堆之后的区域)?进程的虚拟空间不应该是连续的吗?

【问题讨论】:

    标签: memory memory-management gdb dump


    【解决方案1】:

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

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

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

    它们是一个或多个具有相同底层映射(相同文件)和相同保护的页面的跨度。我不确定你到底怎么称呼“逻辑空间”,但你可以这么称呼它们。

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

    正确。

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

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

    【讨论】:

      猜你喜欢
      • 2011-03-21
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多