1. 程式人生 > >GDB偵錯程式手冊[轉]

GDB偵錯程式手冊[轉]

GDB偵錯程式使用手冊.


START-INFO-DIR-ENTRY
* Gdb: (gdb).                     The GNU debugger.
END-INFO-DIR-ENTRY
   This file documents the GNU debugger GDB.

   This is Edition 4.12, January 1994, of `Debugging with GDB: the GNU
Source-Level Debugger' for GDB Version 4.16.

   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995 Free
Software Foundation, Inc.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.

使用GDB:
   本文描述GDB,GNU的原始碼偵錯程式。(這是4.12版1994年一月,GDB版本4。16)
* 目錄:
* 摘要:                        GDB的摘要
* 例項:                          一個使用例項
* 入門:                        進入和退出GDB
* 命令:                        GDB 的命令
* 執行:                        在GDB下執行程式
* 停止:                        暫停和繼續執行
* 棧:                          檢查堆疊
* 原檔案:                      檢查原檔案
* 資料:                        檢查資料
* 語言:                        用不同的語言來使用GDB
* 符號:                         檢查符號表
* 更改:                         更改執行
* GDB的檔案                     檔案
* 物件                          指定除錯物件
* 控制GDB                       控制
* 執行序列:                    執行一序列命令
* Emacs:                        使GDB和Emacs一起工作
* GDB的bug:
* 命令列編輯:                  行編輯
* 使用歷史記錄互動:
* 格式化文件:                  如何格式化和列印GDB文件
* 安裝GDB :

* 索引:

GDB簡介:
**************

   偵錯程式(比如象GDB)能讓你觀察另一個程式在執行時的內部活動,或程式出錯時
發生了什麼。
   GDB主要能為你做四件事(包括為了完成這些事而附加的功能),幫助你找出程式
中的錯誤。
   * 執行你的程式,設定所有的能影響程式執行的東西。

   * 保證你的程式在指定的條件下停止。

   * 當你程式停止時,讓你檢查發生了什麼。

   * 改變你的程式。那樣你可以試著修正某個bug引起的問題,然後繼續查詢另一
     個bug.

   你可以用GDB來除錯C和C++寫的程式。(參考 *C 和C++)

   部分支援Modula-2和chill,但現在還沒有這方面的文件。

   除錯Pascal程式時,有一些功能還不能使用。

  GDB還可以用來除錯FORTRAN程式,儘管現在還不支援表示式的輸入,輸出變數,
或類FORTRAN的詞法。
* GDB是"free software",大家都可以免費拷貝。也可以為GDB增加新的功能,不
過可要遵守GNU的許可協議么。反正我認為GNU還是比較不錯的:-)
就這句話:
   Fundamentally, the General Public License is a license which says
that you have these freedoms and that you cannot take these freedoms
away from anyone else.
GDB的作者:
   Richard Stallman是GDB的始作俑者,另外還有許多別的GNU的成員。許多人
為此作出了貢獻。(都是老外不提也罷,但願他們不要來找我麻煩:-))
這裡是GDB的一個例子: 
        原文中是使用一個叫m4的程式。但很遺憾我找不到這個程式的原始碼, 
所以沒有辦法來按照原文來說明。不過反正是個例子,我就拿一個作業系統的 
程序排程原碼來說明把,原始碼我會附在後面。 
        首先這個程式叫os.c是一個模擬程序排程的原程式(也許是個老古董了:-))。 
先說明一下如何取得包括原始碼符號的可執行程式碼。大家有心的話可以去看一下gcc的 
man檔案(在shell下打man gcc)。gcc -g <原檔案.c> -o <要生成的檔名> 
-g 的意思是生成帶原始碼除錯符號的可執行檔案。 
-o 的意思是指定可執行檔名。 
(gcc 的命令列引數有一大堆,有興趣可以自己去看看。) 
反正在linux下把os.c用以上方法編譯連線以後就產生了可供gdb使用的可執行檔案。 
我用gcc -g os.c -o os,產生的可執行文件叫os. 
然後打gdb os,就可進入gdb,螢幕提示: 
     GDB is free software and you are welcome to 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. 
 
     GDB 4.16, Copyright 1995 Free Software Foundation, Inc... 
 (gdb) 
  (gdb)是提示符,在這提示符下可以輸入命令,直到退出。(退出命令是q/Q) 
為了儘量和原文件說明的命令相符,即使在本例子中沒用的命令我也將演示。 
首先我們可以設定gdb的螢幕大小。鍵入: 
 (gdb)set width 70 
就是把標準螢幕設為70列。 
  然後讓我們來設定斷點。設定方法很簡單:break或簡單打b後面加行號或函式名 
比如我們可以在main 函式上設斷點: 
 (gdb)break main 
或(gdb)b main 
 系統提示:Breakpoint 1 at 0x8049552: file os.c, line 455. 
 然後我們可以執行這個程式,當程式執行到main函式時程式就會停止返回到gdb的 
提示符下。執行的命令是run或r(gdb中有不少alias,可以看一下help,在gdb下打help) 
run 後面可以跟引數,就是為程式指定命令列引數。 
比如r abcd,則程式就會abcd以作為引數。(這裡要說明的是可以用set args來指定參 
數)。打入r或run後,程式就開始執行直到進入main的入口停止,顯示: 
Starting program: <路徑>/os 
 
Breakpoint 1, main () at os.c:455 
455            Initial(); 
這裡455 Initial();是將要執行的命令或函式。 
gdb提供兩種方式:1.單步進入,step into就是跟蹤到函式內啦。命令是step或s 
                 2.單步,next,就是簡單的單步,不會進入函式。命令是next或n 
這兩個命令還有別的用法以後再說。 
我們用n命令,鍵入: 
(gdb)n 
Success forking process# 1 ,pid is 31474 
 
Success forking process# 2 ,pid is 31475 
 
Success forking process# 3 ,pid is 31476 
 
Success forking process# 4 ,pid is 31477 
 
Success forking process# 5 ,pid is 31478 
 
Success forking process# 6 ,pid is 31479 
 
                Dispatching Algorithm : FIFO 
******************************************************************************** 
 
            PCB#        PID     Priority        PC      State 
            1           31474      24            0      WAITING 
            2           31475      19            0      WAITING 
            3           31476      16            0      WAITING 
            4           31477      23            0      WAITING 
            5           31478      22            0      WAITING 
            6           31479      20            0      WAITING 
 
****************************************************************************** 
 
CPU  :  NO process running 
IO :  No process 
Waiting CPU!!!  31474   31475   31476   31477   31478   31479 
Waiting  IO    NONE 
456            State=WAITING; 
最後的一行就是下一句要執行的命令。我們現在在另一個函式上加斷點。注意我們 
可以用l/list命令來顯示原始碼。這裡我們鍵入 
(gdb)l 
451     main() 
452     { 
453             int message; 
454 
455            Initial(); 
456            State=WAITING; 
457            printf("Use Control-C to halt \n"); 
458            signal(SIGALRM,AlarmMessage); 
459            signal(SIGINT,InteruptMessage); 
460            signal(SIGUSR2,IoMessage); 
(gdb) l 
461            alarm(TimeSlot); 
462            for(;;) 
463             { 
464             message=GetMessage(); 
465                   switch(message) 
466                     { 
467                             case INTERRUPT :        printf("Use Control-C t; 
 
468                                                     break; 
469                             case CHILD_IO:          WaitingIo(); 
470                                                     break; 
顯示了原始碼,現在在AlarmMessage上加斷點。 
(gdb) b AlarmMessage 
Breakpoint 2 at 0x8048ee3: file os.c, line 259. 
(gdb) 
然後我們繼續執行程式。 
(gdb)c 
c或continue命令讓我們繼續被中斷的程式。 顯示: 
Continuing. 
Use Control-C to halt 
 
Breakpoint 2, AlarmMessage () at os.c:259 
259             ClearSignal(); 
注意我們下一句語句就是ClearSignal(); 
我們用s/step跟蹤進入這個函式看看它是幹什麼的。 
(gdb) s 
ClearSignal () at os.c:227 
227             signal(SIGINT,SIG_IGN); 
用l命令列出原始碼: 
(gdb) l 
222     } 
223 
224 
225     void ClearSignal()    /* Clear other signals */ 
226     { 
227             signal(SIGINT,SIG_IGN); 
228             signal(SIGALRM,SIG_IGN); 
229             signal(SIGUSR2,SIG_IGN); 
230     } 
231 
(gdb) 
我們可以用s命令繼續跟蹤。現在讓我們來試試bt或backtrace命令。這個命令可以 
顯示棧中的內容。 
(gdb) bt 
#0  ClearSignal () at os.c:227 
#1  0x8048ee8 in AlarmMessage () at os.c:259 
#2  0xbffffaec in ?? () 
#3  0x80486ae in ___crt_dummy__ () 
(gdb) 
大家一定能看懂顯示的意思。棧頂是AlarmMessage,接下來的函式沒有名字--就是 
沒有原始碼符號。這顯示了函式呼叫的巢狀。 
好了,我們跟蹤了半天還沒有檢查過變數的值呢。檢查表示式的值的命令是p或print 
格式是p <表示式> 
444444讓我們來找一個變數來看看。:-) 
(gdb)l 1 
還記得l的作用嗎?l或list顯示原始碼符號,l或list加<行號>就顯示從<行號>開始的 
原始碼。好了找到一個讓我們來看看WaitingQueue的內容 
(gdb) p WaitingQueue 
$1 = {1, 2, 3, 4, 5, 6, 0} 
(gdb) 
WaitingQueue是一個數組,gdb還支援結構的顯示, 
(gdb) p Pcb 
$2 = {{Pid = 0, State = 0, Prior = 0, pc = 0}, {Pid = 31474, State = 2, 
    Prior = 24, pc = 0}, {Pid = 31475, State = 2, Prior = 19, pc = 0}, { 
    Pid = 31476, State = 2, Prior = 16, pc = 0}, {Pid = 31477, State = 2, 
    Prior = 23, pc = 0}, {Pid = 31478, State = 2, Prior = 22, pc = 0}, { 
    Pid = 31479, State = 2, Prior = 20, pc = 0}} 
(gdb) 
這裡可以對照原程式看看。 
原文件裡是一個除錯過程,不過我想這裡我已經把gdb的常用功能介紹了一遍,基本上 
可以用來除錯程式了。:-) 


執行GDB(一些詳細的說明): 
 
  前面已經提到過如何執行GDB了,現在讓我們來看一些更有趣的東西。你可以在執行 
GDB時通過許多命令列引數指定大量的引數和選項,通過這個你可以在一開始就設定好 
程式執行的環境。 
  這裡將要描述的命令列引數覆蓋了大多數的情況,事實上在一定環境下有的並沒有 
什麼大用處。最通常的命令就是使用一個引數: 
 $gdb <可執行文件名> 
你還可以同時為你的執行檔案指定一個core檔案: 
 $gdb <可執行檔名> core 
你也可以為你要執行的檔案指定一個程序號: 
 $gdb <可執行檔名> <程序號> 如:&gdb os 1234將使gdb與程序1234相聯絡(attach) 
除非你還有一個檔案叫1234的。gdb首先檢查一個core檔案。 
如果你是使用一個遠端終端進行遠端除錯的話,那如果你的終端不支援的話,你將無法 
使用第二個引數甚至沒有core dump。如果你覺得開頭的提示資訊比較礙眼的話,你可以 
用gdb -silent。你還可以用命令列引數更加詳細的控制GDB的行為。 
打入gdb -help或-h 可以得到這方面的提示。所有的引數都被按照排列的順序傳給gdb 
除非你用了-x引數。 
  當gdb開始執行時,它把任何一個不帶選項字首的引數都當作為一個可執行檔案或core 
檔案(或程序號)。就象在前面加了-se或-c選項。gdb把第一個前面沒有選項說明的引數 
看作前面加了-se 選項,而第二個(如果有的話)看作是跟著-c選項後面的。 
  許多選項有縮寫,用gdb -h可以看到。在gdb中你也可以任意的把選項名掐頭去尾,只 
要保證gdb能判斷唯一的一個引數就行。 
在這裡我們說明一些最常用的引數選項 
-symbols <檔名>(-s <檔名>)------從<檔名>中讀去符號。 
-exec <檔名>(-e <檔名>)----在合適的時候執行<檔名>來做用正確的資料與core 
 dump的作比較。 
-se <檔名>------從<檔名>中讀取符號並把它作為可執行檔案。 
-core <檔名>(-c <檔名>)--指定<檔名>為一個core dump 檔案。 
-c <數字>----連線到程序號為<數字>,與attach命令相似。 
-command <檔名> 
-x <檔名>-----執行gdb命令,在<檔名>指定的檔案中存放著一序列的gdb命令,就 
象一個批處理。 
-directory(-d) <路徑>---指定路徑。把<路徑>加入到搜尋原檔案的路徑中。 
-m 
-mapped---- 
   注意這個命令不是在所有的系統上都能用。如果你可以通過mmap系統呼叫來獲得記憶體 
映象檔案,你可以用這個命令來使gdb把你當前檔案裡的符號寫入一個檔案中,這個檔案 
將存放在你的當前路徑中。如果你除錯的程式叫/temp/fred那麼map檔案就叫 
./fred.syms這樣當你以後再除錯這個程式時,gdb會認識到這個檔案的存在,從而從這 
個檔案中讀取符號,而不是從可執行檔案中讀取。.syms與主機有關不能共享。 
-r 
-readnow---馬上從符號檔案中讀取整個符號表,而不是使用預設的。預設的符號表是 
調入一部分符號,當需要時再讀入一部分。這會使開始進入gdb慢一些,但可以加快以後 
的除錯速度。 
 
 -m和-r一般在一起使用來建立.syms檔案 
 
 
接下來再談談模式的設定(請聽下回分解 :-)) 
附:在gdb文件裡使用的除錯例子我找到了在minix下有這個程式,叫m4有興趣的 
可以自己去看看模式的選擇 
-------------- 
現在我們來聊聊gdb執行模式的選擇。我們可以用許多模式來執行gdb,例如在"批模式" 
或"安靜模式"。這些模式都是在gdb執行時在命令列作為選項指定的。 
`-nx' 
`-n' 
     不執行任何初始化檔案中的命令。(一般初始化檔案叫做`.gdbinit').一般情況下在 
