為了能讓程式更直觀的被除錯,在編譯時應該新增一些選項
gdb ./a.out
gdb ./a.out
set args -a -b -c any_argument_you_need
b main
run
gdb bin_name core_name
大致按如下步驟
ps axu | grep bin_name
, 獲取程序id
gdb attach pid
,啟動gdb
b somewhere
,設定斷點
c
,繼續執行程式
括號裡是命令縮寫,詳細命令介紹見這裡只列出常用的
命令描述
檢視資訊
info break(b)
檢視斷點
info threads
檢視執行緒
info watchpoints
檢視觀察點
thread thread-number
進入某個執行緒
刪除資訊
delete(d)
刪除所有斷點,觀察點
delete(d) breakpoint-number
delete(d) watchpoint
刪除指定斷點,觀察點
除錯
step(s)
進入函式
next(n)
執行一行
until line-number
執行到指定行
continue(c)
執行到下乙個斷點/觀察點
finish
執行到函式完成
堆疊
backtrace(bt)
列印堆疊
frame(f) number
檢視某一幀
up/down
列印所有執行緒堆疊資訊
原始碼
list(l)
list function
檢視原始碼,函式
directory(dir) directory-name
新增原始碼搜尋路徑
檢視變數
print(p) variable-name
列印變數
p *array-variable@length
列印陣列的前length個變數
p/format
variable-name
format和printf格式近似
d: 整數
u: 無符號整數
c: 字元
f: 浮點數
x: 十六進製制
o: 八進位制
t: 二進位制
r: raw格式
按指定格式列印變數,如p/x variable-name代表以十六進製制列印變數
x/nfu address
nfu為可選的三個引數
n代表要列印的資料塊數量
f為列印的格式,和p/format中一致
u為列印的資料塊大小,有如下選擇
b/h/w/g: 單/雙/四/八字節
預設為4位元組
按指定格式檢視記憶體資料,如x/7xh address
表示從記憶體位址address開始列印7個雙位元組,每個雙位元組以十六進製制顯示
ptype variable
列印變數資料型別
執行和退出
run(r)
執行程式
quit(q)
退出除錯
設定
set print pretty on/off
預設off。格式化結構體的列印
set print element 0
列印完整字串
set logging file log-file
set logging on/off
設定日誌檔案,預設是gdb.txt
開啟/關閉日誌
case說明
手動載入源**
當我們伺服器上除錯程式時,由於沒有載入原始碼路徑而無法檢視**,此時可以將原始碼目錄拷貝到伺服器上,然後在gdb除錯時通過dir directory-name
命令載入原始碼,注意,這裡的directory-name一般是程式的makefile所在的路徑
列印除錯資訊到日誌檔案
有時候需要對列印的資訊進行查詢分析,這種操作在gdb介面不太方便,可以將內容列印到日誌,然後通過shell指令碼處理。先開啟日誌除錯開關set logging on
,然後列印你需要的資訊,再關閉開關set logging off
,這期間列印的資訊就會被寫入gdb.txt檔案,如果不想寫入這個檔案,可以在開啟日誌開關前先設定日誌檔名set logging file log-file
gdb自帶tui(text user inte***ce)模式,詳細介紹見
基本使用方式如下
tui的視窗一共有4種,src, cmd, asm, regs, 預設是開啟src和cmd視窗,可以通過layout選擇不同的視窗布局。最終的效果圖是這樣的
可以看到上面是**區(src),可以檢視當前執行的**和斷點資訊,當前執行的**被高亮顯示,並且在**最左邊有乙個符號>
,設定了斷點的行最左邊的符號是b
,下面是命令區(cmd),可以鍵入gdb除錯命令
這樣除錯的時候執行到哪一行**就一清二楚了,當然,用gdb除錯最關鍵的還是掌握基本命令,tui只是一中輔助手段
當我們要檢視某種資料結構的變數,如果gdb不認識該資料結構,它會按照p/r variable-name
的方式列印資料的原始內容,對於比較複雜的資料結構,比如map型別,我們更關心的是它儲存的元素內容,而不是它的資料結構原始內容,還好gdb7.0提供python介面可以通過實現python指令碼列印特殊的資料結構,已經有一些開源**提供對boost以及stl資料結構的解析
首先檢視系統下是否有/usr/share/gdb/python/libstdcxx目錄,如果有,說明gdb已經自帶對stl資料型別的解析,如果沒有可以自己安裝,詳細介紹見這裡簡單說明一下
svn co svn:
新建~/.gdbinit,鍵入如下內容
這時即可列印boost資料結構,我們用以下**做乙個簡單的測試python
souceforge上有現成的boost-gdb-printers,但根據我的試驗發現在列印unordered_map等資料結構時會報錯,因此我做了一些修改並放在github上經測試在boost的1.55和1.58版本下均可用import sys
sys.path.insert(0, '/home/maude/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (none)
end
source your_dir/boost-gdb-printers.py
// filename: gdb_test.cpp
#include #include #include #include using std::map;
using std::string;
struct testdata
;void break_here()
int main()
編譯如下
g++ -g gdb_test.cpp -i/your-boost-include-dir
your-boost-include-dir替換為實際的boost標頭檔案所在路徑,編寫gdb指令碼gdb_test.gdb如下
b break_here
rfin
p/r shared_x
p shared_x
p/r unordered_map_x
p unordered_map_x
qy
執行gdb ./a.out -x gdb_test.gdb,檢視變數的輸出如下
$1和$3分別是shared_ptr和unordered_map資料型別的原始列印格式,$2和$4是載入boost-gdb-printers之後的列印格式
gdb除錯備忘
指令 r 執行 根據 行數設定斷點是最常見的一種方式,在debug程式執行前就可以進行斷點的配置。如 gdb b src main.cpp 127當程式執行到main.cpp檔案的第127行時就會出發斷點。顧名思義,這種斷點是當滿足一定條件時才會觸發,比較適合進行異常排查。設定方式 gdb brea...
GDB除錯技巧
在公司工作了一段時間,發現 b s結構的 除錯很麻煩,經常用的手段是通過 printf 打一串訊息來進行跟蹤,然後估計問題出在 通過逐步新增 printf 語句,獲得越來越多的資訊最終確定問題的根源。我感覺這樣比較麻煩,如果能把 gdb的單步除錯功能用上就好了。工作之餘,做了一定的嘗試,希望對跟我一...
GDB除錯技巧
談到gdb,不能不對他的強大功能所折服,在我所用過的所有偵錯程式中,這實在是乙個強大的除錯工具,今天就說說gdb的簡單用法。gdb是gnu開源組織發布的乙個強大的unix下的程式除錯工具。或許,各位比較喜歡那種圖形介面方式的,像vc bcb等ide的除錯,但如果你是在 unix平台下做軟體,你會發現...