gdb 是unix/linux 系統下的程式除錯工具,和ide(如vs, eclipse等)的圖形化除錯工具相比,gdb在斷點,跟蹤顯示方面有著不足,但是它在某些方面比圖形化除錯工具更加豐富的功能。
gdb 除錯前提
如果希望程式能夠被gdb除錯,則需要在編譯程式時候,指定 -g 選項。 gdb 的除錯和程式的release 優化一樣,也存在著級別,可以手動設定。預設的gdb級別為2, 當把gdb的除錯級別設定為3的時候,可以在gdb除錯過程中 macro expand/exp
對程式中的巨集定義進行展開。
gdb 除錯的圖形化工具
gdb本身不帶圖形化介面,這樣在除錯中難以方便的知道程式當前的上下文。為了克服這一弱點,gdb也增加了一些圖形化的工具集,如 gdb -tui。使用 $ gdb -tui 程式名 可以進入gdb的圖形化除錯狀態。或者執行 $ gdb 程式名 進入命令列除錯,然後執行 ctrl + x + a 開啟 tui 模式,ctrl + x + a 關閉tui模式。
gdb 除錯的常用指令
除錯前的準備
1. 設定執行引數
set args 可設定執行時引數, set args -ip "192.168.0.1" -port 6555
show args 可以顯示執行時引數
2. 執行環境
path 可設定程式的執行路徑
show paths 顯示程式的執行路徑
set environment varname = value 可以設定環境變數
show environment varname 可以顯示環境變數
3.工作目錄
cd 相當於shell的cd
pwd 顯示當前所在的目錄
4. 程式的輸入輸出
info terminal 顯示程式用到的終端的模式
使用重定向控制程式的輸出,如 r (run) > outfile
常用命令
gdb常用命令
格式含義
簡寫list
list [開始,結束]
列出檔案的**清單
lprit
print 變數名
列印變數內容
pbreak
break [行號或函式名]
設定斷點
bcontinue
continue [開始,結束]
繼續執行
cfinish
finish
繼續執行直到程式結束
info
info 變數名
列出資訊
inext
next
下一行n
step
step
進入函式(步入)
suntil
until 行號
執行到指定的行
udisplay
display 變數名/ 表示式
顯示引數或者表示式的值
file
file 檔名(可以是絕對路徑和相對路徑)
載入檔案
runrun args
執行程式
renable
enable b (num) / display (num)
使 斷點/顯示 有效
disable
disable b (num)/display (num)
使斷點/顯示 無效
clear
clearn filename:linenumber(filename為空表示當前檔案)
刪除設定在特定原始檔、特定行上的斷點。
backtrace
bt檢視函式呼叫的棧幀
bt回車
重複上一條命令
info break 顯示當前斷點清單,包括到達斷點處的次數等。
info files 顯示被除錯檔案的詳細資訊。
info func 顯示所有的函式名稱。
info local 顯示當函式中的區域性變數資訊。
info prog 顯示被除錯程式的執行狀態。
info var 顯示所有的全域性和靜態變數名稱。
kill 終止正被除錯的程式。
l(list) filename: line_number 用來顯示指定檔案的行
斷點
b (break) 行號 在指定行新增斷點
b(break) 函式名 在制定函式前新增斷點
b(break) filename:行號 在指定檔案的指定行之前新增斷點
b(break) filename:函式名 在指定檔案的指定函式前新增斷點
b(break) *address 在程式執行到指定的記憶體位址處停止
b(break) ... if ... 條件斷點, 如 break 337 if i == 0
info b 列出所有的斷點資訊
d 刪除所有的斷點, d number 刪除number號斷點
condition break-num conds 當在conds條件滿足時,break-num被觸發。可以用來設定或者修改斷點的條件。
condition break-num 使break-num的斷點無條件。
觀察點
watch 一旦表示式值有變化,馬上停止程式
rwatch 當表示式/變數被讀時,停止程式
awatch 當表示式/變數 被讀或寫時,停止程式
info watchpoints 列出所有的觀察點
觀察點刪除,使用 d 觀察點的序號(info b 可以列出所有斷點 + 觀察點 + 的情況)
為停止點設定執行命令(實用功能)
commands [break-num]
...command list....
end為斷點 break-num 指定乙個命令列表,當在停止點處停止時,gdb依次執行列表中的命令
除錯子程序
1. set-follow-fork-mode
gdb 中 可以設定對使用fork/vfork的方式產生子程序的程式進行多程序除錯。
set-follow-fork-mode parent 在fork/vfork之後繼續對父程序進行除錯
set-follow-fork-mode child 在fork/vfork之後繼續對子程序進行除錯
(gdb) set follow-fork-mode child
(gdb) break 子程序行號
2. attach (gdb在除錯乙個程序的時候,使用attach 另乙個程序的pid, 除錯另乙個程序,除錯完之後,detach 釋放另乙個程序,繼續除錯本程序)
attach 命令可以繫結乙個外部程式進行除錯,attach 程序的pid
假設要除錯程序 proc1 的子程序,使用 ps -ef |grep proc1 找出子程序的pid, 然後 (gdb) attach 子程序pid 即可。
除錯完之後,使用detach pid釋放子程序,繼續對父程序進行除錯。
自定義除錯節奏
gdb 可以自定義命令來簡化方便除錯過程,命令定義在檔案 .gdbinit 檔案中,格式為:
define
enddocument
end
檢視巨集定義
首先在編譯時加入引數 『-gdwarf-2』 『-g3』 :
$ gcc -gdwarf-2 -g3 sample.c -o sample
用於通知gcc編譯器在編譯時加入擴充套件資訊.
* info macro : 顯示巨集的資訊
* macro expand expression : 展開表示式expression. 但是不會顯示表示式結果.
假設有定義 #define add(x,y) (x)+(y) 那麼
(gdb) macro expand add(7,8)
expands to: (7)+(8)
gdb tui 模式的常用選項
執行gdb -tui 程式名,自動進入tui模式的 layout src 模式,即 視窗上方顯示程式原始碼,下方為命令視窗。
layout src 預設模式,上方為程式原始碼,下方為命令視窗
layout asm 上方顯示程式的彙編**,下方為命令視窗
layout split 三個視窗,上方為src, 中間為 asm,下方為cmd
layout reg 在最上方(src 的上方或asm的上方)顯示暫存器視窗
tui reg general 顯示通用暫存器
tui reg float 顯示浮點暫存器
tui reg system 顯示系統暫存器
focus src/asm/cmd/reg 將游標切換到指定視窗
refresh 重新整理所有視窗
update 更新源**視窗和當前執行點
winheight name +/- line 調整name視窗的高度
gdb 除錯core dump
程式可能會出現隨機性的執行時崩潰,這種崩潰一般很難重現。可以使用core dump檔案來除錯這種問題。core dump檔案是程式在發生崩潰的時候系統所產生的記錄檔案。
ulimit -c 檢視系統設定的core 檔案大小限制,ulimit -c size 設定系統設定的core 檔案的大小,如 ulimit -c unlimited 設定大小無限制 // 設定只對當前shell有效
debug版的程式在執行時出錯,生成core檔案後。使用gdb 對core檔案進行除錯,可以除錯隨機性的錯誤。
$ gdb 程式名 core檔案
啟動之後,就和正常gdb一樣除錯。
gdb除錯學習
一般來說,gdb主要幫忙你完成下面四個方面的功能 1 啟動你的程式,可以按照你的自定義的要求隨心所欲的執行程式。2 可讓被除錯的程式在你所指定的調置的斷點處停住。斷點可以是條件表示式 3 當程式被停住時,可以檢查此時你的程式中所發生的事。4 動態的改變你程式的執行環境。除錯的程式如下 root lo...
gdb除錯學習
gdb是乙個由gnu開源組織發布的,unix linux作業系統下的,基於命令列,功能強大的程式除錯工具。可以用來除錯c,c 程式。在今天驗收實驗時發生特別尷尬的事情,由於在編譯.c檔案的時候沒有加 g選項,所以一直無法用gdb除錯程式,所以在總結gdb之前先來看看gcc在編譯時的引數。a.常規選項...
gdb除錯學習筆記
監視點 watch m 25 只有遍歷所在的記憶體值發生變化,且滿足條件是中斷 列印變數 print j 幫助文件 help breakpoint 產看斷點幫助文件 編譯時 g選項 如果不加同樣能夠除錯,不過不可以檢視變數和行號 注意是編譯過程使用,在鏈結過程沒沒有用 tui介面 ctrl x a ...