這些檔案中的命令會在所有的命令列引數都被傳給gdb後執行。 
 
`-quiet' 
`-q' 
     "安靜模式"。不輸出介紹和版權資訊。這些資訊在"批模式"中也被跳過。 
 
`-batch' 
     "批模式"。在"批模式"下執行。當在命令檔案中的所有命令都被成功的執行後 
     gdb返回狀態"0",如果在執行過程中出錯,gdb返回一個非零值。 
     "批模式"在把gdb作為一個過濾器執行時很有用。比如在一臺遠端計算機上下載且 
     執行一個程式。資訊" Program exited normally"(一般是當執行的程式正常結束 
     時出現)不會在這種模式中出現。 
`-cd DIRECTORY' 
     把DIRECTORY作為gdb的工作目錄,而非當前目錄(一般gdb預設把當前目錄作為工作目 
     錄)。 
`-fullname' 
`-f' 
     GNU Emacs 設定這個選項,當我們在Emacs下,把gdb作為它的一個子程序來執行時, 
     Emacs告訴gdb按標準輸出完整的檔名和行號,一個可視的棧內容。這個格式跟在 
     檔名的後面。行號和字元重新按列排,Emacs-to-GDB介面使用\032字元作為一個 
     顯示一頁原檔案的訊號。 
