接續前一篇的話題。在查資料的時候看到valgrind可以和gdb合作,試了一下發現他的作法和我想的不一樣。原本以為是valgrind跑出來以後直接把漏掉的call stack和program counter傳給gdb,而gdb把他當成一種中斷點。結果完全不是,他的用法是:
測試程式碼和測試環境和前一篇一模一樣,所以就請自行看連結。
valgrind --vgdb=yes --vgdb-error=0 ./你要抓漏的程式
$ valgrind --vgdb=yes --vgdb-error=0 ./leak
==28450== Memcheck, a memory error detector
==28450== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==28450== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==28450== Command: ./leak
==28450==
==28450== (action at startup) vgdb me ...
==28450==
==28450== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==28450== /path/to/gdb ./leak
==28450== and then give GDB the following command
==28450== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=28450
==28450== --pid is optional if only one valgrind process is running
==28450==
$ gdb ./leak
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./leak...done.
(gdb)
target remote | vgdb
(gdb) target remote | vgdb
Remote debugging using | vgdb
relaying data between gdb and process 28450
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00000000040012d0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb)
(gdb) b 47
Breakpoint 1 at 0x400703: file leak.c, line 47.
(gdb) b 48
Breakpoint 2 at 0x400708: file leak.c, line 48.
47, 48行內容是
47 leak1();
48 ch_ptr = leak2();
(gdb) c
Continuing.
Breakpoint 1, main () at leak.c:47
47 leak1();
(gdb)
help monitor
查詢執行中斷點前
(gdb) monitor leak_check full reachable any
==28450== All heap blocks were freed -- no leaks are possible
==28450==
執行下一步後再檢查
(gdb) n
Breakpoint 2, main () at leak.c:48
48 ch_ptr = leak2();
(gdb) monitor leak_check full reachable any
==28450== 100 bytes in 1 blocks are still reachable in loss record 1 of 1
==28450== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28450== by 0x40065E: leak1 (leak.c:11)
==28450== by 0x400707: main (leak.c:47)
==28450==
==28450== LEAK SUMMARY:
==28450== definitely lost: 0 bytes in 0 blocks
==28450== indirectly lost: 0 bytes in 0 blocks
==28450== possibly lost: 0 bytes in 0 blocks
==28450== still reachable: 100 bytes in 1 blocks
==28450== suppressed: 0 bytes in 0 blocks
多執行幾步後再看看leak情況
(gdb) n
49 if(ch_ptr) {
(gdb) n
50 printf("%s", ch_ptr);
(gdb) n
53 lk_ptr = leak3();
(gdb) n
54 if(lk_ptr) {
(gdb) monitor leak_check full reachable any
==28450== 8 bytes in 1 blocks are still reachable in loss record 2 of 5
==28450== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28450== by 0x4006C3: leak3 (leak.c:33)
==28450== by 0x400732: main (leak.c:53)
==28450==
==28450== 14 bytes in 1 blocks are still reachable in loss record 3 of 5
==28450== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28450== by 0x4EC02B9: strdup (strdup.c:42)
==28450== by 0x400687: leak2 (leak.c:20)
==28450== by 0x40070C: main (leak.c:48)
==28450==
==28450== 14 bytes in 1 blocks are still reachable in loss record 4 of 5
==28450== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28450== by 0x4EC02B9: strdup (strdup.c:42)
==28450== by 0x4006E2: leak3 (leak.c:37)
==28450== by 0x400732: main (leak.c:53)
==28450==
==28450== 100 bytes in 1 blocks are definitely lost in loss record 5 of 5
==28450== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==28450== by 0x40065E: leak1 (leak.c:11)
==28450== by 0x400707: main (leak.c:47)
==28450==
==28450== LEAK SUMMARY:
==28450== definitely lost: 100 bytes in 1 blocks
==28450== indirectly lost: 0 bytes in 0 blocks
==28450== possibly lost: 0 bytes in 0 blocks
==28450== still reachable: 36 bytes in 3 blocks
==28450== suppressed: 0 bytes in 0 blocks
==28450==
man valgrind