GDB是GNU開源組織發(fā)布的一個(gè)強(qiáng)大的UNIX下的程序調(diào)試工具。或許,各位比較喜歡那種圖形界面方式的,像VC、BCB等IDE的調(diào)試,但如果你是在UNIX/linux平臺(tái)下做軟件,你會(huì)發(fā)現(xiàn)GDB這個(gè)調(diào)試工具有比VC、BCB的圖形化調(diào)試器更強(qiáng)大的功能。所謂“寸有所長,尺有所短”就是這個(gè)道理。
一般來說,GDB主要幫忙你完成下面四個(gè)方面的功能:
1、啟動(dòng)你的程序,可以按照你的自定義的要求隨心所欲的運(yùn)行程序。 2、可讓被調(diào)試的程序在你所指定的調(diào)置的斷點(diǎn)處停住。(斷點(diǎn)可以是條件表達(dá)式) 3、當(dāng)程序被停住時(shí),可以檢查此時(shí)你的程序中所發(fā)生的事。 4、動(dòng)態(tài)的改變你程序的執(zhí)行環(huán)境。
從上面看來,GDB和一般的調(diào)試工具沒有什么兩樣,基本上也是完成這些功能,不過在細(xì)節(jié)上,你會(huì)發(fā)現(xiàn)GDB這個(gè)調(diào)試工具的強(qiáng)大,大家可能比較習(xí)慣了圖形化的調(diào)試工具,但有時(shí)候,命令行的調(diào)試工具卻有著圖形化工具所不能完成的功能。讓我們一一看來。
使用一個(gè)簡單的判斷來測(cè)試一下:文件名gdbtest.c
[cpp] view plain copy<span style="font-size:18px">#include "stdio.h" int main() { int x=3; if(x<4) PRintf("x is less than 4/n"); else printf("x is biger than 4/n"); } </span>程序很簡單,設(shè)置x=3,然后判斷x是否比4小,若比4小則輸出”x is less than 4“,若比4大,則輸出”x is biger than 4“ ,程序很無聊,但是我們可以用來做GDB的測(cè)試!
注: 編譯的時(shí)候需要使用-g選項(xiàng),我使用的是: gdb -g3 gdbtest.c -o gdbtest
使用GDB調(diào)試:
[cpp] view plain copy#gdb gdbtest <------- 啟動(dòng)GDB GNU gdb (GDB) 7.5-Ubuntu Copyright (C) 2012 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 "i686-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/long/gdbtest...done. (gdb) l <------- l命令相當(dāng)于list,從第一行開始例出原 碼 1 #include "stdio.h" 2 int main() 3 { 4 int x=3; 5 if(x<4) 6 printf("x is less than 4/n"); 7 else 8 printf("x is biger than 4/n"); 9 } (gdb) break 5 <------- 設(shè)置斷點(diǎn),在源程序第5行處。 Breakpoint 1 at 0x8048935: file gdbtest.c, line 5. (gdb) run <------- 運(yùn)行程序,也可以用簡寫r Starting program: /home/long/gdbtest Breakpoint 1, main () at gdbtest.c:5 <------- 其實(shí)停在第一個(gè)斷點(diǎn),在第5行 5 if(x<4) (gdb) info break <------- 查看斷點(diǎn)的信息 Num Type Disp Enb Address What 1 breakpoint keep y 0x08048935 in main at gdbtest.c:5 breakpoint already hit 1 time (gdb) print x <------- 打印x的值(print 也可以用其簡寫p)>,這時(shí)候x等于上面賦值的3 $1 = 3 (gdb) print &x <------- 打印x的地址 $2 = (int *) 0xbffff21c (gdb) x/4x 0xbffff21c <------- 查看從0xbffff21c開始的4*4個(gè)字節(jié)的值 0xbffff21c: 0x00000003 0x0804a000 0x00000000 0x00000000 <------- x為int值,為4個(gè)字節(jié) ,所以x的值等于0x00000003,我們可以看到此時(shí)x等于3 (gdb) set x=5 <------- 我們?cè)O(shè)置x=5 (gdb) print x <------- 打印x的值,可以看到x已經(jīng)被改成5了 $3 = 5 (gdb) x/4x 0xbffff21c 0xbffff21c: 0x00000005 0x0804a000 0x00000000 0x00000000 (gdb) n <------- 單條語句執(zhí)行,next命令簡寫。 8 printf("x is biger than 4/n"); (gdb) c <------- 繼續(xù)運(yùn)行程序,continue命令簡寫。 Continuing. profiling:/home/zhouyl:Cannot create directory profiling:/home/zhouyl/NicholClass/error_test/gdb/gdbtest.gcda:Skip x is biger than 4[Inferior 1 (process 9265) exited with code 01] <------- 程序輸出x is biger than 4,因?yàn)榇藭r(shí)x已經(jīng)被改為5了 (gdb) q <------- 退出gdb #在上述GDB調(diào)試測(cè)試中,我們可以將x的值改為5,然后程序的輸出變?yōu)?x is biger than 4 。很有趣又很強(qiáng)大是不?
1.3.1 GDB 調(diào)試如何傳參數(shù)?
我們?nèi)匀皇褂檬纠齺硌菔荆?/p>
示例的代碼很簡單:test.c
[cpp] view plain copy#include <stdio.h> int main(int argc, char **argv) { int i=0; i=atoi(argv[1]); i = i + 1; printf("The value after add the first arg is : %d/n",i); i=atoi(argv[2]); i = i - 1; printf("The value after minus the second arg is : %d/n",i); return 0; }示例中我們分別打印第一個(gè)參數(shù)加1和第二個(gè)參數(shù)減1 的值。
我們使用gdb調(diào)試,在進(jìn)入調(diào)試后 使用set args 111 1的方法設(shè)置參數(shù)
[cpp] view plain copy#gcc -g3 test.c -o test #gdb test <------- 正常開始調(diào)劑程序 GNU gdb (GDB) 7.5-ubuntu Copyright (C) 2012 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 "i686-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /tmp/test...done. (gdb) set args 111 1 <------- 在調(diào)試時(shí)給程序傳入?yún)?shù) (gdb) run Starting program: /tmp/test 111 1 The value after add the first arg is : 112 The value after minus the second arg is : 0 [Inferior 1 (process 9667) exited normally] (gdb) q #或者我們可以使用 gdb --args ./test 111 1的方法
[cpp] view plain copygdb --args ./test 111 1 GNU gdb (GDB) 7.5-ubuntu Copyright (C) 2012 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 "i686-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /tmp/test...done. (gdb) run Starting program: /tmp/test 111 1 The value after add the first arg is : 112 The value after minus the second arg is : 0 [Inferior 1 (process 10784) exited normally] (gdb) q下面我們對(duì)第一章中的gdbtest.c文件使用gdb腳本調(diào)試,其實(shí)很簡單我們只要把需要的操作放到一個(gè)文件中,比如叫做 gdbtest.sh
[cpp] view plain copybreak 5 run set x=5 c q 那么我們?nèi)绾问褂茫科鋵?shí)很簡單,我們?cè)谑褂脮r(shí),不用直接gdb gdbtest ,而使用 gdb ./gdbtest -command=gdbtest.sh其實(shí)還有種方法,我們直接在腳本中添加所要調(diào)試的文件信息,此時(shí)的 gdbtest.sh內(nèi)容為:
[cpp] view plain copyfile gdbtest <----- 制定目標(biāo)文件為gdbtest break 5 run set x=5 c q 而我們調(diào)試使用的命令就簡單了,直接使用gdb -x gdbtest.sh 即可!注:程序概要分析工具是分析代碼性能的工具。
gcov可以統(tǒng)計(jì):
每一行代碼的執(zhí)行頻率實(shí)際上哪些代碼確實(shí)被執(zhí)行了每一段代碼(section code)的耗時(shí)(執(zhí)行時(shí)間)因此,gcov可以幫你優(yōu)化代碼,當(dāng)然這個(gè)優(yōu)化動(dòng)作還是應(yīng)該有開發(fā)者完成。
我們繼續(xù)使用第一章中的gdbtest.c文件,使用gcov時(shí)候,在編譯時(shí)使用 gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c
[cpp] view plain copy<span style="font-size:18px">#ls gdbtest.c gdbtest.sh #gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c <-------- 使用-fprofile-arcs -ftest-coverage 參數(shù)添加gcov信息,其實(shí)可以不使用-g參數(shù),我示例中需要使用gdb調(diào)試,所以添加了 #./a.out x is less than 4 #gcov gdbtest File‘gdbtest.c’ 已執(zhí)行的行數(shù):83.33% (共 6 行) Creating 'gdbtest.c.gcov' # cat gdbtest.c.gcov -: 0:Source:gdbtest.c -: 0:Graph:gdbtest.gcno -: 0:Data:gdbtest.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include "stdio.h" 1: 2:int main() <----------- "1"為本行運(yùn)行次數(shù) -: 3:{ 1: 4: int x=3; 1: 5: if(x<4) 1: 6: printf("x is less than 4/n"); -: 7: else #####: 8: printf("x is biger than 4/n"); <-----------"#####"代表此行未運(yùn)>行 1: 9:} # #gdb ./a.out -command=gdbtest.sh <-------- 使用上面的腳本調(diào)試,其 實(shí)我們的目的是運(yùn)行 else ,然后看區(qū)別! GNU gdb (GDB) 7.5-ubuntu Copyright (C) 2012 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 "i686-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/long/gcovtest/a.out...done. Breakpoint 1 at 0x80489dd: file gdbtest.c, line 5. Breakpoint 1, main () at gdbtest.c:5 5 if(x<4) x is biger than 4 [Inferior 1 (process 10165) exited with code 01] #gcov gdbtest <----------- 多運(yùn)行幾次a.out或者 使用腳本,后想重新看看最新的測(cè)試代碼覆蓋率,需要重新 gcov gdbtest File‘gdbtest.c’ 已執(zhí)行的行數(shù):100.00% (共 6 行) Creating 'gdbtest.c.gcov' #cat gdbtest.c.gcov -: 0:Source:gdbtest.c -: 0:Graph:gdbtest.gcno -: 0:Data:gdbtest.gcda -: 0:Runs:2 -: 0:Programs:1 -: 1:#include "stdio.h" 2: 2:int main() -: 3:{ 2: 4: int x=3; 2: 5: if(x<4) 1: 6: printf("x is less than 4/n"); <----------- 使用腳本運(yùn)行時(shí),此>行未執(zhí)行,所以還是運(yùn)行了1次 -: 7: else <----------- 其實(shí)本行else是運(yùn)行>過一次的,但是gcov 統(tǒng)計(jì)時(shí)把本行與下一行打印放在一起計(jì)時(shí)的! 1: 8: printf("x is biger than 4/n"); 2: 9:} # </span>注:
【1】陳浩專欄: "用GDB調(diào)試工具"
一、 http://blog.csdn.net/haoel/article/details/2879
二、http://blog.csdn.net/haoel/article/details/2880
三、http://blog.csdn.net/haoel/article/details/2881
四、http://blog.csdn.net/haoel/article/details/2882
五、http://blog.csdn.net/haoel/article/details/2883
六、http://blog.csdn.net/haoel/article/details/2884
七、http://blog.csdn.net/haoel/article/details/2885
【2】http://blog.csdn.net/zhujinghao09/article/details/8461543
【3】http://blog.csdn.net/ganggexiongqi/article/details/8846001
【4】http://blog.csdn.net/yukin_xue/article/details/7653482
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注