`-b BPS' 
     為遠端除錯設定波特率。 
 
`-tty DEVICE' 
     使用DEVICE來作為你程式的標準輸入輸出。 

退出gdb 
============ 
 
`quit' 
     使用'quit'命令來退出gdb,或打一個檔案結束符(通常是' CTROL-D')。如果 
     你沒有使用表示式,gdb會正常退出,否則它會把表示式的至作為error code 
     返回。 
 
     一箇中斷(通常是'CTROL-c)不會導致從gdb中退出,而是結束任何一個gdb的命 
     令,返回gdb的命令輸入模式。一般在任何時候使用'CTROL-C'是安全的,因為 
     gdb會截獲它,只有當安全時,中斷才會起作用。 
     如果你正在用gdb控制一個被連線的程序或裝置,你可以用'detach'命令來釋放 
     它。 
 
Shell命令 
============== 
    當你偶爾要執行一些shell命令時,你不必退出除錯過程,也不需要掛起它;你 
    可以使用'shell'命令。 
 
`shell COMMAND STRING' 
     呼叫標準shell來執行'COMMAND STRING'.環境變數'SHELL'決定了那個shell被 
     執行。否則gdb使用'/bin/sh'. 
     'make'工具經常在開發環境中使用,所以你可以不用'shell'命令而直接打'make' 
 
`make MAKE-ARGS' 
     用指定的命令列變數來執行'make'程式,這等於使用'shell make MAKE-ARGS' 
GDB 命令 
************ 
   我們可以把一個gdb命令縮寫成開頭幾個字母,如果這沒有二意性你可以直接回車來 
   執行。你還可以使用TAB鍵讓gdb給你完成接下來的鍵入,或向你顯示可選擇的命令, 
   如果有不止一個選擇的話。 
 
Command語法 
============== 
 
   一個gdb命令是一個單行的輸入。長度沒有限制。它一個命令開頭,後面可以跟參量。 
   比如命令'step'接受一個參量表示單步執行多少步。你也可以不用參量。有的命令 
   不接受任何參量。 
 
   gdb命令只要沒有二意性的話就可以被縮寫。另外一些縮寫作為一個命令列出。在某些 
   情況下二意也是允許的。比如's'是指定'step'的縮寫,但還有命令'start'。你可以把 
   這些縮寫作為'help'命令的參量來測試它們。 
   空行(直接回車)表示重複上一個命令。但有些命令不能重複比如象'run',就不會以這 
   種方式重複,另外一些當不小心重複會產生嚴重後果的命令也不能用這種方法重複。 
   'list'和'x'命令當你簡單的打回車時,會建立新的變數,而不是簡單的重複上一個命 
   令。這樣你可以方便的瀏覽原始碼和記憶體。 
   gdb還有一種解釋RET的方法:分割長輸出。這種方法就和'more'命令相似。由於這時經 
   常會不小心多打回車,gdb將禁止重複當一個命令產生很長的輸出時。 
   任何用'#'開頭一直到行尾的命令列被看作是註釋。主要在命令檔案中使用。 

輸入命令的技巧 
================== 
   前面已經提到過TAB鍵的使用。使用TAB鍵能讓你方便的得到所要的命令。比如 
在gdb中: 
   (gdb)info bre <TAB>(鍵入info bre,後按TAB鍵) 
   gdb能為你完成剩下的輸入。它還能萎蔫提供選擇的可能性。如果有兩個以上可 
能的話,第一次按<TAB>鍵,gdb會響鈴提示,第二次則顯示可能的選擇。同樣gdb 
也可以為一些子命令提供快速的訪問。用法與上相同。 
  上例中顯示 
   (gdb)info breakepoints 
   你也可以直接打回車,gdb就將你輸入的作為命令的可能的縮寫。來判斷執行。 
如果你打入的縮寫不足以判斷,那麼gdb會顯示一個列表,列出可能的命令。同樣的 
情況對於命令的引數。在顯示完後gdb把你的輸入拷貝到當前行以便讓你繼續輸入。 
   如果你只想看看命令的列表或選項,你可以在命令列下打M-?(就是按著ESC鍵 
同時按SHIFT和?鍵)。你可以直接在命令列下打試試。 
  (gdb)<M-?> 
   gdb會響鈴並顯示所有的命令。不過這種方式好象在遠端除錯是不行。當有的命令 
使用一個字串時,你可以用" ' "將其括起來。這種方法在除錯C++程式時特別有用。 
因為C++支援函式的過載。當你要在某個有過載函式上設斷點時,不得不給出函式引數 
以區分不同的過載函式。這時你就應該把整個函式用" ' "括起來。比如,你要在一個 
叫name的函式上設斷點,而這個函式被過載了(name(int)和name(float))。你將不得 
不給出參變數以區分不同的函式。使用'name(int)'和'name(float)'。這裡有個技巧, 
你可以在函式名前加一個" ' "符號。然後打M-?. 

得到幫助 
============ 
   你可以使用help命令來得到gdb的線上幫助。 
 
`help' 
`h' 
      你可以使用help或h後面不加任何引數來得到一個gdb命令類的列表。 
 
          (gdb) help 
          List of classes of commands: 
 
          running -- Running the program 
          stack -- Examining the stack 
          data -- Examining data 
          breakpoints -- Making program stop at certain points 
          files -- Specifying and examining files 
          status -- Status inquiries 
          support -- Support facilities 
          user-defined -- User-defined commands 
          aliases -- Aliases of other commands 
          obscure -- Obscure features 
 
          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) 
 
`help CLASS' 
     使用上面列出的help class作為help或h的參量,你可以得到單一的命令列表。 
     例如顯示一個'status'類的列表。 
 
          (gdb) help status 
          Status inquiries. 
 
          List of commands: 
 
          show -- Generic command for showing things set 
           with "set" 
          info -- Generic command for printing status 
 
          Type "help" followed by command name for full 
          documentation. 
          Command name abbreviations are allowed if unambiguous. 
          (gdb) 
 
