整理常用的gdb技巧。
常用的gdb命令...
直接執行
gdb --args prog arg1 arg2
執行gdb後使用run命令
gdb progrun arg1 arg2
attach到已執行的程式
gdb --pid $
ptype用於顯示symbol的型別,示例原始碼為:
struct abcint main()
執行gdb:
(gdb) b 7(gdb) r
(gdb) ptype abc
type = struct ***
ptype可以輸出表示式的返回型別,具體介紹可參考examining the symbol table。
print(p)可以按照某種型別輸出變數的值,示例原始碼如下:
struct abcint main()
執行gdb:
(gdb) b 13(gdb) r
(gdb) p pabc
$1 = (void *) 0x7fffffffe710
(gdb) p 0x7fffffffe710
$2 =
(gdb) p pabc
$3 =
(gdb) p * (abc*) pabc
$4 =
(gdb) p pabc
$5 = 1.5
(gdb) p * (double*) pabc
$6 = 1.5
(gdb) p (pabc + sizeof (double))
$7 = 10
(gdb) p * (int*) (pabc + sizeof (double))
$8 = 10
examine(x)可以按照一定的格式列印記憶體位址處的資料,詳細文件可參考這裡。
(gdb) x/
: 列印的位元組數目,預設為上次使用的:
: 目標位址
幾個例子:
(gdb) x/a 0x4014190x401419 : 0x55c3c900000000b8
(gdb) x/i 0x40138d
=> 0x40138d : mov -0x10(%rbp),%eax
(gdb) x/1fg 140737488346064
0x7fffffffdbd0: 10.125
參考specifying source directories,使用dir /path/to/your/sources
可在除錯時新增乙個原始碼目錄。
gdb預設使用utf-8編碼,可以使用如下命令修改編碼。
set charset gbk
也可直接在~/.gdbinit裡設定。
下面是一些除錯多執行緒程式時常用的命令:
一些不太廣為人知的技巧...
gdb除錯的時候可以從單獨的符號檔案中載入除錯資訊。
(gdb) exec-file test(gdb) symbol-file test.debug
test是移除了除錯資訊的可執行檔案, test.debug是被移除後單獨儲存的除錯資訊。參考stackoverflow上的乙個問題,可以如下分離除錯資訊:
# 編譯程式,帶除錯資訊(-g)gcc -g -o test main.c
# 拷貝除錯資訊到test.debug
objcopy --only-keep-debug test test.debug
# 移除test中的除錯資訊
strip --strip-debug --strip-unneeded test
# 然後啟動gdb
gdb -s test.debug -e test
# 或這樣啟動gdb
gdb(gdb) exec-file test
(gdb) symbol-file test.debug
分離出的除錯資訊test.debug還可以鏈結回可執行檔案test中
objcopy --add-gnu-debuglink test.debug test
然後就可以正常用addr2line等需要讀取除錯資訊的程式了
addr2line -e test 0x401c23
將記憶體資料拷貝到檔案裡
dump binary value file_name variable_namedump binary memory file_name begin_addr end_addr
改變記憶體資料
使用set命令
常用的gdb操作,比如打斷點等可以放在乙個gdb指令碼裡,然後使用時匯入即可。例如:
b main.cpp:15b test.cpp:18
gdb執行時,使用source命令即可匯入
(gdb) source /path/to/breakpoints.txt
或gdb執行時匯入
gdb -x /path/to/breakpoints.txt prog
對於每次gdb執行都要呼叫的指令碼,比如設定字符集等,可以放在~/.gdbinit初始檔案裡,這樣每次gdb啟動時都會自動呼叫。
有時候需要gdb執行若干條命令後就立即退出,而不是進入互動介面,這時可以使用-batch
選項。
上面的命令列印$pid程序所有執行緒的堆疊並退出。
參考gdb/define,可以在gdb中自定義命令,比如:
(gdb) define hello(gdb) print "welcome"
(gdb) print "hello $arg0"
(gdb) end
然後如此呼叫
(gdb) hello world
即可輸出
(gdb) $1 = "welcome"(gdb) $2 = "hello world"
在條件斷點裡可以呼叫標準庫的函式,比如下面這個:
# 如果stra == strb,則在斷點處暫停(gdb) b main.cpp:255 if strcmp(stra.c_str(), strb.c_str()) == 0
# 還是上面的場景,直接用string類的compare函式
(gdb) b main.cpp:255 if stra.compare(strb) != 0
gdb遇到未處理的exception時,並不會捕獲處理。但是參考set catchpoints,可以使用catch catch
命令來捕獲exception。
copy between memory and a file
howto: writing into process memory with gdb
specifying source directories
examining the symbol table
gdb 命令整理
最近除錯nginx原始碼,使用到了gdb,為方便以後除錯使用。整理了一些常用命令。啟動專案並斷點 start 打臨時斷點 tb打斷點 b根據 行位置設定斷點 根據函式名設定斷點 b func name 根據執行時的位址設定斷點 b 0x5859c0 檢視斷點列表 info break 檢視函式堆疊 ...
GDB除錯技巧
在公司工作了一段時間,發現 b s結構的 除錯很麻煩,經常用的手段是通過 printf 打一串訊息來進行跟蹤,然後估計問題出在 通過逐步新增 printf 語句,獲得越來越多的資訊最終確定問題的根源。我感覺這樣比較麻煩,如果能把 gdb的單步除錯功能用上就好了。工作之餘,做了一定的嘗試,希望對跟我一...
GDB高階技巧
本文主要示例一些平常較少使用到的gdb功能,掌握這些用法有助於提高gdb除錯和解決問題的能力。1 檢視巨集 預設情況下,在gdb中是不能檢視巨集的值及定義的,但通過如下方法,則可以達到目的 編譯源 時,加上 g3 gdwarf 2 選項,請注意不是 g 必須為 g3 檢視巨集的值使用命令p,這和檢視...