检查由pmap报告的虚拟内存块

检查由pmap报告的虚拟内存块

问题描述:

我在程序中看到了泄漏。它不会被“valgrind memcheck”所捕获(我通过总结报告证实了这一点,它不是接近我可以看到的*用法)。在使用“valgrind massif - 页面 - 堆 - ”时,我可以更接近我的内存使用情况。 然而,它并没有报告完成追踪的部分,它做了mmap和分配大部分内存,我也无法检查内存分配,因为我只能在程序被终止后才能收集到massif的输出。 我试过的另一件事是检查占用大量RSS空间的内存块。但是我不知道如何查看pmap报告的内存块的内容。将该addr放在gdb dint help上。我听说gdb使用了一些地址随机化。有人可以帮助我如何获得与由pmap输出报告的内存位置相对应的符号。检查由pmap报告的虚拟内存块

将该addr放在gdb dint help上。

我不知道你所说的“把对GDB是地址”,但这样做是正确帮助的意思。

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

您没听错:GDB本身并不做任何的随机化,它(默认)禁用随机该操作系统执行,从而使调试更容易,更重复。

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

你很困惑:堆分配内存不是有任何符号定义。

好吧,让我们通过使用GDB在pmap中看到的内存示例进行工作。让我们通过编译这个程序,它建立了一些字符串在它100万个长链表开始:

#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; 

现在我们可以PMAP检查程序:

(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 

它似乎很明显, anon开始于0x602000的78MiB空间必须位于我们大部分数据所在的位置。 (您也可以通过循环进行几次验证。)

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

(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 

马上就可以发现,在0x602018,在0x6020680x6020b8ASCII字符串。

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

(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有一个节点,另一个在0x6020b0。你能否证实这个猜测:

(gdb) p *(Node*)0x602060 
$1 = {next = 0x602010, payload = "string 1", '\000' <repeats 55 times>} 
(gdb) p *(Node*)0x6020b0 
$2 = {next = 0x602060, payload = "string 2", '\000' <repeats 55 times>} 

而这所有有它。