`help COMMAND' 
     詳細列出單個命令的資料。 
 
`complete ARGS' 
     列出所有以ARGS開頭的命令。例如: 
 
          complete i 
 
     results in: 
 
          info 
          inspect 
          ignore 
 
     This is intended for use by GNU Emacs. 
 
   除了使用'help'你還可以使用gdb的命令'info'和'show'來查詢你程式的 
狀態,每個命令可以查詢一系列的狀態。這些命令以恰當的方式顯示所有的 
子命令。 
 
`info' 
     此命令(可以縮寫為'i')用來顯示你程式的狀態。比如,你可以使用info 
args 列出你程式所接受的命令列引數。使用info registers列出暫存器的狀態。 
或用info breakpoint列出在程式中設的斷點。要獲得詳細的關於info的資訊打 
help info. 
`set' 
     這個命令用來為你的程式設定一個執行環境(使用一個表示式)。比如你 
可以用set prompt $來把gdb的提示符設為$. 
 
`show' 
     與'info'相反,'show'命令用來顯示gdb自身的狀態。你使用'set'命令來 
可以改變絕大多數由'show'顯示的資訊。比如使用show radix命令來顯示基數。 
用不帶任何參變數的'set'命令你可以顯示所有你可以設定的變數的值。 
有三個變數是不可以用'set'命令來設定的。 
`show version' 
     顯示gdb的版本號。如果你發現gdb有bug的話你應該在bug-reports里加 
入gdb的版本號。 
 
`show copying' 
顯示版權資訊。 
 
`show warranty' 
顯示擔保資訊。 
在gdb下執行你的程式 
************************** 
   當你在gdb下執行程式時,你必須先為gdb準備好帶有除錯資訊的可執行文件。 
還可以在gdb中為你的程式設定參變數,重定向你程式的輸入/輸出,設定環境變 
量,除錯一個已經執行的程式或kill掉一個子程序。 
   這裡許多內容在早先的例子中都已經用到過,可以參見gdb(二)。 
目錄: 
 
* 編譯::                        為除錯編譯帶除錯資訊的程式碼 
* 執行::                        執行你的程式 
* 參變數::                      為你的程式設定參變數 
* 執行環境::                    為你的程式設定執行時環境 
* 設定工作目錄::                在gdb中設定程式的工作目錄。 
* 輸入/輸出::                   設定你程式的輸入和輸出 
* 連線::                        除錯一個已經執行的程式 
* 結束子程序::                  Kill子程序 
* 程序資訊::                    附加的程序資訊 
* 執行緒::                        除錯帶多執行緒的程式 
* 多程序::                   除錯帶多程序的程式 
為除錯準備帶除錯資訊的程式碼 
=========================== 
   為了高效的除錯一個程式,你需要使用編譯器來產生附帶除錯資訊的可執行程式碼 
這些除錯資訊儲存在目標檔案中;描述了變數資料型別和函式宣告,在原檔案程式碼行 
和執行程式碼之間建立聯絡。 
   為產生除錯資訊,當你使用編譯器時指定'-g'選項,就可以為你的程式產生帶有 
除錯資訊的可執行程式碼。 
   有些c編譯器不支援'-g'選項和'-O'選項,那你就有麻煩了,或者有別的方法產生 
帶除錯資訊的可執行程式碼,要不就沒辦法了。 
   gcc,GNU的c語言編譯器支援'-g'和'-O'選項。這樣你就可以產生帶除錯資訊的且 
優化過的可執行程式碼. 
   當你使用gdb來除錯一個使用'-g','-O'選項產生的程式時,千萬記住編譯器為了優 
化你的程式重新安排了你的程式。不要為執行次序與你原來設想的不同,最簡單的例子 
就是當你定義了一個變數但從未使用過它時,gdb中是看不到這個變數的--因為它已經 
被優化掉了。 
   所以有時你不要使用'-O'選項,如果當你不用優化時產生的程式是正確的,而優化 
過後變的不正確了,那麼這是編譯器的bug你可以向開發者提供bug-reports(包括出錯 
的例子)。 
   早期的GUN C語言編譯器允許'-gg'選項,也用來產生除錯資訊,gdb不再支援這種格 
式的除錯資訊,如果你的編譯器支援'-gg'選項,請不要使用它。 

開執行你的程式 
===================== 
 
`run' 
`r' 
     使用'run'命令在gdb下啟動你的程式。你必須先指定你程式的名字(用gdb的命令列 
引數)或使用'file'命令,來指定檔名。如果你在一個支援多程序的環境下執行你的程 
序'run'命令建立一個子程序然後載入你的程式。如果環境不支援程序,則gdb直接調到 
程式的第一條命令。 
   一些父程序設定的參量可以決定程式的執行。gdb提供了指定參量的途徑,但你必須 
在程式執行前設定好他們。你也可以在執行過程中改變它們,但每次改變只有在下一次 
執行中才會體現出來。這些參量可以分為四類: 
---引數 
     你可以在使用'run'命令時設定,如果shell支援的話,你還可以使用萬用字元,或 
變數代換。在UNIX系統中你可以使用'shell環境變數'來控制shell。 
---環境: 
     你的程式一般直接從gdb那裡繼承環境變數。但是你可以使用'set environment' 
命令來設定專門的環境變數。 
---工作目錄 
     你的程式還同時從gdb那裡繼承了工作目錄,你可以使用'cd'命令在gdb中改變工作 
目錄。 
---標準輸入/輸出 
     你的程式一般使用與gdb所用的相似的裝置來輸入/輸出。不過你可以為你的程式的 
輸入/輸出進行重定向。使用'run'或'tty'命令來設置於gdb所用不同的裝置。 
*注意:當你使用輸入/輸出重定向時,你將不能使用無名管道來把你所除錯的程式的輸出 
傳給另一個程式。這樣gdb會認為除錯程式出錯。 
   當你發出'run'命令後,你的程式就開始執行。 
   如果你的符號檔案的時間與gdb上一次讀入的不同,gdb會廢棄原來的符號表並重新讀 
