检查pmap报告的虚拟内存块

时间:2017-10-20 14:47:08

标签: memory gdb massif

我看到我的程序漏洞了。它没有被“valgrind memcheck”抓住(我用摘要报告证实了这一点,它没有接近我能看到的顶级用法)。在使用“valgrind massif --pages-as-heap”时,我可以更接近我的内存使用情况。 然而,它没有报告ms部分的完整Traceback并分配大部分内存,我也无法检查内存分配,因为我只能在程序被杀死后收集massif输出。 我尝试的另一件事是检查占用大量RSS空间的内存块。但是我不知道如何查看pmap报告的内存块的内容。将该addr放在gdb dint帮助上。我听说gdb使用了一些地址随机化。有人可以帮我如何获得与pmap输出报告的内存位置相对应的符号。

1 个答案:

答案 0 :(得分:1)

  

将该addr放在gdb dint帮助中。

我不知道你的意思"把这个地址放在gdb"上,但正确地做帮助。

  

我听说gdb使用了一些地址随机化。

你听错了:GDB本身没有进行任何随机化,并且(默认情况下)禁用操作系统执行的随机化,以便使调试更容易,更可重复。

  

有人可以帮我了解如何获得与pmap输出报告的内存位置相对应的符号。

您感到困惑:堆分配的内存根据定义没有符号。

好的,让我们通过GDB检查在at中可见的内存的示例。让我们从编译这个程序开始,该程序构建一个包含一些字符串的100万个长链表:

bash

现在我们可以用pmap检查程序:

pmap

很明显,从#include <stdlib.h> #include <stdio.h> #include <unistd.h> typedef struct Node { struct Node *next; char payload[64]; } Node; int main() { int j; Node *head = NULL; for (j = 0; j < 1000000; j++) { Node *n = malloc(sizeof(*n)); n->next = head; sprintf(n->payload, "string %d", j); head = n; } return 0; } gcc -Wall -g -std=c99 t.c && gdb -q ./a.out (gdb) b 17 Breakpoint 1 at 0x4005e3: file t.c, line 17. (gdb) r Starting program: /tmp/a.out Breakpoint 1, main () at t.c:17 17 return 0; 开始的(gdb) info prog Using the running image of child process 23785. Program stopped at 0x4005e3. It stopped at breakpoint 1. Type "info stack" or "info registers" for more information. (gdb) shell pmap 23785 23785: /tmp/a.out 0000000000400000 4K r-x-- a.out 0000000000600000 4K r---- a.out 0000000000601000 4K rw--- a.out 0000000000602000 78144K rw--- [ anon ] 00007ffff7a11000 1784K r-x-- libc-2.19.so 00007ffff7bcf000 2048K ----- libc-2.19.so 00007ffff7dcf000 16K r---- libc-2.19.so 00007ffff7dd3000 8K rw--- libc-2.19.so 00007ffff7dd5000 20K rw--- [ anon ] 00007ffff7dda000 140K r-x-- ld-2.19.so 00007ffff7fd1000 12K rw--- [ anon ] 00007ffff7ff6000 8K rw--- [ anon ] 00007ffff7ff8000 8K r---- [ anon ] 00007ffff7ffa000 8K r-x-- [ anon ] 00007ffff7ffc000 4K r---- ld-2.19.so 00007ffff7ffd000 4K rw--- ld-2.19.so 00007ffff7ffe000 4K rw--- [ anon ] 00007ffffffde000 132K rw--- [ stack ] ffffffffff600000 4K r-x-- [ anon ] total 82356K 空间78MiB必须是我们大部分数据的位置。 (你也可以通过在循环中踩几次来验证这一点。)

我们如何看待这些数据?像这样:

anon

您可以立即注意到0x602000(gdb) x/30gx 0x602000 0x602000: 0x0000000000000000 0x0000000000000051 0x602010: 0x0000000000000000 0x3020676e69727473 0x602020: 0x0000000000000000 0x0000000000000000 0x602030: 0x0000000000000000 0x0000000000000000 0x602040: 0x0000000000000000 0x0000000000000000 0x602050: 0x0000000000000000 0x0000000000000051 0x602060: 0x0000000000602010 0x3120676e69727473 0x602070: 0x0000000000000000 0x0000000000000000 0x602080: 0x0000000000000000 0x0000000000000000 0x602090: 0x0000000000000000 0x0000000000000000 0x6020a0: 0x0000000000000000 0x0000000000000051 0x6020b0: 0x0000000000602060 0x3220676e69727473 0x6020c0: 0x0000000000000000 0x0000000000000000 0x6020d0: 0x0000000000000000 0x0000000000000000 0x6020e0: 0x0000000000000000 0x0000000000000000 0x6020180x602068个字符串。

您可以像这样检查这些字符串:

0x6020b8

您还可以注意到ASCII指向(gdb) x/s 0x602018 0x602018: "string 0" (gdb) x/s 0x602068 0x602068: "string 1" (gdb) x/s 0x6020b8 0x6020b8: "string 2" 的指针,0x602060指针指向0x602010

这可以让您猜测0x6020b0处有一个节点,0x602060处有另一个节点。你可以确认这个猜测:

0x602060

那就是所有