GDB調試詳解:正則表達式
要進行調試程序首先要生成一個含有調試信息的執行程序命令以下:shell
gcc(g++) -g -o 文件名 源文件.c(源文件.cpp)express
gcc(g++) -ggdb3 -o 文件名 源文件.c(源文件.cpp)windows
此時便會生成一個含有調試信息的可執行文件,而後即可以用 gdb 去調試這個程序了,進入調試程序命令,可是若是用 gdb 去調試一個未包含調試信息的可執行文件則會發生錯誤數組
gdb 執行文件名(含調試信息)sass
--------------------------------------------------------------------------------bash
運行 GDBide
gdb <program> -- program也就是你的執行文件,通常在固然目錄下.函數
gdb <program> core -- 用 gdb 同時調試一個運行程序和 core 文件,core 是程序非法執行後 core dump 後產生的文件.spa
gdb <program> <PID> -- 調試正在運行的程序. program 爲須要調試的程序文件, PID 爲當前正在運行的程序.或是先用 gdb <program> 關聯上源代碼進入 gdb,後用 attach 命令來掛接進程的 PID.並用 detach 來取消掛接的進程
gdb 啓動經常使用的參數
從指定文件中讀取符號表:
-symbols <file>
-s <file>
從指定文件中讀取符號表信息,並把他用在可執行文件中:
-se file
調試時core dump的core文件:
-core <file>
-c <file>
加入一個源文件的搜索路徑.默認搜索路徑是環境變量中PATH所定義的路徑:
-directory <directory>
-d <directory>
設置啓動時候參數:
--args arglist
gdb 幫助文檔
help -- 查看 gdb 的命令種類
help <CmdType> -- 查看 CmdType 種類的 gdb 命令
apropos <keyWord> -- 查看關鍵字 keyWord 的相關命令
info <keyWord> -- 查看關鍵字 keyWord 調試信息
show <keyWord> -- 查看關鍵字 keyWord gdb 自己設置信息
gdb中運行unix的shell程序:
shell <command string> -- 調用unix的shell來執行<command string>,環境變量shell中定義的unix的shell將會被用來執行<command string>,
若是shell沒有定義,那就使用unix的標準shell:/bin/sh.(在 windows 中使用 command.com 或 cmd.exe)
make <make-args> -- 等價於"shell make <make-args>"
歷史記錄
當你用gdb的print查看程序運行時的數據時,你每個print都會被gdb記錄下來.gdb會以$1,$2,$3 ...這樣的方式爲你每個print命令編上號.因而,你可使用這個編號訪問之前的表達式,
如 $1.這個功能所帶來的好處是,若是你先前輸入了一個比較長的表達式,若是你還想查看這個表達式的值,你可使用歷史記錄來訪問,省去了重複輸入.
啓動程序
run <arg ...> -- 啓動程序,<arg ...> 爲程序運行時候須要輸入的參數
.也可用set args 命令去設置運行參數
.簡寫爲r
--------------------------------------------------------------------------------
GDB 環境設置
gdb 設置
設置顯示選項-地址
set print address <on/off> -- 打開地址輸出,當程序顯示函數信息時,gdb會顯出函數的參數地址.系統默認爲打開.
show print address -- 查看 print address 選項信息
數組元素單獨行顯示
set print array <on/off> -- 打開時數組顯示時,每一個元素佔一行,若是不打開的話,每一個元素則以逗號分隔.這個選項默認是關閉的.
show print array -- 查看 print array 選項信息
顯示數組元素顯示
set print elements <number-of-elements> -- 設置數組的顯示的最大長度,設置爲 0,則表示不限制.
show print elements -- 查看 print elements 選項信息.
設置字符串顯示
set print null-stop <on/off> -- 若是打開那麼當顯示字符串時,遇到結束符則中止顯示.這個選項默認爲 off.
show print null-stop -- 查看 print null-stop 選項信息
設置結構體變量顯示
set print pretty <on/off> -- 結構體優雅顯示
show print pretty -- 查看 gdb 是如何顯示結構體的.
設置字符顯示
set print sevenbit-strings <on/off> -- 符顯示,是否按"/nnn"的格式顯示,若是打開,則字符串或字符數據按/nnn顯示,如"/065".
show print sevenbit-strings -- 查看字符顯示開關是否打開.
設置聯合體顯示
set print union <on/off> -- 設置顯示結構體時,是否顯式其內的聯合體數據.
show print union -- 查看聯合體數據的顯示方式
設置對象顯示
set print object <on/off> -- C++中若是一個對象指針指向其派生類,若是打開這個選項,gdb 會自動按照虛方法調用的規則顯示輸出,若是關閉這個選項的話,gdb 就無論虛函數表了.這個選項默認是 off.
show print object -- 查看對象選項的設置.
設置靜態成員顯示
set print static-members <on/off> -- 這個選項表示,當顯示一個 C++ 對象中的內容是,是否顯示其中的靜態數據成員.默認是 on.
show print static-members -- 查看靜態數據成員選項設置.
設置虛函數表顯示
set print vtbl <on/off> -- 當此選項打開時,gdb 將用比較規整的格式來顯示虛函數表時.其默認是關閉的.
show print vtbl -- 查看虛函數顯示格式的選項.
設置運行程序的相關環境及其參數:
指定源文件的路徑
directory <dirname ... > -- 加一個源文件路徑到當前路徑的前面.若是你要指定多個路徑,UNIX 下你可使用":",Windows 下你可使用";"。
.縮寫 dir
directory -- 清除全部的自定義的源文件搜索路徑信息.
show directories -- 顯示定義了的源文件搜索路徑.
運行參數
set args -- 可指定運行時參數
show args -- 命令能夠查看設置好的運行參數
運行環境
path <dir> -- 可設定程序的運行路徑
show paths -- 查看程序的運行路徑
set environment varname=value -- 設置環境變量
show environment [varname] -- 查看環境變量
工做目錄
cd <dir> -- 至關於shell的cd命令
pwd -- 顯示當前的所在目錄
程序的輸入輸出
info terminal -- 顯示你程序用到的終端的模式
tty -- 命令能夠指寫輸入輸出的終端設備
重定向控制程序輸出
堆棧幀設置
set backtrace <limit> -- 設置堆棧幀的最大顯示數量,默認是沒有限制
調試模式
set step-mode [on | off] -- step-mode 模式,因而,在進行單步跟蹤時,程序不會由於沒有debug信息而不停住.這個參數有很利於查看機器碼.
設置gdb日誌:
set logging file <FILENAME> -- 設置日誌文件名文件爲FILENAME.txt
set logging <on/off> -- 打開日誌輸出,默認文件爲gdb.txt.系統默認爲關閉.
set logging on [FILENAME] -- 打開日誌輸出,日誌文件爲FILENAME.txt.
show print address -- 查看logging選項信息
--------------------------------------------------------------------------------
GDB 源碼查看:
顯示源代碼:
list <linenum> -- 顯示程序第 linenum 行的周圍的源程序.
list <function> -- 顯示函數名爲 function 的函數的源程序.
list <filename:linenum> -- 哪一個文件的哪一行.
list <filename:function> -- 哪一個文件中的哪一個函數.
list <offset> -- 當前行號的+/- offset 偏移量那那行.
list -- 顯示當前行後面的源程序.
list - -- 顯示當前行前面的源程序.
list <first>, <last> -- 顯示從 first 行到 last 行之間的源代碼.若無 first 則顯示從當前行到 last 之間的源代碼.
設置和得到顯示源碼的行數:
set listsize <count> -- 設置一次顯示源代碼的行數.
show listsize -- 查看當前listsize的設置.
搜索源代碼:
forward-search <regexp> -- 向後面搜索.正則表達式爲 regexp 的關鍵字
search <regexp> -- 向後面搜索.正則表達式爲 regexp 的關鍵字
reverse-search <regexp> -- 向前面搜索.正則表達式爲 regexp 的關鍵字
源代碼的內存:
info line <linenum> -- 查看行號爲 linenum 源代碼在內存中的地址.
info line <function> -- 查看函數在源代碼在內存中的地址.
info line <filename:linenum> -- 查看filename文件的第linenum行源代碼在內存中的地址.
info line <filename:function>-- 查看filename文件的function函數在源代碼在內存中的地址.
查看彙編代碼:
disassemble -- 查看源程序的當前執行時的機器碼,這個命令會把目前內存中的指令dump出來.
--------------------------------------------------------------------------------
GDB 中止點設置及維護:
斷點(BreakPoint):
設置斷點:(threadno指定了線程的ID,注意,這個ID是gdb分配的,能夠經過"info threads"命令來查看正在運行程序中的線程信息):
break thread <threadno> -- break命令沒有參數時,表示在下一條指令處停住.
break +offset thread <threadno> -- 在當前行號的後面的 offset 行停住.(offiset 爲天然數)
break -offset thread <threadno> -- 在當前行號的前面的 offset 行停住.(offiset 爲天然數)
break <linenum> thread <threadno> -- 在指定行號停住.
break filename:linenum thread <threadno> -- 在源文件filename的linenum行處停住.
break <function> thread <threadno> -- 在進入指定函數時停住.
break filename:function thread <threadno>--在源文件filename的function函數的入口處停住.
break *address -- 在程序運行的內存地址處停住.
break ... thread<threadno> if <condition>-- ...能夠是上述的參數,condition表示條件,在條件成立時停住.好比在循環境體中,能夠設置break if i==100,表示當i爲100時停住程序.
tbreak -- 設置只中止一次的斷點.用法和break相似
查看斷點:
info breakpoints [n]
info break [n]
info b [n]
觀察點(WatchPoint)觀察點通常來觀察某個表達式(變量也是一種表達式)的值是否有變化了,若是有變化,立刻停住程序:
設在觀察點:
watch <expr> -- 爲表達式(變量)expr設置一個觀察點.一量表達式值有變化時,立刻停住程序.
rwatch <expr> -- 當表達式(變量)expr被讀時,停住程序.
awatch <expr> -- 當表達式(變量)的值被讀或被寫時,停住程序.
查看觀察點:
info watchpoints -- 列出當前所設置了的全部觀察點.
捕捉點(CatchPoint)設置捕捉點來補捉程序運行時的一些事件.如:載入共享庫(動態連接庫)或是 C++ 的異常:
設置捕捉點:
catch <event> -- 當event發生時,停住程序.event能夠是下面的內容:throw一個C++拋出的異常(throw爲關鍵字)
catch 一個 C++ 捕捉到的異常(catch 爲關鍵字):
exec 調用系統調用 exec 時.(exec 爲關鍵字,目前此功能只在 HP-UX 下有用)
fork 調用系統調用 fork 時.(fork 爲關鍵字,目前此功能只在 HP-UX 下有用)
vfork 調用系統調用 vfork 時.(vfork 爲關鍵字,目前此功能只在 HP-UX 下有用)
load 或 load <libname> 載入共享庫(動態連接庫)時.(load 爲關鍵字,目前此功能只在 HP-UX 下有用)
unload 或 unload <libname> 卸載共享庫(動態連接庫)時.(unload 爲關鍵字,目前此功能只在 HP-UX 下有用)
tcatch <event> -- 只設置一次捕捉點,當程序停住之後,應點被自動刪除.
維護中止點:
清除中止點:
clear -- 全部的已定義的中止點.
clear <function> -- 清除全部設置在函數上的中止點.
clear <filename:function> -- 清除全部設置在函數上的中止點.
clear <linenum> -- 清除全部設置在指定行上的中止點.
clear <filename:linenum> -- 清除全部設置在指定行上的中止點.
刪除中止點
delete [range] -- 刪除中止點.其簡寫命令爲d.
禁用中止點
disable [range] -- 禁用中止點
啓用中止點
enable [range] -- 啓用中止點.
enable once [rang] -- 啓用中止點一次,當程序中止後,該中止點立刻被 gdb 自動 disable.
enable count [rang] -- 啓用中止點 count 次,當程序中止後,該中止點立刻被 gdb 自動 disable.
enable delete [rang] -- 啓用中止點一次,當程序中止後,該中止點立刻被 gdb 自動刪除.
中止條件維護,以用condition命令來修改斷點的條件.(只有break和watch命令支持if,catch目前暫不支持if)
condition <bnum> <expression> -- 修改斷點號爲bnum的中止條件爲expression.
condition <bnum> -- 清除斷點號爲bnum的中止條件.
忽略中止點N次:
ignore <bnum> <count> -- 表示忽略斷點號爲bnum的中止條件count次.
爲中止點設定運行命令,格式:
commands [bnum]-- 爲斷點號 bnum寫一個命令列表.當程序被該斷點停住時,gdb 依次運行命令列表中的命令.
... command-list ...
end
例如:
break foo if x>0
commands
printf "x is %d/n",x
continue
end
--------------------------------------------------------------------------------
信號(Signals):
添加信號處理:
handle <signal> <keywords...>
在 gdb 中定義一個信號處理.信號 <signal> 能夠以 SIG 開頭或不以 SIG 開頭,能夠用定義一個要處理信號的範圍(如:SIGIO-SIGKILL,表示處理從SIGIO信號到SIGKILL的信號,其中包括SIGIO,SIGIOT,SIGKILL三個信號),也可使用關鍵字all來標明要處理全部的信號.一旦被調試的程序接收到信號,運行程序立刻會被gdb停住,以供調試.其<keywords>能夠是如下幾種關鍵字的一個或多個.若沒有keywords則查看奇信號的處理狀態:
nostop -- 當被調試的程序收到信號時,gdb 不會停住程序的運行,但會打出消息告訴你收到這種信號.
stop -- 當被調試的程序收到信號時,gdb 會停住你的程序.
print -- 當被調試的程序收到信號時,gdb 會顯示出一條信息.
noprint -- 當被調試的程序收到信號時,gdb 不會告訴你收到信號的信息.
pass -- 當被調試的程序收到信號時,gdb 不處理信號.這表示,gdb 會把這個信號交給被調試程序會處理.
noignore -- 當被調試的程序收到信號時,gdb 不處理信號.這表示,gdb 會把這個信號交給被調試程序會處理.
nopass -- 當被調試的程序收到信號時,gdb 不處理信號.這表示,gdb 會把這個信號交給被調試程序會處理.
1gnore -- 當被調試的程序收到信號時,gdb 不會讓被調試程序來處理這個信號.
查看處理信號
info signals -- 查看有哪些信號在被 gdb 檢測中.
info handle -- 查看有哪些信號在被 gdb 檢測中.
--------------------------------------------------------------------------------
GDB 程序調試:
恢復執行:
continue [ignore-count] -- ignore-count 表示忽略其後的斷點次數.恢復程序運行,直到程序結束,或是下一個斷點到來.縮寫 c
fg [ignore-count] -- ignore-count 表示忽略其後的斷點次數.恢復程序運行,直到程序結束,或是下一個斷點到來.縮寫 c
單步調試
step <count> -- 單步跟蹤,若是有函數調用,它會進入該函數;count表示執行後面count條語句,不加則默認爲1.
next <count> -- 一樣單步跟蹤,若是有函數調用,他不會進入該函數;count表示執行後面count條語句,不加則默認爲1.
跟蹤機器指令:
與之同樣有相同功能的命令是:
display/i $pc -- 當運行完這個命令後,單步跟蹤會在打出程序代碼的同時打出機器指令(也就是彙編代碼)
stepi 或 si -- 單步跟蹤一條機器指令,簡寫 si
nexti 或 ni -- 單步跟蹤一條機器指令,簡寫 ni
函數調試:
finish -- 運行程序,直到當前函數完成返回.並打印函數返回時的堆棧地址和返回值及參數值等信息.
return <expression> -- 使函數以expression表達式返回出去,忽略尚未執行的語句.若無返回void出去;
call <expr> -- 表達式中能夠一是函數,以此達到強制調用函數的目的.並顯示函數的返回值,若是函數返回值是void,那麼就不顯示.
print --也能夠作到相似的功能和call的不一樣是,若是函數返回void,call則不顯示,print則顯示函數返回值,並把該值存入歷史數據中.
循環體調試:
until -- 能夠運行程序直到退出循環體.簡寫u
修改變量值:
print varname=var -- 修改被調試程序運行時的變量值
set var varname=value -- 修改被調試程序運行時的變變量
whatis varname -- 查看變量的類型
跳轉執行:
jump <linespec> -- 指定下一條語句的運行點.<linespce>能夠是文件的行號,能夠是file:line格式,能夠是+num這種偏移量格式.表式着下一條運行語句從哪裏開始.
jump <address> -- 跳轉到指定的程序內存地址運行.<address>是代碼行的內存地址.
注意:
jump 指令不會改變當前的程序棧中的內容,因此,當你從一個函數跳到另外一個函數時,當函數運行完返回時進行彈棧操做時必然會發生錯誤.
jump 命令只是改變了指令寄存器中的值.因而可使用"set $pc"來更改跳轉執行的地址.如:set $pc=0x485;
產生信號量
signal <signal> -- 產生一個signal信號.UNIX 的系統信號量一般從1到15.因此<signal>取值也在這個範圍.
--------------------------------------------------------------------------------
GDB 運行時數據:
查看運行時數據:
print /<f> <expr> -- 查看當前程序的運行數據.簡寫p; <expr>是表達式;
@ -- 是一個和數組有關的操做符,在後面會有更詳細的說明.在@左邊是數組的地址,右邊是數組的長度,eg:array@len;
:: -- 指定一個在文件或是一個函數中的變量.
{<type>} <addr> -- 表示一個指向內存地址<addr>的類型爲type的一個對象.
<f>是輸出的格式:
d -- 按十進制格式顯示變量.
u -- 按十六進制格式顯示無符號整型.
o -- 按八進制格式顯示變量.
t -- 按二進制格式顯示變量.
a -- 按十六進制格式顯示變量.
c -- 按字符格式顯示變量.
f -- 按浮點數格式顯示變量.
printf "fmt",arg,... -- 打印格式化字符串fmt.
數組:
有時候,你須要查看一段連續的內存空間的值。好比數組的一段,或是動態分配的數據的大小。
你可使用GDB的「@」操做符,"@"的左邊是第一個內存的地址的值,"@"的右邊則你你想查看內存的長度。
例如,你的程序中有這樣的語句:
int *array = (int *) malloc (len * sizeof (int));
在GDB調試過程當中,你能夠以以下命令顯示出這個動態數組的取值:
p *array@len-- @的左邊是數組的首地址的值,也就是變量array所指向的內容,右邊則是數據的長度;
若是是靜態數組的話,能夠直接用print數組名,就能夠顯示數組中全部數據的內容了。
注意:
1.若出現變量重名,局部變量會隱藏全局變量.若想查看全局變量的值時,可使用"::"操做符.
2.能夠經過這種形式指定你所想查看的變局變量值:
eg:
(1) p 'filename'::variable
(2) p function::variable
查看內存:
examine/<n/f/u> <addr> -- 來查看內存地址中的值,簡寫x; <n/f/u>,n是一個正整數,表示顯示內存的長度,也就是說從當前地址向後顯示幾個地址的內容;
f表示顯示的格式:
s-- 按字符串格式顯示內存地址內容.
i-- 查看內存地址的機器指令內容
x-- 按十六進制格式顯示地址內容.
d-- 按十進制格式顯示地址內容.
u-- 按十六進制格式顯示無符號整型.
o-- 按八進制格式顯示地址內容.
t-- 按二進制格式顯示地址內容.
a-- 按十六進制格式顯示地址內容.
c-- 按字符格式顯示地址內容.
f-- 按浮點數格式顯示地址內容.
u表示從當前地址日後請求的字節數,若是不指定的話,gdb默認是4個bytes:
b -- 表示單字節
h -- 表示雙字節
w -- 表示四字節
g -- 表示八字節
<addr> 表示一個內存地址.
查看變量的數據類型:
ptype --顯示變量的數據類型
自動顯示:
設置自動顯示:
display/<fmt> <expr> -- 自動顯示expr表達式
display/<fmt> <addr> -- 自動顯示addr地址
fmt表示顯示的格式:
i -- 輸出格式爲機器指令碼,也就是彙編.
s -- 輸出格式爲字符串
刪除自動顯示:
undisplay <range> -- 刪除自動顯示
delete display <range> -- 刪除自動顯示
啓用和禁自動顯示:
sable display <range> -- 禁用自動顯示
enable display <range> -- 啓動自動顯示
查看棧信息:
backtrace <n> -- 擦看函數棧信息,簡寫bt;n如果正數,只打印棧頂上n層的棧信息,如果負數,只打印棧頂下n層的棧信息,若無則打印當前的函數調用棧的全部信息.
frame -- 會打印出這些信息:棧的層編號,當前的函數名,函數參數值,函數所在文件及行號,函數執行到的語句.
info frame -- 這個命令會打印出更爲詳細的當前棧層的信息,只不過,大多數都是運行時的內存地址.
info args -- 打印出當前函數的參數名及其值.
info locals -- 打印出當前函數中全部局部變量及其值.
info catch -- 打印出當前的函數中的異常處理信息.
切換函數棧位置:
frame <n> -- 切換到第n層函數棧位置,簡寫f.
up <n> -- 表示上面移動n層,能夠不打n,表示向上移動一層.
down <n> -- 表示向棧的下面移動 n 層,能夠不打 n,表示向下移動一層.
select-frame <n> -- 相似 frame 命令.不打印出棧層信息.
up-silently <n> -- 相似 up 命令.不打印出棧層信息.
down-silently <n> -- 相似 down 命令.不打印出棧層信息.
查看寄存器
info registers -- 查看寄存器的狀況.(除了浮點寄存器)
info all-registers -- 查看全部寄存器的狀況.(包括浮點寄存器)
info registers <regname> -- 查看所指定的寄存器的狀況.
線程查看與切換線程
info threads -- 查看當前線程
thread <threadno> -- 切換到threadno的線程,簡寫t.
--------------------------------------------------------------------------------
自定義命令:
定義一個命令:
格式
define cmdName
...
end
條件語句
if cond_expr
...
else
...
end
循環語句
while cond_expr
...
end
定義一個命令的文檔信息(在help cmdName的時候顯示)
document cmdName
...
end
查看自定命令:
help user-define
-- 查看全部用戶自定義的命令
show user cmdName -- 查看用戶定義的cmdName的命令.
help cmdName -- 查看用戶自定義的cmdName的幫助文檔
show max-user-call-depth -- 查看用戶自定義命令的遞歸最大深度,缺省是1024
set max-user-call-depth <limit> -- 設置用戶自定義命令的遞歸最大深度.
查看當前程序棧的內容: x/10x $sp -- 打印stack的前10個元素
查看當前程序棧的信息: info frame -- list general info about the frame
查看當前程序棧的參數: info args -- lists arguments to the function
查看當前程序棧的局部變量: info locals-- list variables stored in the frame
查看當前寄存器的值:info registers(不包括浮點寄存器) info all-registers(包括浮點寄存器)
查看當前棧幀中的異常處理器:info catch(exception handlers)