入。當前的斷點不變。 

程式環境 
========================== 
   "環境"包括了一系列的環境變數和它們的值。環境變數一般記錄了一些常用的資訊, 
比如你的使用者名稱,主目錄,你的終端型號和你的執行程式的搜尋路徑。一般你可以在shell 
下設定環境變數,然後這些變數被所有你所執行的程式所共享。在除錯中,可以設定恰當 
的環境變數而不用退出gdb. 
 
`path DIRECTORY' 
     在'PATH'環境變數前加入新的內容('PATH'提供了搜尋執行檔案的路徑)。對於gdb和 
你的程式來說你也許要設定一些專門的路徑。使用':'或空格來分隔。如果DIRECTORY已經 
在路徑中了,這個操作將會把它移到前面。 
     你可以使用串'$cmd'來代表當前路徑,如果你用'.'的話,它代表你使用'path'命令 
時的路徑,gdb將在把DIRECTORY加入搜尋路徑前用'.'代替當前路徑 
 
`show paths' 
     顯示當前路徑變數的設定情況。 
 
`show environment [VARNAME]' 
     顯示某個環境變數的值。如果你不指明變數名,則gdb會顯示所有的變數名和它們的 
內容。environment可以被縮寫成'env' 
 
`set environment VARNAME [=] VALUE' 
     設定某個環境變數的值。不過只對你所除錯的程式有效。對gdb本身是不起作用的。 
值可以是任何串。如果未指定值,則該變數值將被設為NULL. 
看一個例子: 
          set env USER = foo 
     告訴一個linux程式,當它下一次執行是使用者名稱將是'foo' 
 
`unset environment VARNAME' 
     刪除某環境變數。 
 
   注意:gdb使用'shell'環境變數所指定的shell來執行你的程式。 
 
 
工作路徑 
================================ 
   當你每次用'run'命令來執行你的程式時,你的程式將繼承gdb的 
當前工作目錄。而gdb的工作目錄是從它的父程序繼承而來的(一般是 
shell)。但你可以自己使用'cd'命令指定工作目錄。 
   gdb的工作目錄就是它去尋找某些檔案或資訊的途徑。 
`cd DIRECTORY' 
     把gdb的工作目錄設為DIRECTORY 
`pwd' 
     列印輸出當前目錄。 
你程式的輸入/輸出 
=============================== 
   預設時,你的程式的輸入/輸出和gdb的輸入/輸出使用同一個終端。 
gdb在它自己和你的程式之間切換來和你互動,但這會引起混亂。 
`info terminal' 
     顯示你當前所使用的終端的型別資訊。 
     你可以把你程式的輸入/輸出重定向。 
例如: 
     run > outfile 
執行你的程式並把你程式的標準輸出寫入檔案outfile中。 
   另一個為你程式指定輸入/輸出的方法是使用'tty'命令,這個命令 
接受一個檔名作為參量把這個檔案作為以後使用'run'命令的預設命 
令檔案。它還重新為子程序設定控制終端。 
例如: 
     tty /dev/ttyb 
指定以後用'run'命令啟動的程序使用終端'/dev/ttyb'作為程式的輸入 
/輸出,而且把這個終端設為你程序的控制終端。 
   一個清楚的使用'run'命令的重定向將重新設定'tty'所設定的內容 
,但不影響控制終端。   當你使用'tty'命令或在'run'命令中對輸入 
/輸出進行重定向時,只有你當前除錯的程式的輸入/輸出被改變了, 
並不會影響到別的程式。 
除錯一個已經執行的程式: 
==================================== 
 
`attach PROCESS-ID' 
     這個命令把一個已經執行的程序(在gdb外啟動)連線入gdb,以便 
除錯。PROCESS-ID是程序號。(UNIX中使用'ps'或'jobs -l'來檢視程序) 
     'attach'一般不重複。(當你打了一個以上的回車時) 
   當然要使用'attach'命令的話,你的作業系統環境必須支援程序。 
另外你還要有向此程序發訊號的權力。 
   當使用'attach'命令時,你應該先使用'file'命令來指定程序所 
聯絡的程式原始碼和符號表。   當gdb接到'attach'命令後第一件 
事就是停止程序的執行,你可以使用所有gdb的命令來除錯一個"連線" 
的程序,就象你用'run'命令在gdb中啟動它一樣。如果你要程序繼續運 
行,使用'continue'或'c'命令就行了。 
`detach' 
   當你結束除錯後可以使用此命令來斷開程序和gdb的連線。(解除gdb 
對它的控制)在這個命令執行後進程將繼續執行。 
   如果你在用'attach'連線一個程序後退出了gdb,或使用'run'命令執 
行了另一個程序,這個被'attach'的程序將被kill掉。但預設時,gdb會 
要求你確認你是否要退出或執行一個新的程序。 

結束子程序 
========================= 
`kill' 
     Kill命令結束你程式在gdb下開的子程序 
     這個命令當你想要除錯(檢查)一個core dump檔案時更有用。gdb在除錯過程中 
會忽略所有的core dump。 
   在一些作業系統上,一個程式當你在上面加了斷點以後就不能離開gdb獨立執行。 
你可以用kill命令來解決這個問題。 
   'kill'命令當你想重新編譯和連線你的程式時也很有用。因為有些系統不允許修改 
正在執行的可執行程式。這樣當你再一次使用'run'命令時gdb會知道你的程式已經被改 
變了,那麼gdb會重新load新的符號。(而且儘量保持你當前的斷點設定。 
附加的程序資訊 
============================== 
   一些作業系統提供了一個裝置目錄叫做'/proc'的,供檢查程序映象。如果gdb被在這 
樣的作業系統下執行,你可以使用命令'info proc'來查詢程序的資訊。('info proc'命 
令只在支援'procfs'的SVR4系統上有用。 
`info proc' 
     顯示程序的概要資訊。 
`info proc mappings' 
     報告你程序所能訪問的地址範圍。 
`info proc times' 
     你程序和子程序的開始時間,使用者時間(user CPU time),和系統CPU時間。 
`info proc id' 
     報告有關程序id的資訊。 
`info proc status' 
     報告你程序的一般狀態資訊。如果程序停止了。這個報告還包括停止的原因和收到的 
