gdb除錯技巧備忘

2021-07-05 05:57:13 字數 4514 閱讀 2217

為了能讓程式更直觀的被除錯,在編譯時應該新增一些選項

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,鍵入如下內容

python

import sys

sys.path.insert(0, '/home/maude/gdb_printers/python')

from libstdcxx.v6.printers import register_libstdcxx_printers

register_libstdcxx_printers (none)

endsouceforge上有現成的boost-gdb-printers,但根據我的試驗發現在列印unordered_map等資料結構時會報錯,因此我做了一些修改並放在github上經測試在boost的1.55和1.58版本下均可用

source your_dir/boost-gdb-printers.py

這時即可列印boost資料結構,我們用以下**做乙個簡單的測試

// 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平台下做軟體,你會發現...