1. GDB簡介
gdb是gnu debugger的縮寫, 是一款可以用於源碼級和彙編級調試的無圖形界面調試器, 雖然對新手並不算友好, 但是和vim一樣, 都屬於花時間學了就會真香的小工具,學費了就直接拋棄IDE和vscode吧…
2. 源碼級調試
2.1 控制要調試的進程
gdb <executable_file_name>可以啟動調試器, 獲得如下界面

run可以啟動待調試的可執行文件, 可以簡寫成r. 如果啟動需要帶上命令行參數, 就直接加在後面.
例如r BV1zuCXYfE6z --resolution=1080p --downloader=/usr/bin/curl
-
start可以自動啟動程序, 並在main函數的第一行停下, 若沒有調試信息, 也會完成動態庫加載等準備工作之後停在入口處 -
kill可以殺死正在調試的進程 -
continue可以使程序繼續運行, 直到遇到斷點或崩潰 -
finish可以使程序運行到當前函數結束, 返回調用地點
Notes
gdb的幾乎所有命令都能夠簡寫, 在不具有二義性的情況下可以寫盡量少的字母, 例如
run可以寫成r,continue可以寫成c, 也可以使用TAB鍵補全命令
2.2 斷點
gdb的斷點指令是break, 可以只簡寫成b.
-
b <function>: 使程序在進入函數後的第一條語句處停下. 如果是C++代碼, 可以寫出作用域加函數原型, 保證斷點在正確的重載處 -
b <line-number>: 將斷點打在當前文件的對應行號處 -
b <file_name>:<line_number>: 將斷點打在指定文件名稱的指定行號處 -
info breakpoints: 查看斷點信息 -
delete breakpoints <breakpoint number>: 刪除對應標號的斷點, 若沒給出標號, 就刪除所有斷點
2.3 單步運行
單步不進入
next可以單步運行代碼(簡寫n), 不進入下一層的函數內部
單步進入
step可以單步運行代碼(簡寫s), 會進入下一層函數
例如: 當代碼走到auto res...這一行停下時, 鍵入n會進入下一行std::fstream output_file;, 而鍵入s則會進入qrc_decode函數內部
// decode...
auto res = qqmusic::utils::qrc_decode(in_buf, out_buf, qqmusic::utils::qrc_type::local);
std::fstream output_file;
std::string output_file_name = (std::string)argv[i] + ".decode";
ulog(MSG_INFO, "output file is %s", output_file_name.c_str());
output_file.open(output_file_name, std::ios::out);
2.4 查看信息
print
print可以簡寫為p, 可以打印變量的值或表達式的值

p後面可以加一些修飾來表示以指定的格式輸出內容
-
x: 十六進制顯示 -
d: 十進制顯示 -
u: 十六進制無符號 -
i: 反彙編之後顯示 -
t: 八進制顯示 -
c: 字符格式顯示 -
f: 浮點數格式顯示 -
s: 按C風格字符串顯示
使用案例: p/s str1, 以字符串打印str1變量
x
x指令可以打印內存地址和寄存器中的值. 用法: x/nfu address
-
n是一個正整數, 指定顯示address向高地址方向打印的內存單元的數量, 不給出就默認一個 -
f是指定顯示格式的, 和上面p的選項一致, 默認十六進制顯示 -
u是指定內存單元長度的選項,b表示單字節,h表示雙字節,w表示四字節,g表示八字節
使用案例: x/50wx char_ptr就是十六進制查看char_ptr指向的地址到char_ptr + 50 * 4地址, 也就是char_ptr指向地址偏移200字節內的內容
3. 彙編級調試
在沒有調試信息時gdb仍然可以根據符號表進行調試
3.1 反彙編
-
disassemble <function>可以反彙編指定的函數 -
x/i $rip可以反彙編指令寄存器指向的指令
3.2 彙編級單步執行
-
ni: 彙編級單步不進入(遇到call指令不進入函數) -
si: 彙編級單步進入(遇到call指令進入函數)
3.3 查看內存與寄存器
info register: 簡寫i r, 查看所有寄存器信息

- 使用
x指令查看寄存器和其指向內容—例:x/50wx $rsp查看棧頂指針寄存器向高地址方向的200字節, 4字節一組十六進制顯示
大部分常用的調試技巧其實只有寥寥幾條指令, 讀者稍加練習就能掌握, 並體驗到命令行調試器的優勢.
如果需要更詳細的gdb調試技巧, 可以看看100個gdb小技巧.