訊號。 
`info proc all' 
     顯示上面這些命令返回的所有資訊。 
對多執行緒程式的除錯 
======================================== 
   一些作業系統中,一個單獨的程式可以有一個以上的執行緒在執行。執行緒和程序精確的定?nbsp;
?nbsp;
 
?nbsp;
?nbsp;
有自己的暫存器,執行時堆疊或許還會有私有記憶體。 
   gdb提供了以下供除錯多執行緒的程序的功能: 
   * 自動通告新執行緒。 
   * 'thread THREADNO',一個用來線上程之間切換的命令。 
   * 'info threads',一個用來查詢現存執行緒的命令。 
   * 'thread apply [THREADNO] [ALL] ARGS',一個用來向執行緒提供命令的命令。 
   * 執行緒有關的斷點設定。 
   注意:這些特性不是在所有gdb版本都能使用,歸根結底要看作業系統是否支援。 
   如果你的gdb不支援這些命令,會顯示出錯資訊: 
          (gdb) info threads 
          (gdb) thread 1 
          Thread ID 1 not known.  Use the "info threads" command to 
          see the IDs of currently known threads. 
   gdb的執行緒級除錯功能允許你觀察你程式執行中所有的執行緒,但無論什麼時候 
gdb控制,總有一個"當前"執行緒。除錯命令對"當前"程序起作用。 
   一旦gdb發現了你程式中的一個新的執行緒,它會自動顯示有關此執行緒的系統信 
息。比如: 
     [New process 35 thread 27] 
不過格式和作業系統有關。 
   為了除錯的目的,gdb自己設定執行緒號。 
`info threads' 
     顯示程序中所有的執行緒的概要資訊。gdb按順序顯示: 
       1.執行緒號(gdb設定) 
       2.目標系統的執行緒標識。 
       3.此執行緒的當前堆疊。 
       一前面打'*'的執行緒表示是當前執行緒。 
     例如: 
     (gdb) info threads 
       3 process 35 thread 27  0x34e5 in sigpause () 
       2 process 35 thread 23  0x34e5 in sigpause () 
     * 1 process 35 thread 13  main (argc=1, argv=0x7ffffff8) 
         at threadtest.c:68 
`thread THREADNO' 
     把執行緒號為THREADNO的執行緒設為當前執行緒。命令列引數THREADNO是gdb內定的 
執行緒號。你可以用'info threads'命令來檢視gdb內設定的執行緒號。gdb顯示該執行緒 
的系統定義的標識號和執行緒對應的堆疊。比如: 
 
          (gdb) thread 2 
          [Switching to process 35 thread 23] 
          0x34e5 in sigpause () 
     "Switching後的內容取決於你的作業系統對執行緒標識的定義。 
 
`thread apply [THREADNO] [ALL]  ARGS' 
     此命令讓你對一個以上的執行緒發出相同的命令"ARGS",[THREADNO]的含義同上。 
如果你要向你程序中的所有的執行緒發出命令使用[ALL]選項。 
   無論gdb何時中斷了你的程式(因為一個斷點或是一個訊號),它自動選擇訊號或 
斷點發生的執行緒為當前執行緒。gdb將用一個格式為'[Switching to SYSTAG]'的訊息 
來向你報告。 
   *參見:執行和停止多執行緒程式。 
   *參見:設定觀察點 
 
除錯多程序的程式 
========================================== 
   gdb對除錯使用'fork'系統呼叫產生新程序的程式沒有很多支援。當一個程式開始 
一個新程序時,gdb將繼續對父程序進行除錯,子程序將不受影響的執行。如果你在子 
程序可能會執行到的地方設了斷點,那麼子程序將收到'SIGTRAP'訊號,如果子程序沒 
有對這個訊號進行處理的話那麼預設的處理就是使子程序終止。 
   然而,如果你要一定要除錯子程序的話,這兒有一個不是很麻煩的折衷的辦法。在 
子程序被執行起來的開頭幾句語句前加上一個'sleep'命令。這在除錯過程中並不會引 
起程式中很大的麻煩(不過你要自己注意例外的情況么:-))。然後再使用'ps'命令列出 
新開的子程序號,最後使用'attach'命令。這樣就沒有問題了。 
  關於這一段,本人覺得實際使用上並不全是這樣。我在除錯程中就試過,好象不一定 
能起作用,要看gdb的版本和你所使用的作業系統了。 
停止和繼續 
*********************** 
   偵錯程式的基本功能就是讓你能夠在程式執行時在終止之前在某些條件下停止下來,然 
後再繼續執行,這樣的話你就可以檢查當你的程式出錯時你的程式究竟做了些什麼。 
   在gdb內部,你的程式會由於各種原因而暫時停止,比如一個訊號,一個斷點,或是 
由於你用了'step'命令。在程式停止的時候你就可以檢查和改變變數的值,設定或去掉 
斷點,然後繼續你程式的執行。一般當程式停下來時gdb都會顯示一些有關程式狀態的信 
息。比如象程式停止的原因,堆疊等等。如果你要了解更詳細的資訊,你可以使用'info 
program'命令。另外,在任何時候你輸入這條命令,gdb都會顯示當前程式執行的狀態信 
息。 
 
`info program' 
     顯示有關你程式狀態的資訊:你的程式是在執行還是停止,是什麼程序,為什麼停 
止。 
 
斷點,觀察點和異常 
======================================== 
   斷點的作用是當你程式執行到斷點時,無論它在做什麼都會被停止下來。對於每個斷點 
你都可以設定一些更高階的資訊以決定斷點在什麼時候起作用。你可以使用'break'命令 
來在你的程式中設定斷點,在前面的例子中我們已經提到過一些這個命令的使用方法了。 
你可以在行上,函式上,甚至在確切的地址上設定斷點。在含有異常處理的語言(比如象 
c++)中,你還可以在異常發生的地方設定斷點。 
   在SunOS 4.x,SVR4和Alpha OSF/1的設定中,你還可以在共享庫中設定斷點。 
   觀察點是一種特殊的斷點。它們在你程式中某個表示式的值發生變化時起作用。你必 
須使用另外一些命令來設定觀察點。除了這個特性以外,你可以象對普通斷點一樣對觀察 
點進行操作--使用和普通斷點操作一樣的命令來對觀察點使能,使不能,刪除。 
   你可以安排當你程式被中斷時顯示的程式變數。 
   當你在程式中設定斷點或觀察點時gdb為每個斷點或觀察點賦一個數值.在許多對斷點 
操作的命令中都要使用這個數值。 

設定斷點 
============= 
   使用'break'或簡寫成'b'來設定斷點。gdb使用環境變數$bpnum來記錄你最新設定的 
斷點。 
   你有不少方法來設定斷點。 
 
 
`break FUNCTION' 
     此命令用來在某個函式上設定斷點。當你使用允許函式過載的語言比如C++時,有可 
能同時在幾個過載的函式上設定了斷點。 
 
`break +OFFSET' 
`break -OFFSET' 
     在當前程式執行到的前幾行或後幾行設定斷點。OFFSET為行號。 
 
`break LINENUM' 
     在行號為LINENUM的行上設定斷點。程式在執行到此行之前停止。 
 
`break FILENAME:LINENUM' 
     在檔名為FILENAME的原檔案的第LINENUM行設定斷點。 
 
`break FILENAME:FUNCTION' 
     在檔名為FILENAME的原檔案的名為FUNCTION的函式上設定斷點。 
當你的多個檔案中可能含有相同的函式名時必須給出檔名。 
 
`break *ADDRESS' 
     在地址ADDRESS上設定斷點,這個命令允許你在沒有除錯資訊的程 
