我在程序中看到了泄漏。它不會被「valgrind memcheck」所捕獲(我通過總結報告證實了這一點,它不是接近我可以看到的頂級用法)。在使用「valgrind massif - 頁面 - 堆 - 」時,我可以更接近我的內存使用情況。 然而,它並沒有報告完成追蹤的部分,它做了mmap和分配大部分內存,我也無法檢查內存分配,因爲我只能在程序被終止後才能收集到massif的輸出。 我試過的另一件事是檢查佔用大量RSS空間的內存塊。但是我不知道如何查看pmap報告的內存塊的內容。將該addr放在gdb dint help上。我聽說gdb使用了一些地址隨機化。有人可以幫助我如何獲得與由pmap輸出報告的內存位置相對應的符號。檢查由pmap報告的虛擬內存塊
0
A
回答
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
,在0x602068
和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
有一個節點,另一個在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>}
而這所有有它。
相關問題
- 1. 檢查虛擬內存地址
- 2. 虛擬內存
- 3. 虛擬內存?
- 4. 檢查並報告缺少Perl模塊
- 5. sql報告服務器虛擬目錄
- 6. 如何在Unix中查找虛擬內存塊大小
- 7. Linux上的虛擬內存
- 8. 虛擬內存的使用
- 9. 在內存管理/ spdispose檢查中的Msocaf報告錯誤
- 10. Java檢查虛擬文件
- 11. 分配內存之前虛擬內存
- 12. 虛擬內存到物理內存
- 13. 物理內存與虛擬內存
- 14. 虛擬內存或物理內存
- 15. Excel虛擬內存問題
- 16. 虛擬內存處理
- 17. gdb:虛擬內存耗盡
- 18. 虛擬內存和sbrk
- 19. Android支持虛擬內存
- 20. mongodb虛擬內存大小
- 21. 需要虛擬內存嗎?
- 22. Memcached和虛擬內存
- 23. 什麼是虛擬內存?
- 24. 訪問linux虛擬內存
- 25. cc1plus:虛擬內存耗盡
- 26. 關於虛擬內存
- 27. Pytables vs虛擬內存
- 28. 虛擬內存大小
- 29. Flash虛擬內存改進
- 30. 虛擬內存空間