2012-07-19 90 views
1

我想了解內存泄漏檢查程序如何識別是否爲給定的malloc調用了空閒程序。 malloc可以很容易地通過brk系統調用來識別,所以如果我正在編寫一個分析器並在系統調用中斷開一個進程時做單步操作,我可以很容易地理解malloc已經完成。 我如何找到一個免費的這個malloc?內存泄漏檢查程序如Valgrind如何識別免費

下面是strace的輸出。這段代碼有免費的,我們怎麼能知道自由是通過檢查該strace的調用 -

read(0, "13608\n", 4096)    = 6 
brk(0)         = 0x8cc6000 
brk(0x8ce7000)       = 0x8ce7000 
write(1, "File name - /proc/13608/maps\n", 29) = 29 
open("/proc/13608/maps", O_RDONLY)  = 3 
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x55559000 
read(3, "00349000-00363000 r-xp 00000000 "..., 4096) = 1046 
write(1, "ptr1-ffd1f49a\n", 14)   = 14 
write(1, "ptr2-ffd1f4a8\n", 14)   = 14 
write(1, "Buffer read - 00349000-00363000 "..., 102) = 102 
write(1, "\n", 1)      = 1 
write(1, "ptr1-ffd1f49a\n", 14)   = 14 
write(1, "ptr2-ffd1f4aa\n", 14)   = 14 
write(1, "Buffer read - 00367000-004a6000 "..., 104) = 104 
write(1, "\n", 1)      = 1 
write(1, "ptr1-ffd1f49a\n", 14)   = 14 
write(1, "ptr2-ffd1f4bd\n", 14)   = 14 
write(1, "Buffer read - 08048000-08049000 "..., 123) = 123 
write(1, "\n", 1)      = 1 
write(1, "ptr1-ffd1f49a\n", 14)   = 14 
write(1, "ptr2-ffd1f4a1\n", 14)   = 14 
write(1, "Buffer read - ffad8000-ffaf1000 "..., 95) = 95 
write(1, "\n", 1)      = 1 
write(1, "ptr1-ffd1f479\n", 14)   = 14 
write(1, "ptr2-ffd1f479\n", 14)   = 14 
write(1, "Buffer read - ffffe000-fffff000 "..., 55) = 55 
write(1, "\n", 1)      = 1 
read(3, "", 4096)      = 0 
close(3)        = 0 
munmap(0x55559000, 4096)    = 0 
write(1, "Starting Address - 00349000\n", 28) = 28 
write(1, "Ending Address - 00363000\n", 26) = 26 
write(1, "Permissions - r-xp\n", 19) = 19 
write(1, "Offset - 00000000\n", 18)  = 18 
write(1, "PathName - </lib/ld-2.5.so>\n", 28) = 28 
write(1, "\n", 1)      = 1 
write(1, "\n", 1)      = 1 
write(1, "Starting Address - 00367000\n", 28) = 28 
write(1, "Ending Address - 004a6000\n", 26) = 26 
write(1, "Permissions - r-xp\n", 19) = 19 
write(1, "Offset - 00000000\n", 18)  = 18 
write(1, "PathName - </lib/libc-2.5.so>\n", 30) = 30 
write(1, "\n", 1)      = 1 
write(1, "\n", 1)      = 1 
write(1, "Starting Address - 08048000\n", 28) = 28 
write(1, "Ending Address - 08049000\n", 26) = 26 
write(1, "Permissions - r-xp\n", 19) = 19 
write(1, "Offset - 00000000\n", 18)  = 18 
write(1, "PathName - </fs_user/samirba/myP"..., 49) = 49 
write(1, "\n", 1)      = 1 
write(1, "\n", 1)      = 1 
write(1, "Starting Address - ffad8000\n", 28) = 28 
write(1, "Ending Address - ffaf1000\n", 26) = 26 
write(1, "Permissions - rw-p\n", 19) = 19 
write(1, "Offset - 7ffffffe6000\n", 22) = 22 
write(1, "PathName - <[stack]>\n", 21) = 21 
write(1, "\n", 1)      = 1 
write(1, "\n", 1)      = 1 
write(1, "Starting Address - ffffe000\n", 28) = 28 
write(1, "Ending Address - fffff000\n", 26) = 26 
write(1, "Permissions - r-xp\n", 19) = 19 
write(1, "Offset - ffffe000\n", 18)  = 18 
write(1, "PathName - <EMPTY>\n", 19) = 19 
write(1, "\n", 1)      = 1 
write(1, "\n", 1)      = 1 
exit_group(0)       = ? 

回答

1

malloc調用和系統調用之間沒有一對一的關係。 通常,malloc庫將使用例如OS 來獲得大塊。 brk系統調用或mmap系統調用。 然後這些大塊將被切割成更小的塊來服務連續的malloc調用 。免費通常不會導致系統調用 (例如munmap)被調用。 因此,在系統調用級別上,您無法真正跟蹤malloc和free。

Valgrind的可以跟蹤內存泄漏,因爲它攔截(並替換) malloc的,免費的,... 的Valgrind的替代功能是保持分配塊的列表。

Valgrind使用所有活動的存儲器的掃描找到實際泄漏(即不能再到達的存儲器,即所有指向其的指針 已被丟失/擦除)。

+0

當我們調用valgrind的memcheck工具時,它不需要編譯時通過valgrind標誌進行檢測的程序,但它仍然可以計算出多少個malloc和free被調用。我想了解它是如何計算出所謂的釋放數量的。 – 2012-08-17 01:17:03

0

據我所知,由操作系統分配的內存塊被標識由起始地址。因此,請查找以相同參數調用的free(),該參數以前由malloc()返回。由於strace會記錄更多低級別mmapbrk調用,請使用ltrace記錄高級庫調用,並注意返回值和參數。

+0

如果我正在使用strace跟蹤一個進程,我不會看到malloc,我只會在輸出中看到brk。下面是strace的輸出,這段代碼有空。你怎麼能看出自由被調用的輸出? PLease看到我上面編輯的問題 – 2012-07-19 23:54:40

+0

嘗試'ltrace'程序 – spacediver 2012-07-20 04:51:45

+0

好的... ltrace工作正常,因爲它顯示免費...但如果我正在寫一個探查器,它正在做一個ptrace比我可以確定哪些系統調用正在發生......有什麼辦法可以通過系統調用找到免費的嗎? – 2012-07-20 15:25:39