序中設定斷點。 
`break' 
     當'break'命令不包含任何引數時,'break'命令在當前執行到的程 
序執行棧中的下一條指令上設定一個斷點。除了棧底以外,這個命令使 
程式在一旦從當前函式返回時停止。相似的命令是'finish',但'finish' 
並不設定斷點。這一點在迴圈語句中很有用。 
     gdb在恢復執行時,至少執行一條指令。 
 
`break ... if COND' 
     這個命令設定一個條件斷點,條件由COND指定;在gdb每次執行到此 
斷點時COND都被計算當COND的值為非零時,程式在斷點處停止。這意味著 
COND的值為真時程式停止。...可以為下面所說的一些參量。 
 
`tbreak ARGS' 
     設定斷點為只有效一次。ARGS的使用同'break'中的參量的使用。 
 
`hbreak ARGS' 
     設定一個由硬體支援的斷點。ARGS同'break'命令,設定方法也和 
'break'相同。但這種斷點需要由硬體支援,所以不是所有的系統上這個 
命令都有效。這個命令的主要目的是用於對EPROM/ROM程式的除錯。因為 
這條命令可以在不改變程式碼的情況下設定斷點。這可以同SPARCLite DSU 
一起使用。當程式訪問某些變數和程式碼時,DSU將設定"陷井"。注意: 
你只能一次使用一個斷點,在新設定斷點時,先刪除原斷點。 
`thbreak ARGS' 
     設定只有一次作用的硬體支援斷點。ARGS用法同'hbreak'命令。這個命令 
和'tbreak'命令相似,它所設定的斷點只起一次作用,然後就被自動的刪除。這 
個命令所設定的斷點需要有硬體支援。 
 
`rbreak REGEX' 
     在所有滿足表示式REGEX的函式上設定斷點。這個命令在所有相匹配的函式 
上設定無條件斷點,當這個命令完成時顯示所有被設定的斷點資訊。這個命令設 
置的斷點和'break'命令設定的沒有什麼不同。這樣你可以象操作一般的斷點一 
樣對這個命令設定的斷點進行刪除,使能,使不能等操作。當除錯C++程式時這 
個命令在過載函式上設定斷點時非常有用。 
 
`info breakpoints [N]' 
`info break [N]' 
`info watchpoints [N]' 
     顯示所有的斷點和觀察點的設定表,有下列一些列 
 
    *Breakpoint Numbers*----斷點號 
    *Type*----斷點型別(斷點或是觀察點) 
    *Disposition*---顯示斷點的狀態。 
 
    *Enabled or Disabled*---使能或不使能。'y'表示使能,'n'表示不使能。 
 
    *Address*----地址,斷點在你程式中的地址(記憶體地址) 
    *What*---地址,斷點在你程式中的行號。 
     如果斷點是條件斷點,此命令還顯示斷點所需要的條件。 
     帶引數N的'info break'命令只顯示由N指定的斷點的資訊。 
     此命令還顯示斷點的執行資訊(被執行過幾次),這個功能在使用'ignore' 
命令時很有用。你可以'ignore'一個斷點許多次。使用這個命令可以檢視斷點 
被執行了多少次。這樣可以更快的找到錯誤。 
    gdb允許你在一個地方設定多個斷點。但設定相同的斷點無疑是弱智的。不過 
你可以使用條件斷點,這樣就非常有用。 
   gdb有時會自動在你的程式中加入斷點。這主要是gdb自己的需要。比如為了正 
確的處理C語言中的'longjmp'。這些內部斷點都是負值,以'-1'開始。'info 
breakpoints'不會顯示它們。 
   不過你可以使用命令'maint info breakpoints'來檢視這些斷點。 
 
`maint info breakpoints' 
     使用格式和'info breakpoints'相同,顯示所有的斷點,無論是你設定的還是 
gdb自動設定的。 
     以下列的含義: 
 
    `breakpoint' 
          斷點,普通斷點。 
    `watchpoint' 
          普通觀察點。 
 
    `longjmp' 
          內部斷點,用於處理'longjmp'呼叫。 
 
    `longjmp resume' 
          內部斷點,設定在'longjmp'呼叫的目標上。 
 
    `until' 
          'until'命令所使用的內部斷點。 
 
    `finish' 
          'finish'命令所使用的內部斷點。 
設定觀察點 
============== 
   你可以使用觀察點來停止一個程式,當某個表示式的值改變時,觀察點會將程式 
停止。而不需要先指定在某個地方設定一個斷點。 
   由於觀察點的這個特性,使觀察點的使用時開銷比較大,但在捕捉錯誤時非常有 
用。特別是你不知道你的程式什麼地方出了問題時。 
 
`watch EXPR' 
     這個命令使用EXPR作為表示式設定一個觀察點。GDB將把表示式加入到程式中 
並監視程式的執行,當表示式的值被改變時GDB就使程式停止。這個也可以被用在 
SPARClite DSU提供的新的自陷工具中。當程式存取某個地址或某條指令時(這個地 
址在除錯暫存器中指定),DSU將產生自陷。對於資料地址DSU支援'watch'命令,然而 
硬體斷點暫存器只能儲存兩個斷點地址,而且斷點的型別必須相同。就是兩個 
'rwatch'型斷點,或是兩個'awatch'型斷點。 
 
`rwatch EXPR' 
     設定一個觀察點,當EXPR被程式讀時,程式被暫停。 
 
`awatch EXPR' 
     設定一個觀察點,當EXPR被讀出然後被寫入時程式被暫停。這個命令和'awatch' 
命令合用。 
 
`info watchpoints' 
     顯示所設定的觀察點的列表,和'info break'命令相似。 
     *注意:*在多執行緒的程式中,觀察點的作用很有限,GDB只能觀察在一個執行緒中 
的表示式的值如果你確信表示式只被當前執行緒所存取,那麼使用觀察點才有效。GDB 
不能注意一個非當前執行緒對錶達式值的改變。 
 
斷點和異常 
============== 
   在一些語言中比如象GNU C++,實現了異常處理。你可以使用GDB來檢查異常發生的 
原因。而且GDB還可以列出在某個點上異常處理的所有過程。 
 
