2017-10-20 112 views
0

我在程序中看到了泄漏。它不會被「valgrind memcheck」所捕獲(我通過總結報告證實了這一點,它不是接近我可以看到的頂級用法)。在使用「valgrind massif - 頁面 - 堆 - 」時,我可以更接近我的內存使用情況。 然而,它並沒有報告完成追蹤的部分,它做了mmap和分配大部分內存,我也無法檢查內存分配,因爲我只能在程序被終止後才能收集到massif的輸出。 我試過的另一件事是檢查佔用大量RSS空間的內存塊。但是我不知道如何查看pmap報告的內存塊的內容。將該addr放在gdb dint help上。我聽說gdb使用了一些地址隨機化。有人可以幫助我如何獲得與由pmap輸出報告的內存位置相對應的符號。檢查由pmap報告的虛擬內存塊

回答

0

將該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>} 

而這所有有它。