Linuxc/c++ GDB命令總結
基於上一篇博文進行簡單總結,側重於命令的使用。不過想要更加清晰,還是要看前一博文的介紹。
一.啓動GDB
-
gdb<program>
-
gdb<program> core
-
gdb<program> <PID>
-
GDB啓動時,加上一些GDB的啓動開關,比較常用的參數:
-symbols<file>
-s<file>
從指定文件中讀取符號表
-se<file>
從指定文件中讀取符號表信息,並把它用在可執行文件中
-core<file>
-c<file>
調試時coredump的core文件
-directroy<directory>
-d<directory>
加入一個源文件的搜索路徑。默認搜索路徑是環境變量PATH所定義的路徑
二.在GDB中運行程序
運行程序使用r或者run命令。程序的運行,可以設置下面四個方面:
-
程序運行參數
setargs
可指定運行時參數。例如setargs 10 20 30 40 50
showargs
命令可以查看設置好的運行參數
-
運行環境
path<dir>
設定程序的運行路徑
showpaths
查看程序的運行路徑
setenvironment varname [=value]
設置環境變量.如setenv USER = Dong
showenvironment [varname]
查看環境變量
-
工作目錄
cd<dir>
相當於shell的cd命令
pwd
顯示當前所在目錄
-
程序的輸入輸出
infoterminal
顯示程序所用到的終端模式
使用重定向控制程序輸出。如: run >outfile
tty命令可以指寫輸入輸出的終端設備。如: tty/dev/ttyb
三.調試已運行的程序
-
在Unix下用ps查看正在運行的程序的pid,然後用gdb<program> pid格式掛接正在運行的程序。
-
先用gdb<program>關聯上源代碼,並進行gdb,在gdb中用attach命令掛接進程的pid,並用detach來取消掛接的進程。
四.暫停/恢復程序運行
-
設置斷點
break<function>
在進入函數時停住。C++中可以使用class::function或者function(type,type)格式來指定函數名
break<linenum>
在指定行號停住
break+offset
break -offset
在當前行行號的前面和後面的offset行停住,offset爲自然數
breakfilename:linenum
在源文件filename的linenum行處停住
breakfilename:function
在源文件filename的funciton函數的入口處停住
break*address
在程序運行的內存地處停住
break
命令沒有參數時,表示在下一條指令處停住
break….if<condition>
可以在上述的參數,condition表示條件,在條件成立時停住。比如在循環環境中,可以設置breakif i=100,表示i爲100時停住程序
查看斷點,可用info命令:(n表示斷點號)
infobreakpoints [n]
infobreak [n]
-
設置捕捉點(CatchPoint)
catch<event>
當event發生時,停住程序。Event可以是下面的內容:
1.throw一個c++拋出的異常(throw爲關鍵字)
2.catch一個c++拋出的異常(catch爲關鍵字)
tcatch<event>
只設置一次捕捉點,當程序停住以後,應點被自動刪除
維護停止點
clear
清除所有的已定義的停止點
clear<function>
clear<filename:funciton>
清除所有設置在函數上的停止點
clear<linenum>
clear<filename:linenum>
清除所有設置在行號上的停止點
delete[breakpoins] [range]
刪除指定的斷號,breakpoints爲斷點號。如果不指定斷點號,則表示刪除所有的斷點。range表示斷點號的範圍(如3-7)。其簡寫命令爲d
disable[breakpoints][range]
disable所指定的停止點號,如果什麼都不指定,則表示disable所有的停止點。簡寫dis
enable[breakpoints][range]
enable所指定的停止點,breakpoints爲停止點號
enable[breakpoints] once range..
enalbe所指定的停止點一次,當程序停止後,該停止點馬上被gdb自動disable
enable[breakpoints] break range..
enable所指定的停止點一次,當程序停止後,該停止點馬上被gdb自動刪除
停止條件維護
condition<bnum> <expression>
修改斷點號爲bnum的停止條件爲expression
condition<bnum>
清除斷點號爲bnum的停止條件
ignore<bnum> <count>
表示忽略斷點號爲bunm的調整條件count次
爲停止點設定運行命令
commands[bunm]
…..command-list....
end
爲斷點號bnum寫一個程序列表。當程序被該斷點停住時,gdb會一次執行命令列表中的命令。
例如:
breakfoo if x>0
commands
printf“x is %d/n”, x
continue
end
斷點設置在函數foo中,斷點條件爲x>0,如果程序被斷住後,gdb會自動打印x的值,
並繼續運行程序
清除斷點上的命令序列,只要簡單的執行commands命令,並直接end就可以了。
-
恢復程序運行和單步調試
continue[ignore-count]
c[igore-count]
fg[ignore-count]
恢復程序運行,直到程序就誒樹,或是下一個斷點到來。ignore-count表示忽略其後的斷點次數。Continue,c,fg三個命令是一個意思
step<count>
單步跟蹤,如果有函數調用,則會進入函數。後面count可以加也可以不佳,不加表示一條一條執行,加表示執行後面的count條指令,然後在停止
next<count>
同樣單步跟蹤,如果有函數調用,不會進入函數
setstep-mode
setstep-mode on
打開set-mode模式,於是,在進行單步跟蹤時,程序不會因爲沒有bug信息而不停住。
setstep-mod off
關閉step-mod模式
finish
運行程序,直到當前函數完成返回。並打印函數返回時的堆棧地址和返回值及參數值等信息
until或者u
在一個循環體內單步跟蹤時,這個命令可以運行程序直到退出循環體
stepi或者si
nexti或者ni
單步跟蹤一條機器指令,stepi和nexti可以單步執行機器指令。與之相同功能的命令是”display/i$pc”,當運行完這個命令後,單步跟蹤會在打出程序代碼的同時打印出機器指令。
信號
SIGINT表示終端字符信號,也就是Ctrl+C的信號;
SIGBUS表示硬件故障信號;
SIGCHLD表示子進程狀態改變信號;
SIGKILL表示終止程序運行的信號;
handle<signal> <keywords..>
在gdb定義一個信號處理。信號<signal>可以表示以SIG開頭或者不以SIG開頭,可以用定義一個處理範圍(如SIGIO-SIGKILL),也可以使用關鍵字all來表明要處理所有的信號。一旦被調試的程序接收到信號,運行程序馬上會被GDB停住,以供調試。其<keywords>可以使以下集中關鍵字的一個或多個:
nostop:當被調試的程序收到信號時,gdb不會停住程序的運行,但會打出消息告訴收到這種信號
stop:當被調試的程序收到信號時,gdb會停住程序
print:當被調試的程序收到信號時,gdb會顯示出一條信息
noprint:當被調試的程序收到信號時,gdb不會告訴你收到信號的信息
pass
noignore:當被調試的程序收到信號時,gdb不處理信號。這表示gdb會把這個信號交給調試程序會處理
nopass
ignore:當被調試的程序收到信號時,gdb不會讓被調試程序來處理這個信號
infosignals
infohandle:查看哪些信號在gdb檢測中
線程
break<linespec> thread <threadno>
break<linespec> thread <threadno> if …
inespec指定了斷點設置在的源程序的行號。threadno指定了線程的ID,注意,這個ID是GDB分配的,你可以通過“infothreads”命令來查看正在運行程序中的線程信息。如果你不指定thread<threadno>則表示你的斷點設在所有線程上面。你還可以爲某線程指定斷點條件。
如:(gdb)break frik.c:13 thread 28 if bartab > lim
查看棧信息
backtrace
bt
打印當前的函數調用棧的所有信息。
backtrace<n>
bt <n>
n是一個正整數,表示只打印棧頂上n層的棧信息
backtrace<-n>
bt <-n>
-n表一個負整數,表示只打印棧底下n層的棧信息。
frame<n>
f <n>
n是一個從0開始的整數,是棧中的層編號。比如:frame0,表示棧頂,frame1,表示棧的第二層
up<n>
表示向棧的上面移動n層,可以不打n,表示向上移動一層。
down<n>
表示向棧的下面移動n層,可以不打n,表示向下移動一層。
frame或f
會打印出這些信息:棧的層編號,當前的函數名,函數參數值,函數所在文件及行號,函數執行到的語句。
infoframe
infof
這個命令會打印出更爲詳細的當前棧層的信息,只不過,大多數都是運行時的內內地址。比如:函數地址,調用函數的地址,被調用函數的地址,目前的函數是由什麼樣的程序語言寫成的、函數參數地址及值、局部變量的地址等等。
infoargs
打印出當前函數的參數名及其值。
infolocals
打印出當前函數中所有局部變量及其值
infocatch
打印出當前的函數中的異常處理信息。
-
查看源代碼
list<linenum>
顯示程序第linenum行的周圍的源程序
list<function>
顯示函數名爲function的函數的源程序
list
顯示當前行後面的源程序
setlistsize <count>
設置一次顯示源代碼的行數
showlistsize
查看當前listsize的設置
list<first>, <last>
顯示從first行到last行之間的源代碼
list, <last>
顯示從當前行到last行之間的源代碼
-
搜索源代碼
forward-search<regexp>
search <regexp>
向前面搜索
reverse-search<regexp>
全部搜索
-
指定源文件路徑
directory<dirname ... >
dir <dirname ...>
加一個源文件路徑到當前路徑的前面。如果你要指定多個路徑,UNIX下你可以使用“:”,Windows下你可以使用“;”。
-
源代碼內存
infoline
命令來查看源代碼在內存中的地址。infoline後面可以跟“行號”,“函數名”,“文件名:行號”,“文件名:函數名”,這個命令會打印出所指定的源碼在運行時的內存地址
disassemble
可以查看源程序的當前執行時的機器碼
查看運行時數據
print<expr>
print /<f><expr>
<expr>是表達式,是你所調試的程序的語言的表達式(GDB可以調試多種編程語言),<f>是輸出的格式,比如,如果要把表達式按16進制的格式輸出,那麼就是/x
-
數組
“@”的左邊是第一個內存的地址的值,“@”的右邊則你你想查看內存的長度
(gdb) p *array@len
$1 ={2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,38, 40}如果是靜態數組的話,可以直接用print數組名,就可以顯示數組中所有數據的內容了 -
輸出格式
x按十六進制格式顯示變量。
d按十進制格式顯示變量。
u按十六進制格式顯示無符號整型。
o按八進制格式顯示變量。
t按二進制格式顯示變量。
a按十六進制格式顯示變量。
c按字符格式顯示變量。
F按浮點數格式顯示變量。 -
查看內存
examine命令
簡寫x
查看內存地址中的值
x/<n/f/u><addr>
n是一個正整數,表示顯示內存的長度,也就是說從當前地址向後顯示幾個地址的內容。
f表示顯示的格式,參見上面。如果地址所指的是字符串,那麼格式可以是s,如果地址是指令地址,那麼格式可以是i。
u表示從當前地址往後請求的字節數,如果不指定的話,GDB默認是4個bytes。u參數可以用下面的字符來代替,b表示單字節,h表示雙字節,w表示四字節,g表示八字節。當我們指定了字節長度後,GDB會從指內存定的內存地址開始,讀寫指定字節,並把其當作一個值取出來
<addr>表示一個內存地址
自動顯示
display<expr>
display/<fmt> <expr>
display/<fmt><addr>
expr是一個表達式,fmt表示顯示的格式,addr表示內存地址,當你用display設定好了一個或多個表達式後,只要你的程序被停下來,GDB會自動顯示你所設置的這些表達式的值。
格式i和s同樣被display支持,一個非常有用的命令是:
display/i$pc
$pc是GDB的環境變量,表示着指令的地址,/i則表示輸出格式爲機器指令碼,也就是彙編。於是當程序停下後,就會出現源代碼和機器指令碼相對應的情形,這是一個很有意思的功能。
undisplay<dnums...>
delete display<dnums...>
刪除自動顯示,dnums意爲所設置好了的自動顯式的編號。如果要同時刪除幾個,編號可以用空格分隔,如果要刪除一個範圍內的編號,可以用減號表示(如:2-5)
disabledisplay <dnums...>
enable display<dnums...>
disable和enalbe不刪除自動顯示的設置,而只是讓其失效和恢復
infodisplay
查看display設置的自動顯示的信息。GDB會打出一張表格,向你報告當然調試中設置了多少個自動顯示設置,其中包括,設置的編號,表達式,是否enable
-
設置顯示選項
setprint address
set print addresson
打開地址輸出,當程序顯示函數信息時,GDB會顯出函數的參數地址。系統默認爲打開的
setprint address off
關閉函數的參數地址顯示
showprint address
查看當前地址顯示選項是否打開
setprint array
set print arrayon
打開數組顯示,打開後當數組顯示時,每個元素佔一行,如果不打開的話,每個元素則以逗號分隔。這個選項默認是關閉的。
setprint array off
show print array
setprint elements <number-of-elements>
這個選項主要是設置數組的,如果你的數組太大了,那麼就可以指定一個<number-of-elements>來指定數據顯示的最大長度,當到達這個長度時,GDB就不再往下顯示了。如果設置爲0,則表示不限制。
showprint elements
查看printelements的選項信息
setprint null-stop <on/off>
如果打開了這個選項,那麼當顯示字符串時,遇到結束符則停止顯示。這個選項默認爲off
showprint pretty
查看GDB是如何顯示結構體的。
setprint sevenbit-strings<on/off>
設置字符顯示,是否按“/nnn”的格式顯示,如果打開,則字符串或字符數據按/nnn顯示,如“/065”。
showprint sevenbit-strings
查看字符顯示開關是否打開。
setprint union <on/off>
設置顯示結構體時,是否顯式其內的聯合體數據。
showprint union
查看聯合體數據的顯示方式
setprint object<on/off>
在C++中,如果一個對象指針指向其派生類,如果打開這個選項,GDB會自動按照虛方法調用的規則顯示輸出,如果關閉這個選項的話,GDB就不管虛函數表了。這個選項默認是off。
showprint object
查看對象選項的設置。
setprint static-members<on/off>
這個選項表示,當顯示一個C++對象中的內容是,是否顯示其中的靜態數據成員。默認是on。
showprint static-members
查看靜態數據成員選項設置。
setprint vtbl <on/off>
當此選項打開時,GDB將用比較規整的格式來顯示虛函數表時。其默認是關閉的。
showprint vtbl
查看虛函數顯示格式的選項
-
GDB環境變量
定義一個GDB的變量很簡單隻需。使用GDB的set命令。GDB的環境變量和UNIX一樣,也是以$起頭。如:
set $i = 0
print bar[$i++]->contents
於是,當你就不必,printbar[0]->contents, printbar[1]->contents地輸入命令了。輸入這樣的命令後,只用敲回車,重複執行上一條語句,環境變量會自動累加,從而完成逐個輸出的功能。
showconvenience
該命令查看當前所設置的所有的環境變量
-
查看寄存器
inforegisters
查看寄存器的情況。(除了浮點寄存器)
infoall-registers
查看所有寄存器的情況。(包括浮點寄存器)
inforegisters <regname ...>
查看所指定的寄存器的情況
-
語言環境
showlanguage
查看當前的語言環境。如果GDB不能識爲你所調試的編程語言,那麼,C語言被認爲是默認的環境。
infoframe
查看當前函數的程序語言。
infosource
查看當前文件的程序語言。
setlanguage
手動設置當前程序語言
setlanguage命令後什麼也不跟的話,你可以查看GDB所支持的語言種類: