gdb參數詳解(整理過)

名稱
        gdb - GNU 調試器

提要
        gdb    [-help] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps]
              [-tty=dev] [-s symfile] [-e prog] [-se prog] [-c
              core] [-x cmds] [-d dir] [prog[core|procID]]

描述
        調試器(如GDB)的目的是允許你在程序運行時進入到某個程序內部去看看該程序在做什麼,或者在該程序崩潰時它在做什麼。

        GDB主要可以做4大類事(加上一些其他的輔助工作),以幫助用戶在程序運行過程中發現bug。

          o  啓動您的程序,並列出可能會影響它運行的一些信息
          o  使您的程序在特定條件下停止下來
          o  當程序停下來的時候,檢查發生了什麼
          o  對程序做出相應的調整,這樣您就能嘗試糾正一個錯誤並繼續發現其它錯誤

        您能使用GDB調試用C、C++、Modula-2寫的程序。等GNU Fortran編譯器準備好過後,GDB將提供對Fortran的支持

        GDB通過在命令行方式下輸入gdb來執行。啓動過後,GDB會從終端讀取命令,直到您輸入GDB命令quit使GDB退出。您能通過GDB命令help獲取在線幫助。

        您能以無參數無選項的形式運行GDB,不過通常的情況是以一到兩個參數運行GDB,以待調試的可執行程序名爲參數
        gdb 程序名

        您能用兩個參數來運行GDB,可執行程序名與core文件(譯註:不知道怎麼翻譯好,就不翻譯了)。
        gdb 程序名 core

        您可以以進程ID作爲第二個參數,以調式一個正在運行的進程
        gdb 程序名 1234
        將會把gdb附在進程1234之上(除非您正好有個文件叫1234,gdb總是先查找core文件)

       下面是一些最常用的GDB命令:

       file [filename]
              裝入想要調試的可執行文件

       kill [filename]
              終止正在調試的程序

       break [file:]function
              在(file文件的)function函數中設置一個斷點

       clear
              刪除一個斷點,這個命令需要指定代碼行或者函數名作爲參數

       run [arglist]
              運行您的程序 (如果指定了arglist,則將arglist作爲參數運行程序)

       bt Backtrace: 顯示程序堆棧信息

       print expr
              打印表達式的值

       continue
              繼續運行您的程序 (在停止之後,比如在一個斷點之後)

       list
              列出產生執行文件的源代碼的一部分

       next
              單步執行 (在停止之後); 跳過函數調用

       nexti
              執行下一行的源代碼中的一條彙編指令

       set
              設置變量的值。例如:set nval=54 將把54保存到nval變量中

       step
              單步執行 (在停止之後); 進入函數調用

       stepi
              繼續執行程序下一行源代碼中的彙編指令。如果是函數調用,這個命令將進入函數的內部,單步執行函數中的彙編代碼

       watch
              使你能監視一個變量的值而不管它何時被改變

       rwatch
              指定一個變量,如果這個變量被讀,則暫停程序運行,在調試器中顯示信息,並等待下一個調試命令。參考rwatch和watch命令

       awatch
              指定一個變量,如果這個變量被讀或者被寫,則暫停程序運行,在調試器中顯示信息,並等待下一個調試命令。參考rwatch和watch命令

       Ctrl-C
              在當前位置停止執行正在執行的程序,斷點在當前行

       disable
              禁止斷點功能,這個命令需要禁止的斷點在斷點列表索引值作爲參數

       display
              在斷點的停止的地方,顯示指定的表達式的值。(顯示變量)

       undisplay
              刪除一個display設置的變量顯示。這個命令需要將display list中的索引做參數

       enable
              允許斷點功能,這個命令需要允許的斷點在斷點列表索引值作爲參數

       finish
              繼續執行,直到當前函數返回

       ignore
              忽略某個斷點制定的次數。例:ignore 4 23 忽略斷點4的23次運行,在第24次的時候中斷

       info [name]
              查看name信息

       load
              動態載入一個可執行文件到調試器

       xbreak
              在當前函數的退出的點上設置一個斷點

       whatis
              顯示變量的值和類型

       ptype
              顯示變量的類型

       return
              強制從當前函數返回

       txbreak
              在當前函數的退出的點上設置一個臨時的斷點(只可使用一次)

       make
              使你能不退出 gdb 就可以重新產生可執行文件

       shell
              使你能不離開 gdb 就執行 UNIX shell 命令

       help [name]
              顯示GDB命令的信息,或者顯示如何使用GDB的總體信息

       quit
              退出gdb.

       要得到所有使用GDB的資料,請參考Using GDB: A Guide to the GNU
       Source-Level  Debugger,  by Richard M. Stallman and Roland
       H. Pesch.  當用info查看的時候,也能看到相同的文章

