gdb 是unix/linux 系統下的程序調試工具,和IDE(如VS, Eclipse等)的圖形化調試工具相比,gdb在斷點,跟蹤顯示方面有着不足,可是它在某些方面比圖形化調試工具更加豐富的功能。linux
gdb 調試前提shell
若是但願程序可以被gdb調試,則須要在編譯程序時候,指定 -g 選項。 gdb 的調試和程序的release 優化同樣,也存在着級別,能夠手動設置。默認的gdb級別爲2, 當把gdb的調試級別設置爲3的時候,能夠在gdb調試過程當中 macro expand/exp 對程序中的宏定義進行展開。express
gdb 調試的圖形化工具函數
gdb自己不帶圖形化界面,這樣在調試中難以方便的知道程序當前的上下文。爲了克服這一弱點,gdb也增長了一些圖形化的工具集,如 gdb -tui。使用 $ gdb -tui 程序名 能夠進入gdb的圖形化調試狀態。或者執行 $ gdb 程序名 進入命令行調試,而後執行 ctrl + x + A 開啓 tui 模式,ctrl + x + A 關閉tui模式。工具
gdb 調試的經常使用指令優化
調試前的準備ui
1. 設置運行參數spa
set args 可設置運行時參數, set args -ip "192.168.0.1" -port 6555命令行
show args 能夠顯示運行時參數debug
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 [開始,結束] | 列出文件的代碼清單 | l |
prit | Print 變量名 | 打印變量內容 | p |
break | Break [行號或函數名] | 設置斷點 | b |
continue | Continue [開始,結束] | 繼續運行 | c |
finish | finish | 繼續運行直到程序結束 | |
info | Info 變量名 | 列出信息 | i |
next | Next | 下一行 | n |
step | Step | 進入函數(步入) | s |
until | until 行號 | 運行到指定的行 | u |
display | Display 變量名/ 表達式 |
顯示參數或者表達式的值 | |
file | File 文件名(能夠是絕對路徑和相對路徑) | 加載文件 | |
run | Run args | 運行程序 | r |
enable | 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 <command>
<code>
end
document <command>
<help text>
end
查看宏定義
首先在編譯時加入參數 ‘-gdwarf-2’ ‘-g3’ :
$ gcc -gdwarf-2 -g3 sample.c -o sample
用於通知gcc編譯器在編譯時加入擴展信息.
* info macro <macro name> : 顯示宏的信息
* 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 顯示系統寄存器
tui reg next 顯示寄存器的下一頁
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同樣調試。