日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GDB调试及其调试脚本的使用

發布時間:2023/12/2 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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://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命令相當于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://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???????????????????????<-------?在調試時給程序傳入參數??
  • (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://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??



  • 二、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是什么?

    • Gcov is GCC Coverage
    • 是一個測試代碼覆蓋率的工具
    • 是一個命令行方式的控制臺程序
    • 伴隨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://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???????????????????????????????????????????<-----------?多運行幾次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调试及其调试脚本的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。