gdb調試詳解

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)

相關文章
相關標籤/搜索