選項
        任何參數而非選項指明瞭一個可執行文件及core 文件(或者進程ID);所
        遇到的第一個未關聯選項標誌的參數與 '-se' 選項等價,第二個,如果存
        在,且是一個文件的名字,則等價與 '-c' 選項。許多選項都有一個長格式
        與短格式;都會在這裏表示出來。如果你把一個長格式截短,只要不引起歧
        義,那麼它還是可以被識別。(如果你願意,你可以使用 '+' 而非 '-' 標
        記選項參數,不過我們在例子中仍然遵從通常的慣例)

        -help

       -h     列出所有選項,並附簡要說明。  

       -symbols=file

       -s file
              讀出文件(file)中的符號表。

       -write
              開通(enable)往可執行文件和核心文件寫的權限。

       -exec=file

       -e file
              在適當時候把File作爲可執行的文件執行,來檢測與core dump結合的數據。
       -se File
              從File讀取符號表並把它作爲可執行文件。
       -core File
       -c File
              把File作爲core dump來執行。
       -command=File
       -x File
              從File中執行GDB命令。
       -directory=Directory
       -d Directory
              把Dicrctory加入源文件搜索的路徑中。
       -nx
       -n
              不從任何.gdbinit初始化文件中執行命令。通常情況下,這些文件中的命令是在所有命令選項和參數處理完後才執行。
       -quiet
       -q
              "Quiet".不輸入介紹和版權信息。這些信息輸出在batch模式下也被關閉。
       -batch
              運行batch模式。在處理完所有用'-x'選項指定的命令文件(還有'.gdbi-nit',如果沒禁用)後退出,並返回狀態碼0.如果在命令文件中的命令被
執行時發生錯誤,則退出,並返回狀態碼非0.batch模式對於運行GDB作爲過濾器也許很有用,比如要從另一臺電腦上下載並運行一個程序;爲了讓這些更有用,當
在batch模式下運行時,消息:Program exited normally.(不論什麼時候,一個程序在GDB控制下終止運行,這條消息都會正常發出.),將不會發出.
       -cd=Directory
              運行GDB,使用Directory作爲它的工作目錄,取代當前工作目錄.
       -fullname
       -f
              當Emacs讓GDB作爲一個子進程運行時,設置這個選項.它告訴GDB每當一個堆棧結構(棧幀)顯示出來(包括每次程序停止)就用標準的,認同的方式
輸出文件全名和行號.這裏,認同的格式看起來像兩個' 32'字符,緊跟文件名,行號和字符位置(由冒號,換行符分隔).Emacs同GDB的接口程序使用這兩個' 32'字
符作爲一個符號爲框架來顯示源代碼.
       -b Bps
              設置行速(波特率或bits/s).在遠程調試中GDB在任何串行接口中使用的行速.
       -tty=Device
              使用Device作爲你程序運行的標準輸入輸出.


gdb主要調試的是C/C++的程序。要調試C/C++的程序,首先在編譯時,必須要把調試信息加到可執行文件中。使用編譯器(cc/gcc/g++)的 -g 參數即可。如:

[david@DAVID david]$ gcc -g hello.c -o hello

[david@DAVID david]$ g++ -g hello.cpp -o hello

如果沒有-g,將看不見程序的函數名和變量名,代替它們的全是運行時的內存地址。當用-g把調試信息加入,併成功編譯目標代碼以後,看看如何用gdb來調試。

啓動gdb的方法有以下幾種:

1. gdb <program>
program也就是執行文件,一般在當前目錄下。

2. gdb <program> core
用gdb同時調試一個運行程序和core文件,core是程序非法執行後,core dump後產生的文件。

3. gdb <program> <PID>
如果程序是一個服務程序,那麼可以指定這個服務程序運行時的進程ID。gdb會自動attach上去,並調試它。program應該在PATH環境變量中搜索得到。

gdb啓動時,可以加上一些gdb的啓動開關,詳細的開關可以用gdb -help查看。下面只列舉一些比較常用的參數:

-symbols <file>

-s <file>

從指定文件中讀取符號表。

-se file

從指定文件中讀取符號表信息,並把它用在可執行文件中。

-core <file>

-c <file>

調試時core dump的core文件。

-directory <directory>

-d <directory>

