GDB技巧整理

2021-07-09 08:05:44 字數 3687 閱讀 6883

整理常用的gdb技巧。

常用的gdb命令...

直接執行

gdb --args prog arg1 arg2

執行gdb後使用run命令

gdb prog

run arg1 arg2

attach到已執行的程式

gdb --pid $

ptype用於顯示symbol的型別,示例原始碼為:

struct abc 

int main()

執行gdb:

(gdb) b 7

(gdb) r

(gdb) ptype abc

type = struct ***

ptype可以輸出表示式的返回型別,具體介紹可參考examining the symbol table。

print(p)可以按照某種型別輸出變數的值,示例原始碼如下:

struct abc 

int 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 0x401419

0x401419 : 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_name

dump binary memory file_name begin_addr end_addr

改變記憶體資料

使用set命令

常用的gdb操作,比如打斷點等可以放在乙個gdb指令碼裡,然後使用時匯入即可。例如:

b main.cpp:15

b 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,這和檢視...