官术网_书友最值得收藏!

2.8 gdb實用調試技巧

這里講解gdb的一些實用調試技巧。

2.8.1 將print輸出的字符串或字符數組完整顯示

當我們使用 print命令打印一個字符串或者字符數組時,如果該字符串太長,則使用print命令默認顯示不完整,這時可以通過在gdb中輸入set print element 0進行設置,這樣再次使用print命令就能完整地顯示該變量的所有字符串了:

通過以上代碼,在第1次使用print命令輸出friendlist變量值時,只能顯示部分字符串。使用set print element 0設置后就能完整顯示了:

2.8.2 讓被gdb調試的程序接收信號

先看看下面這段程序:

在上面這段程序中,我們讓程序在接收到Ctrl+C信號(對應的信號值是SIGINT)時簡單打印一行信息。我們用gdb調試這個程序時,由于Ctrl+C信號默認會被gdb接收(讓調試器中斷),所以導致我們無法模擬程序接收這一信號。有以下兩種方法解決這個問題。

(1)在gdb中使用signal函數手動向我們的程序發送信號,這里就是signal SIGINT。

(2)改變gdb信號處理的設置,通過handle SIGINT nostop print告訴gdb在接收到SIGINT時不要停止,并把該信號傳遞給目標調試程序:

2.8.3 函數明明存在,添加斷點時卻無效

有時,一個函數明明存在,在我們的程序中也存在調試符號,但使用 break functionName添加斷點時,gdb卻提示如下:

這時即使輸入 y,添加的斷點可能也不會正確觸發。我們需要改變添加斷點的策略,使用該函數所在的代碼文件和行號添加斷點,這樣就能添加同樣效果的斷點了。

2.8.4 調試中的斷點

在實際調試中,我們一般會用到3種斷點:普通斷點、條件斷點和數據斷點。

普通斷點就是我們添加的斷點除去條件斷點和硬件斷點的斷點。

數據斷點是被監視的內存值或者變量值發生變化時觸發的斷點,前面介紹watch命令時添加的部分斷點就是數據斷點。

下面重點介紹條件斷點。條件斷點就是滿足某個條件才會觸發的斷點。這里舉個直觀的例子:

在以上代碼中,假如我們希望在變量i等于5000時,進入do_something_func函數中追蹤這個函數的執行細節,則可以修改代碼,增加一個i=5000的if條件,然后重新編譯鏈接調試。這樣顯然比較麻煩,尤其是對于一些大型項目,每次重新編譯鏈接都需要花一定的時間,而且調試完了還得把程序修改回來。有了條件斷點,我們就不需要這么麻煩了,直接添加一個條件斷點即可。添加條件斷點的命令是break [lineNo] if [condition],其中lineNo 是程序觸發斷點后需要停的位置,condition 是斷點觸發的條件。這里可以將其寫成break 11 if i==5000,11就是調用do_something_fun函數所在的行號。當然這里的行號必須是合理的行號,如果行號非法或者行號位置不合理,則也不會觸發這個斷點:

把i打印出來,gdb確實在i=5000時停了下來。

添加條件斷點還有一種方法,就是先添加一個普通斷點,然后使用“condition 斷點編號 斷點觸發條件”這樣的格式來添加。我們通過這種方法添加上述斷點:

同樣,如果斷點編號不存在,也無法添加成功,gdb就會提示斷點不存在:

No breakpoint number 2.

2.8.5 自定義gdb調試命令

在某些場景下,我們需要根據自己的程序自定義一些可以在調試時輸出程序特定信息的命令。這在gdb中很容易做到,只要在Linux用戶根目錄下,root用戶就對應/root目錄,非 root 用戶對應/home/用戶名目錄,在上述目錄下自定義一個.gdbinit 文件即可。注意,在 Linux系統中這是一個隱藏文件,可以使用 ls-a命令查看;如果文件不存在,則新建一個即可,然后在這個文件中寫上自定義的gdb命令。

這里以Apache Web Server源碼為例(可從Apache官網下載該源碼),在其源碼根目錄下有個.gdbinit文件,在這個文件中存儲了Apache Web Server自定義的gdb命令:

當然,在這個文件的底部已配置不讓gdb調試器處理SIGPIPE和SIGUSR1這兩個信號,而是將這兩個信號直接傳遞給被調試的程序本身,即如果在使用gdb調試Apache Web Server時產生了SIGPIPE或SIGUSR1信號,則gdb本身不處理這兩個信號,而是將這兩個信號傳遞給Apache Web Server程序。

主站蜘蛛池模板: 成都市| 繁峙县| 筠连县| 安岳县| 汝州市| 登封市| 和田市| 松江区| 吉水县| 敦煌市| 郯城县| 清水县| 吉木乃县| 宝鸡市| 察哈| 北票市| 延吉市| 尉氏县| 辉县市| 东至县| 渑池县| 富阳市| 栾城县| 广宗县| 灵台县| 丹江口市| 禹州市| 上饶县| 武夷山市| 句容市| 台北市| 合山市| 莱阳市| 达州市| 乐东| 清水县| 镶黄旗| 益阳市| 丰台区| 正阳县| 纳雍县|