加入一個源文件的搜索路徑。默認搜索路徑是環境變量中PATH所定義的路徑。

4.1.1  gdb的命令概貌
啓動gdb後,進入gdb的調試環境中,就可以使用gdb的命令開始調試程序了。gdb的命令可以使用help命令來查看,如下所示:  

[david@DAVID david]$ gdb

GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)

Copyright 2003 Free Software Foundation, Inc.

gdb is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for gdb.  Type "show warranty" for details.

This gdb was configured as "i386-redhat-Linux-gnu".

(gdb) help

List of classes of commands:

aliases -- Aliases of other commands

breakpoints -- Making program stop at certain points

data -- Examining data

files -- Specifying and examining files

internals -- Maintenance commands

obscure -- Obscure features

running -- Running the program

stack -- Examining the stack

status -- Status inquiries

support -- Support facilities

tracepoints -- Tracing of program execution without stopping the program

user-defined -- User-defined commands

 

Type "help" followed by a class name for a list of commands in that class.

Type "help" followed by command name for full documentation.

Command name abbreviations are allowed if unambiguous.

(gdb)

gdb的命令很多,gdb將之分成許多種類。help命令只是列出gdb的命令種類,如果要看其中的命令,可以使用help <class> 命令。如:

(gdb) help data

也可以直接用help [command]來查看命令的幫助。

gdb中,輸入命令時,可以不用輸入全部命令,只用輸入命令的前幾個字符就可以了。當然,命令的前幾個字符應該標誌着一個惟一的命令,在Linux下,可以按兩次TAB鍵來補齊命令的全稱,如果有重複的,那麼gdb會把它全部列出來。

示例一:在進入函數func時,設置一個斷點。可以輸入break func,或是直接輸入b func。

(gdb) b func

Breakpoint 1 at 0x804832e: file test.c, line 5.

(gdb)

示例二:輸入b按兩次TAB鍵,你會看到所有b開頭的命令。

(gdb) b

backtrace  break  bt

要退出gdb時,只用輸入quit或其簡稱q就行了。

4.1.2  gdb中運行Linux的shell程序
在gdb環境中,可以執行Linux的shell命令:

shell <command string>

調用Linux的shell來執行<command string>,環境變量SHELL中定義的Linux的shell將會用來執行<command string>。如果SHELL沒有定義,那就使用Linux的標準shell:/bin/sh(在Windows中使用Command.com或cmd.exe)。

還有一個gdb命令是make:

make <make-args>

可以在gdb中執行make命令來重新build自己的程序。這個命令等價於shell make <make-args>。 

4.1.3  在gdb中運行程序
當以gdb <program>方式啓動gdb後,gdb會在PATH路徑和當前目錄中搜索<program>的源文件。如要確認gdb是否讀到源文件,可使用l或list命令,看看gdb是否能列出源代碼。

在gdb中,運行程序使用r或是run命令。程序的運行,有可能需要設置下面四方面的事。

1. 程序運行參數
set args 可指定運行時參數。如:

set args 10 20 30 40 50

show args 命令可以查看設置好的運行參數。

2. 運行環境
path <dir> 可設定程序的運行路徑。

show paths 查看程序的運行路徑。

set environment varname [=value] 設置環境變量。如:

set env USER=hchen

show environment [varname] 查看環境變量。

3. 工作目錄
cd <dir> 相當於shell的cd命令。

pwd 顯示當前的所在目錄。

4. 程序的輸入輸出
info terminal 顯示程序用到的終端的模式。

使用重定向控制程序輸出。如:

run > outfile

tty命令可以指寫輸入輸出的終端設備。如:

tty /dev/ttyb

4.1.4  調試已運行的程序
調試已經運行的程序有兩種方法:

●       在Linux下用ps(第一章已經對ps作了介紹)查看正在運行的程序的PID(進程ID),然後用gdb <program> PID格式掛接正在運行的程序。

●       先用gdb <program>關聯上源代碼,並進行gdb,在gdb中用attach命令來掛接進程的PID,並用detach來取消掛接的進程。

4.1.5  暫停/恢復程序運行
調試程序中,暫停程序運行是必需的,gdb可以方便地暫停程序的運行。可以設置程序在哪行停住,在什麼條件下停住,在收到什麼信號時停往等,以便於用戶查看運行時的變量,以及運行時的流程。

當進程被gdb停住時,可以使用info program 來查看程序是否在運行、進程號、被暫停的原因。

