生活随笔
收集整理的這篇文章主要介紹了
GDB调试及其调试脚本的使用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、GDB調試
1.1.?GDB 概述
GDB是GNU開源組織發布的一個強大的UNIX下的程序調試工具。或許,各位比較喜歡那種圖形界面方式的,像VC、BCB等IDE的調試,但如果你是在UNIX/Linux平臺下做軟件,你會發現GDB這個調試工具有比VC、BCB的圖形化調試器更強大的功能。所謂“寸有所長,尺有所短”就是這個道理。
一般來說,GDB主要幫忙你完成下面四個方面的功能:
??? 1、啟動你的程序,可以按照你的自定義的要求隨心所欲的運行程序。
??? 2、可讓被調試的程序在你所指定的調置的斷點處停住。(斷點可以是條件表達式)
??? 3、當程序被停住時,可以檢查此時你的程序中所發生的事。
??? 4、動態的改變你程序的執行環境。
從上面看來,GDB和一般的調試工具沒有什么兩樣,基本上也是完成這些功能,不過在細節上,你會發現GDB這個調試工具的強大,大家可能比較習慣了圖形化的調試工具,但有時候,命令行的調試工具卻有著圖形化工具所不能完成的功能。讓我們一一看來。
1.2.GDB 使用示例
使用一個簡單的判斷來測試一下:文件名gdbtest.c
[cpp]?view plaincopy
<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>??
程序很簡單,設置x=3,然后判斷x是否比4小,若比4小則輸出”x is less than 4“,若比4大,則輸出”x is biger than 4“ ,程序很無聊,但是我們可以用來做GDB的測試!
注: 編譯的時候需要使用-g選項,我使用的是: ?gdb -g3 gdbtest.c -o gdbtest
使用GDB調試:
[cpp]?view plaincopy
#gdb?gdbtest????????????????????????????????<-------?啟動GDB?? GNU?gdb?(GDB)?7.5-ubuntu?? Copyright?(C)?2012?Free?Software?Foundation,?Inc.?? License?GPLv3+:?GNU?GPL?version?3?or?later?<http:?? 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:?? Reading?symbols?from?/home/long/gdbtest...done.?? (gdb)?l?????????????????????????????????????<-------?l命令相當于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???????????????????????????????<-------?設置斷點,在源程序第5行處。?? Breakpoint?1?at?0x8048935:?file?gdbtest.c,?line?5.?? (gdb)?run???????????????????????????????????<-------?運行程序,也可以用簡寫r?? Starting?program:?/home/long/gdbtest?? ?? Breakpoint?1,?main?()?at?gdbtest.c:5????????<-------?其實停在第一個斷點,在第5行?? 5???????if(x<4)?? (gdb)?info?break????????????????????????????<-------?查看斷點的信息?? 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)>,這時候x等于上面賦值的3?? $1?=?3?? (gdb)?print?&x??????????????????????????????<-------?打印x的地址?? $2?=?(int?*)?0xbffff21c?? (gdb)?x/4x?0xbffff21c???????????????????????<-------?查看從0xbffff21c開始的4*4個字節的值?? 0xbffff21c:?0x00000003??0x0804a000??0x00000000??0x00000000??<-------?x為int值,為4個字節?? ,所以x的值等于0x00000003,我們可以看到此時x等于3?? (gdb)?set?x=5???????????????????????????????<-------?我們設置x=5?? (gdb)?print?x???????????????????????????????<-------?打印x的值,可以看到x已經被改成5了?? $3?=?5?? (gdb)?x/4x?0xbffff21c?? 0xbffff21c:?0x00000005??0x0804a000??0x00000000??0x00000000?? (gdb)?n?????????????????????????????????????<-------?單條語句執行,next命令簡寫。?? 8???????????printf("x?is?biger?than?4\n");?? (gdb)?c?????????????????????????????????????<-------?繼續運行程序,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,因為此時x已經被改為5了?? (gdb)?q?????????????????????????????????????<-------??退出gdb?? #??
在上述GDB調試測試中,我們可以將x的值改為5,然后程序的輸出變為 x is biger than 4 。很有趣又很強大是不?
1.3.GDB 更多知識點總結(不斷搜集)
1.3.1 GDB 調試如何傳參數?
我們仍然使用示例來演示:
示例的代碼很簡單:test.c
[cpp]?view plaincopy
#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;?? }??
示例中我們分別打印第一個參數加1和第二個參數減1 的值。
我們使用gdb調試,在進入調試后 使用set args ?111 ?1的方法設置參數
[cpp]?view plaincopy
#gcc?-g3?test.c?-o?test?? #gdb?test???????????????????????????????????<-------?正常開始調劑程序?? GNU?gdb?(GDB)?7.5-ubuntu?? Copyright?(C)?2012?Free?Software?Foundation,?Inc.?? License?GPLv3+:?GNU?GPL?version?3?or?later?<http:?? 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:?? Reading?symbols?from?/tmp/test...done.?? (gdb)?set?args?111??1???????????????????????<-------?在調試時給程序傳入參數?? (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 plaincopy
gdb?--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:?? 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:?? 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??
二、GDB調試腳本的使用
下面我們對第一章中的gdbtest.c文件使用gdb腳本調試,其實很簡單我們只要把需要的操作放到一個文件中,比如叫做?gdbtest.sh
[cpp]?view plaincopy
break?5?? run?? set?x=5?? c?? q??
那么我們如何使用?其實很簡單,我們在使用時,不用直接gdb gdbtest ,而使用 ?
gdb ?./gdbtest ?-command=gdbtest.sh
其實還有種方法,我們直接在腳本中添加所要調試的文件信息,此時的??gdbtest.sh內容為:
[cpp]?view plaincopy
file?gdbtest????????????<-----?制定目標文件為gdbtest?? break?5?? run?? set?x=5?? c?? q??
而我們調試使用的命令就簡單了,直接使用
gdb -x gdbtest.sh
?即可!
三、GCOV的使用
3.1??gcov是什么?
- 伴隨GCC發布,配合GCC共同實現對C/C++文件的語句覆蓋和分支覆蓋測試;
- 與程序概要分析工具(profiling tool,例如gprof)一起工作,可以估計程序中哪一段代碼最耗時;
注:程序概要分析工具是分析代碼性能的工具。
3.2 ?gcov能做什么?
?gcov可以統計:
- 每一段代碼(section code)的耗時(執行時間)
因此,gcov可以幫你優化代碼,當然這個優化動作還是應該有開發者完成。
3.3 gcov 使用
我們繼續使用第一章中的gdbtest.c文件,使用gcov時候,在編譯時使用 ?gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c
[cpp]?view plaincopy
<span?style="font-size:18px">#ls?? gdbtest.c??gdbtest.sh?? #gcc?-g3?-fprofile-arcs?-ftest-coverage?gdbtest.c???????<--------?使用-fprofile-arcs?-ftest-coverage?參數添加gcov信息,其實可以不使用-g參數,我示例中需要使用gdb調試,所以添加了?? #./a.out?? x?is?less?than?4?? #gcov?gdbtest?? File‘gdbtest.c’?? 已執行的行數: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"為本行運行次數?? ????????-:????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");??<-----------"#####"代表此行未運>行???? ????????1:????9:}?? #????????? #gdb?./a.out?-command=gdbtest.sh????????????????????????<--------?使用上面的腳本調試,其?? 實我們的目的是運行?else?,然后看區別!?? GNU?gdb?(GDB)?7.5-ubuntu?? Copyright?(C)?2012?Free?Software?Foundation,?Inc.?? License?GPLv3+:?GNU?GPL?version?3?or?later?<http:?? 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:?? 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???????????????????????????????????????????<-----------?多運行幾次a.out或者?? 使用腳本,后想重新看看最新的測試代碼覆蓋率,需要重新?gcov?gdbtest?? File‘gdbtest.c’??? 已執行的行數: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");???<-----------?使用腳本運行時,此>行未執行,所以還是運行了1次?? ????????-:????7:????else????????????????????????????????<-----------?其實本行else是運行>過一次的,但是gcov?統計時把本行與下一行打印放在一起計時的!?? ????????1:????8:????????printf("x?is?biger?than?4\n");?? ????????2:????9:}?? #?? </span>??
注:?
【1】陳浩專欄: "用GDB調試工具"
一、?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
總結
以上是生活随笔為你收集整理的GDB调试及其调试脚本的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。