GDB進階技巧
yijian 2009-2-22
難得有雅興,邊動手邊記錄操作步驟,本文主要示例一些平常較少使用到的GDB功能,掌握這些用法有助于提高GDB調試和解決問題的能力。
1) 檢視宏
預設情況下,在GDB中是不能檢視宏的值及定義的,但通過如下方法,則可以達到目的:
編譯源代碼時,加上“-g3 -gdwarf-2”選項,請注意不是“-g”,必須為“-g3”,檢視宏的值使用指令p,這和檢視變量的值的方法相同,如果想檢視宏的定義,使用“macro expand”指令即可
2) 如果執行一連串指令?
這個借助指令“source”即可,“source”的參數為一個存有一串指令的檔案名
3) 如何同時給多個函數打斷點?
使用“rb”指令,如果執行“rb”時不帶參數,則表示在所有函數處打一個斷點,“rb”後面可以接一個符合正規表達式的參數,用來對符合正規表達式的所有函數打斷點
4) .gdbinit檔案
GDB在啟動時,會在使用者主目錄中尋找這個檔案,并執行該檔案中所有指令,檔案格式為:
define command-alias
command
end
如要給“b main”取一個别名“bm”:
define bm
b main
此外,還可以給這個别名加上幫助說明性文字,格式為:
document bm
幫助說明性文字
如,給“bm”别名添加幫助說明性文字:
break at main() function
這樣,在使用“help bm”時,GDB就會列印出“break at main() function”
5) 自定義指令
除了在.gdbinit檔案自定義指令外,還可以直接在GDB運作環境定義指令,文法相同
6) 定義指令鈎子
鈎子用來在執行某個指令前或指令後,先執行某個或某些指令。假如想在print指令前顯示一段“----------”,則:
define hook-print
echo ----------\n
注意“hook-”後接的必須是指令全稱,不能是縮寫。
如果想在指令執行完,再執行某個或某些指令,則:
#define hookpost-print
7) GDB中循環
GDB支援if/else/while/loop_break/loop_continue,如:
(gdb) set $x=1
(gdb) while $x==1
>p $x
>set $x=0
>end
-----------------
b$8 = 1
b$9 = 0
maintenance也是個非常強的指令,特别是子指令maintenance translate-address經常用于定位coredump問題。
handle SIGPIPE ignore 表示忽略PIPE信号,進入gdb後,執行“help handle SIGPIPE”可以看到更多用法
set follow-fork-mode child 用于跟蹤調試多程序程式,表示fork之後跟蹤子程序,而父程序不受影響
set follow-fork-mode parent 表示fork之後繼續跟蹤父程序,子程序則不受影響,同樣可以進入gdb後,執行“set follow-fork-mode”檢視說明