在gdb中,有以下幾種暫停方式:斷點(BreakPoint)、觀察點(WatchPoint)、捕捉點(CatchPoint)、信號(Signals)及線程停止(Thread Stops)。

如果要恢復程序運行,可以使用c或是continue命令。

1. 設置斷點(BreakPoint)  
用break命令來設置斷點。有下面幾種設置斷點的方法:

break <function>

在進入指定函數時停住。C++中可以使用class::function或function(type,type)格式來指定函數名。

break <linenum>

在指定行號停住。

break +offset

break -offset

在當前行號的前面或後面的offset行停住。offiset爲自然數。

break filename:linenum

在源文件filename的linenum行處停住。

break filename:function

在源文件filename的function函數的入口處停住。

break *address

在程序運行的內存地址處停住。

break

該命令沒有參數時,表示在下一條指令處停住。

break ... if <condition>

condition表示條件,在條件成立時停住。比如在循環體中,可以設置break if i=100,表示當i爲100時停住程序。

查看斷點時,可使用info命令,如下所示(注:n表示斷點號):

info breakpoints [n]

info break [n] 

2. 設置觀察點(WatchPoint)  
觀察點一般用來觀察某個表達式(變量也是一種表達式)的值是否變化了。如果有變化,馬上停住程序。有下面的幾種方法來設置觀察點: 

watch <expr>

爲表達式(變量)expr設置一個觀察點。一旦表達式值有變化時,馬上停住程序。    

rwatch <expr>

當表達式(變量)expr被讀時,停住程序。   

awatch <expr>

當表達式(變量)的值被讀或被寫時,停住程序。

info watchpoints

列出當前設置的所有觀察點。