`catch EXCEPTIONS' 
     你可以使用這個命令來在一個被啟用的異常處理控制代碼中設定斷點。EXCEPTIONS是 
一個你要抓住的異常。 
     你一樣可以使用'info catch'命令來列出活躍的異常處理控制代碼。 
     現在GDB中對於異常處理由以下情況不能處理。 
   * 如果你使用一個互動的函式,當函式執行結束時,GDB將象普通情況一樣把控制返 
回給你。如果在呼叫中發生了異常,這個函式將繼續執行直到遇到一個斷點,一個訊號 
或是退出執行。 
   * 你不能手工產生一個異常( 即異常只能由程式執行中產生 ) 
   * 你不能手工設定一個異常處理控制代碼。 
   有時'catch'命令不一定是除錯異常處理的最好的方法。如果你需要知道異常產生的 
確切位置,最好在異常處理控制代碼被呼叫以前設定一個斷點,這樣你可以檢查棧的內容。 
如果你在一個異常處理控制代碼上設定斷點,那麼你就不容易知道異常發生的位置和原因。 
   要僅僅只在異常處理控制代碼被喚醒之前設定斷點,你必須瞭解一些語言的實現細節。 
比如在GNU C++中異常被一個叫'__raise_exception'的庫函式所呼叫。這個函式的原 
型是: 
 
         /* ADDR is where the exception identifier is stored. 
            ID is the exception identifier.  */ 
         void __raise_exception (void **ADDR, void *ID); 
要使GDB在棧展開之前抓住所有的控制代碼,你可以在函式'__raise_exception'上設定斷點。 
   對於一個條件斷點,由於它取決於ID的值,你可以在你程式中設定斷點,當某個特 
別的異常被喚醒。當有一系列異常被喚醒時,你可以使用多重條件斷點來停止你的程式。

斷點條件 
=========== 
   最簡單的斷點就是當你的程式每次執行到的時候就簡單將程式掛起。你也可以為斷點 
設定"條件"。條件只是你所使用的程式語言的一個布林表示式,帶有條件表示式的斷點 
在每次執行時判斷計算表示式的值,當表示式值為真時才掛起程式。 
   這是使用"斷言"的一中形式,在這種形式中你只有在斷言為真時才掛起程式。如果 
在C語言中你要使斷言為假時掛起程式則使用:"!表示式"。 
   條件表示式對觀察點也同樣有效,但你並不需要它,因為觀察點本身就計算一個表示式?nbsp;
?nbsp;
但它也許會簡單一些。比如只在一個變數名上設定觀察點然後設定一個條件來測試新的賦 
值。 
  斷點條件可能有副作用(side effects)會影響程式的執行。這一點有時也是很有用的 
比如來啟用一個顯示程式完成情況的的函式,或使用你自己的列印函式來格式化特殊的 
資料結構。當在同一位置沒有另一個斷點設定時,結果是可預見的。(在gdb中如果在同一 
個地方使用了一個斷點和一個條件斷點則普通斷點可能先被啟用。)在條件斷點的應用上 
有很多技巧。 
   斷點條件可以在設定斷點的同時被設定。使用'if'命令作為'break'命令的引數。斷點 
條件也可以在任何時候使用'condition'命令來設定。'watch'命令不能以'if'作為引數 
 
所以使用'condition'命令是在觀察點上設定條件的唯一方法。 
 
`condition BNUM EXPRESSION' 
     把'EXPRESSIN'作為斷點條件。斷點用'BNUM'來指定。在你為BNUM號斷點設定了條件 
後,只有在條件為真時程式才被暫停。當你使用'condition'命令GDB馬上同步的檢查 
'EXPRESSION'的值判斷表示式中的符號在斷點處是否有效,但GDB並不真正計算表示式 
的值。 
 
`condition BNUM' 
     刪除在'BNUM'號斷點處的條件。使之成為一個普通斷點。 
   一個條件斷點的特殊例子是時一個程式在執行了某句語句若干次後停止。由於這 
個功能非常常用,你可以使用一個命令來直接設定它那就是'ignore count'。每個 
斷點都有'ignore count',預設是零。如果'ignore count'是正的那麼你的程式在 
執行過斷點處'count'次後被暫停。 
 
`ignore BNUM COUNT' 
     設定第BNUM號斷點的'ignore count'為'COUNT'。 
     如果要讓斷點在下次執行到時就暫停程式,那麼把'COUNT'設為0. 
     當你使用'continue'命令來繼續你程式的執行時,你可以直接把'ignore count' 
作為'continue'的引數使用。你只要直接在'continue'命令後直接跟要"ignore"的 
次數就行。 
     如果一個斷點同時有一個ignore count和一個條件時,條件不被檢查。只有當 
'ignore count'為零時GDB才開始檢查條件的真假。 
     另外你可以用'condition'命令來獲得與用‘ignore count'同樣效果的斷點。用法 
是用類似於'$foo--<=0'的參量作為'condition'命令的引數(使用一個不停減量的變數 
作為條件表示式的成員)。 
 斷點命令列表 
================== 
   你可以為任一個斷點或觀察點指定一系列命令,當你程式執行到斷點時,GDB自動執行 
這些命令。例如:你可以列印一些表示式的值,或使能其他的斷點。 
 
`commands [BNUM]' 
`... COMMAND-LIST ...' 
`end' 
     為斷點號為BNUM的斷點設定一個命令列表。這些命令在'...COMMAND-LIST...'中列 
出使用'end'命令來表示列表的結束。 
    要刪除斷點上設定的命令序列,你只需在'command'命令後直接跟'end'命令就可以 
了。 
    當不指定BNUM時,GDB預設為最近遇到的斷點或是觀察點設定命令列表。 
    使用回車來表示重複使用命令的特性在'...command list...'中不能使用。 
    你可以使用命令列表中的命令來再次使你的程式進入執行狀態。簡單的在命令列表 
中使用'continue'命令,或'step'命令。 
    在使程式恢復執行的命令後的命令都被忽略。這是因為一旦你的程式重新執行就可 
能遇到新的命令列表,那麼就應該執行新的命令。防止了二義。 
    如果你在命令列表中使用了'silent'命令,那麼你程式在斷點處停止的資訊將不被 
顯示。這對於用一個斷點然後顯示一些資訊,接著再繼續執行很有用。但'silent'命令 
只有在命令列表的開頭有效。 
    命令'echo','output'和'printf'允許你精確的控制顯示資訊,這些命令在"silent" 
斷點中很有用。 
   例如:這個例子演示了使用斷點命令列表來列印'x'的值. 
 
     break foo if x>0 
     commands 
     silent 
     printf "x is %d\n",x 
     cont 
     end 
   斷點命令列表的一個應用是在遇到一個buf之後改正資料然後繼續除錯的過程。 
使用命令來修改含有錯誤值的變數,然後使用'continue'命令繼續程式的執行。 
  使用'silent'命令遮蔽輸出: 
 
     break 403 
     commands 
     silent 
     set x = y + 4 
     cont 
     end 
斷點選單 
============== 
   一些程式語言(比如象C++)允許一個函式名被多次使用(過載),以方便應用的使用。 
當一個函式名被過載時,'break FUNCITON'命令向GDB提供的資訊不夠GDB瞭解你要設定 
斷點的確切位置。如果你瞭解到這個問題,你可以使用'break FUNCITONS(TYPES)'命令 
來指定斷點的確切位置。否則GDB會提供一個函式的選擇的選單供你選擇。使用提示符 
'>'來等待你的輸入。開始的兩個選擇一般是'[0] cancel'和'[1] all'輸入1則在所有 
同名函式上加入斷點。輸入0則退出選擇。 
   下例為企圖在過載的函式符號'String::after'上設定斷點。 
     (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)