3. 設置捕捉點(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>

只設置一次捕捉點,當程序停住以後,應點被自動刪除。

4. 維護停止點
上面說了如何設置程序的停止點,gdb中的停止點也就是上述的三類。在gdb中,如果覺得已定義好的停止點沒有用了,可以使用delete、clear、disable、enable這幾個命令來進行維護。

Clear

清除所有的已定義的停止點。

clear <function>

clear <filename:function>

清除所有設置在函數上的停止點。

clear <linenum>

clear <filename:linenum>

清除所有設置在指定行上的停止點。

delete [breakpoints] [range...]

刪除指定的斷點,breakpoints爲斷點號。如果不指定斷點號,則表示刪除所有的斷點。range 表示斷點號的範圍(如:3-7)。其簡寫命令爲d。

比刪除更好的一種方法是disable停止點。disable了的停止點,gdb不會刪除,當還需要時,enable即可,就好像回收站一樣。

disable [breakpoints] [range...]

disable所指定的停止點,breakpoints爲停止點號。如果什麼都不指定,表示disable所有的停止點。簡寫命令是dis.

enable [breakpoints] [range...]

enable所指定的停止點,breakpoints爲停止點號。

enable [breakpoints] once range...

enable所指定的停止點一次,當程序停止後,該停止點馬上被gdb自動disable。

enable [breakpoints] delete range...

enable所指定的停止點一次,當程序停止後,該停止點馬上被gdb自動刪除。

5. 停止條件維護
前面在介紹設置斷點時,提到過可以設置一個條件,當條件成立時,程序自動停止。這是一個非常強大的功能,這裏,專門介紹這個條件的相關維護命令。

一般來說,爲斷點設置一個條件,可使用if關鍵詞,後面跟其斷點條件。並且,條件設置好後,可以用condition命令來修改斷點的條件(只有break和watch命令支持if,catch目前暫不支持if)。

condition <bnum> <expression>

修改斷點號爲bnum的停止條件爲expression。

condition <bnum>

清除斷點號爲bnum的停止條件。

還有一個比較特殊的維護命令ignore,可以指定程序運行時,忽略停止條件幾次。

ignore <bnum> <count>

表示忽略斷點號爲bnum的停止條件count次。

6. 爲停止點設定運行命令
可以使用gdb提供的command命令來設置停止點的運行命令。也就是說,當運行的程序在被停住時,我們可以讓其自動運行一些別的命令,這很有利行自動化調試。

commands [bnum]

... command-list ...

end

爲斷點號bnum指定一個命令列表。當程序被該斷點停住時,gdb會依次運行命令列表中的命令。

例如:

break foo if x>0

commands

printf "x is %d/n",x

continue

end

斷點設置在函數foo中,斷點條件是x>0,如果程序被斷住後,也就是一旦x的值在foo函數中大於0,gdb會自動打印出x的值,並繼續運行程序。

如果要清除斷點上的命令序列,那麼只要簡單地執行一下commands命令,並直接在輸入end就行了。

7. 斷點菜單
在C++中,可能會重複出現同一個名字的函數若干次(函數重載)。在這種情況下,break <function>不能告訴gdb要停在哪個函數的入口。當然,可以使用break <function(type)>,也就是把函數的參數類型告訴gdb,以指定一個函數。否則的話,gdb會列出一個斷點菜單供用戶選擇所需要的斷點。只要輸入菜單列表中的編號就可以了。如:

(gdb) b String::after

[0] cancel

[1] all

[2] file:String.cc; line number:867

[3] file:String.cc; line number:860

[4] file:String.cc; line number:875

[5] file:String.cc; line number:853

[6] file:String.cc; line number:846

[7] file:String.cc; line number:735

> 2 4 6

Breakpoint 1 at 0xb26c: file String.cc, line 867.

Breakpoint 2 at 0xb344: file String.cc, line 875.

Breakpoint 3 at 0xafcc: file String.cc, line 846.

Multiple breakpoints were set.

Use the "delete" command to delete unwanted

breakpoints.

(gdb)   

可見,gdb列出了所有after的重載函數,選一下列表編號就行了。0表示放棄設置斷點,1表示所有函數都設置斷點。

8. 恢復程序運行和單步調試
當程序被停住後,可以用continue命令恢復程序的運行直到程序結束,或下一個斷點到來。也可以使用step或next命令單步跟蹤程序。

continue [ignore-count]

c [ignore-count]

fg [ignore-count]

恢復程序運行,直到程序結束,或是下一個斷點到來。ignore-count表示忽略其後的斷點次數。continue,c,fg三個命令都是一樣的意思。

step <count>

單步跟蹤,如果有函數調用,它會進入該函數。進入函數的前提是,此函數被編譯有debug信息。很像VC等工具中的step in。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。

next <count>

同樣單步跟蹤,如果有函數調用,它不會進入該函數(很像VC等工具中的step over)。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。

set step-mode

set step-mode on

打開step-mode模式。在進行單步跟蹤時,程序不會因爲沒有debug信息而不停住。這個參數有很利於查看機器碼。

set step-mod off

關閉step-mode模式。

finish

運行程序,直到當前函數完成返回。並打印函數返回時的堆棧地址和返回值及參數值等信息。

until 或 u

當厭倦了在一個循環體內單步跟蹤時,這個命令可以運行程序直到退出循環體。

stepi 或 si

nexti 或 ni

單步跟蹤一條機器指令。一條程序代碼有可能由數條機器指令完成,stepi和nexti可以單步執行機器指令。與之一樣有相同功能的命令是display/i $pc,當運行完這個命令後,單步跟蹤會在顯示出程序代碼的同時顯示出機器指令(也就是彙編代碼)。

9. 信號(Signals)
信號是一種軟中斷,是一種處理異步事件的方法。

一般來說,操作系統都支持許多信號,尤其是Linux,比較重要的應用程序一般都會處理信號。Linux定義了許多信號,比如SIGINT表示中斷字符信號,也就是Ctrl+C的信號,SIGBUS表示硬件故障的信號;SIGCHLD表示子進程狀態改變信號;SIGKILL表示終止程序運行的信號等。信號量編程是UNIX下非常重要的一種技術。

gdb有能力在調試程序的時候處理任何一種信號。可以告訴gdb需要處理哪一種信號;可以要求gdb收到所指定的信號時,馬上停住正在運行的程序,以供用戶進行調試。可用gdb的handle命令來完成這一功能。

handle <signal> <keywords...>

在gdb中定義一個信號處理。信號<signal>可以以SIG開頭或不以SIG開頭,可以定義一個要處理信號的範圍(如:SIGIO-SIGKILL,表示處理從SIGIO信號到SIGKILL的信號,其中包括SIGIO,SIGIOT,SIGKILL三個信號),也可以使用關鍵字all來標明要處理所有的信號。一旦被調試的程序接收到信號,運行程序馬上會被gdb停住,以供調試。其<keywords>可以是以下幾種關鍵字中的一個或多個。

nostop

當被調試的程序收到信號時,gdb不會停住程序的運行,但會顯示出消息告訴用戶收到這種信號。

stop

當被調試的程序收到信號時,gdb會停住程序。

print

當被調試的程序收到信號時,gdb會顯示出一條信息。

noprint

當被調試的程序收到信號時,gdb不會告訴用戶收到信號的信息。

Pass

noignore

當被調試的


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章