gdb除錯命令

劍西樓發表於2017-02-08


  本文主要參考自:http://www.cnblogs.com/zzx1045917067/archive/2012/12/26/2834310.html,進行了一點補充和編排;Core dump部分參考了:http://blog.ddup.us/?p=176

  gdb是一個在UNIX環境下的命令列除錯工具。

  如果需要使用gdb除錯程式,請在gcc時加上-g選項。

  下面的命令部分是簡化版,比如使用l代替list等等。

 

1.基本命令

1)進入GDB  #gdb test

  test是要除錯的程式,由gcc test.c -g -o test生成。進入後提示符變為(gdb) 。

2)檢視原始碼  (gdb) l

  原始碼會進行行號提示。

  如果需要檢視在其他檔案中定義的函式,在l後加上函式名即可定位到這個函式的定義及檢視附近的其他原始碼。或者:使用斷點或單步執行,到某個函式處使用s進入這個函式。

3)設定斷點  (gdb) b 6

  這樣會在執行到原始碼第6行時停止,可以檢視變數的值、堆疊情況等;這個行號是gdb的行號。

 4)檢視斷點處情況  (gdb) info b

  可以鍵入"info b"來檢視斷點處情況,可以設定多個斷點;

5)執行程式碼  (gdb) r

6)顯示變數值  (gdb) p n

  在程式暫停時,鍵入"p 變數名"(print)即可;

  GDB在顯示變數值時都會在對應值之前加上"$N"標記,它是當前變數值的引用標記,以後若想再次引用此變數,就可以直接寫作"$N",而無需寫冗長的變數名;

7)觀察變數  (gdb) watch n

 在某一迴圈處,往往希望能夠觀察一個變數的變化情況,這時就可以鍵入命令"watch"來觀察變數的變化情況,GDB在"n"設定了觀察點;

8)單步執行  (gdb) n

9)程式繼續執行  (gdb) c

  使程式繼續往下執行,直到再次遇到斷點或程式結束;

10)退出GDB  (gdb) q

 

2.斷點除錯

命令格式                        例子                   作用

break + 設定斷點的行號  break n      在n行處設定斷點

tbreak + 行號或函式名  tbreak n/func    設定臨時斷點,到達後被自動刪除

break + filename + 行號  break main.c:10  用於在指定檔案對應行設定斷點

break + <0x...>  break 0x3400a      用於在記憶體某一位置處暫停 

break + 行號 + if + 條件  break 10 if i==3   用於設定條件斷點,在迴圈中使用非常方便 

info breakpoints/watchpoints [n]  info break  n表示斷點號,檢視斷點/觀察點的情況 

clear + 要清除的斷點行號  clear 10    用於清除對應行的斷點,要給出斷點的行號,清除時GDB會給出提示

delete + 要清除的斷點編號  delete 3    用於清除斷點和自動顯示的表示式的命令,要給出斷點的編號,清除時GDB不會給出任何提示

disable/enable + 斷點編號  disable 3    讓所設斷點暫時失效/使能,如果要讓多個編號處的斷點失效/使能,可將編號之間用空格隔開

awatch/watch + 變數  awatch/watch i    設定一個觀察點,當變數被讀出或寫入時程式被暫停 

rwatch + 變數      rwatch i        設定一個觀察點,當變數被讀出時,程式被暫停 

catch                  設定捕捉點來補捉程式執行時的一些事件。如:載入共享庫(動態連結庫)或是C++的異常 

tcatch                  只設定一次捕捉點,當程式停住以後,應點被自動刪除

 

3.資料命令

display +表示式  display a  用於顯示錶達式的值,每當程式執行到斷點處都會顯示錶達式的值 

info display      用於顯示當前所有要顯示值的表示式的情況 

delete + display 編號  delete 3  用於刪除一個要顯示值的表示式,被刪除的表示式將不被顯示

disable/enable + display 編號  disable/enable 3  使一個要顯示值的表示式暫時失效/使能 

undisplay + display 編號  undisplay 3  用於結束某個表示式值的顯示

whatis + 變數  whatis i  顯示某個表示式的資料型別

print(p) + 變數/表示式  p n  用於列印變數或表示式的值

set + 變數 = 變數值  set i = 3  改變程式中某個變數的值

  在使用print命令時,可以對變數按指定格式進行輸出,其命令格式為print /變數名 + 格式

  其中常用的變數格式:x:十六進位制;d:十進位制;u:無符號數;o:八進位制;c:字元格式;f:浮點數。

 

 

4.除錯執行環境相關命令

set args  set args arg1 arg2  設定執行引數

show args  show args  參看執行引數

set width + 數目  set width 70  設定GDB的行寬

cd + 工作目錄  cd ../  切換工作目錄

run  r/run  程式開始執行

step(s)  s  進入式(會進入到所呼叫的子函式中)單步執行,進入函式的前提是,此函式被編譯有debug資訊

next(n)  n  非進入式(不會進入到所呼叫的子函式中)單步執行

finish  finish  一直執行到函式返回並列印函式返回時的堆疊地址和返回值及引數值等資訊

until + 行數  u 3  執行到函式某一行 

continue(c)  c  執行到下一個斷點或程式結束 

return <返回值>  return 5  改變程式流程,直接結束當前函式,並將指定值返回

call + 函式  call func  在當前位置執行所要執行的函式

 

5.堆疊相關命令

backtrace/bt  bt  用來列印棧幀指標,也可以在該命令後加上要列印的棧幀指標的個數,檢視程式執行到此時,是經過哪些函式呼叫的程式,程式“呼叫堆疊”是當前函式之前的所有已呼叫函式的列表(包括當前函式)。每個函式及其變數都被分配了一個“幀”,最近呼叫的函式在 0 號幀中(“底部”幀)

frame  frame 1  用於列印指定棧幀

info reg  info reg  檢視暫存器使用情況

info stack  info stack  檢視堆疊使用情況

up/down  up/down  跳到上一層/下一層函式

 

6.跳轉執行

jump  指定下一條語句的執行點。可以是檔案的行號,可以是file:line格式,可以是+num這種偏移量格式。表式著下一條執行語句從哪裡開始。相當於改變了PC暫存器內容,堆疊內容並沒有改變,跨函式跳轉容易發生錯誤。

 

7.訊號命令

signal   signal SIGXXX   產生XXX訊號,如SIGINT。一種速查Linux查詢訊號的方法:# kill -l

handle   在GDB中定義一個訊號處理。訊號可以以SIG開頭或不以SIG開頭,可以用定義一個要處理訊號的範圍(如:SIGIO-SIGKILL,表示處理從SIGIO訊號到SIGKILL的訊號,其中包括SIGIO,SIGIOT,SIGKILL三個訊號),也可以使用關鍵字all來標明要處理所有的訊號。一旦被除錯的程式接收到訊號,執行程式馬上會被GDB停住,以供除錯。其可以是以下幾種關鍵字的一個或多個:
  nostop/stop
    當被除錯的程式收到訊號時,GDB不會停住程式的執行,但會打出訊息告訴你收到這種訊號/GDB會停住你的程式  
  print/noprint
    當被除錯的程式收到訊號時,GDB會顯示出一條資訊/GDB不會告訴你收到訊號的資訊 
  pass 
  noignore 
    當被除錯的程式收到訊號時,GDB不處理訊號。這表示,GDB會把這個訊號交給被除錯程式會處理。 
  nopass 
  ignore 
    當被除錯的程式收到訊號時,GDB不會讓被除錯程式來處理這個訊號。 
  info signals 
  info handle 
    可以檢視哪些訊號被GDB處理,並且可以看到預設的處理方式

  single命令和shell的kill命令不同,系統的kill命令發訊號給被除錯程式時,是由GDB截獲的,而single命令所發出一訊號則是直接發給被除錯程式的。

 

8.執行Shell命令

  如(gdb)shell ls來執行ls。  

 

9.更多程式執行選項和除錯

1、程式執行引數。 
  set args 可指定執行時引數。(如:set args 10 20 30 40 50) 
  show args 命令可以檢視設定好的執行引數。 
2、執行環境。 
  path 可設定程式的執行路徑。 
  show paths 檢視程式的執行路徑。

  set environment varname [=value] 設定環境變數。如:set env USER=hchen 

  show environment [varname] 檢視環境變數。 

3、工作目錄。

  cd    相當於shell的cd命令。 

  pwd  顯示當前的所在目錄。 
4、程式的輸入輸出。 
  info terminal 顯示你程式用到的終端的模式。 
  使用重定向控制程式輸出。如:run > outfile 
  tty命令可以指寫輸入輸出的終端裝置。如:tty /dev/ttyb

5、除錯已執行的程式

兩種方法: 
  (1)在UNIX下用ps檢視正在執行的程式的PID(程式ID),然後用gdb PID格式掛接正在執行的程式。 
  (2)先用gdb 關聯上原始碼,並進行gdb,在gdb中用attach命令來掛接程式的PID。並用detach來取消掛接的程式。

6、暫停 / 恢復程式執行  當程式被gdb停住時,你可以使用info program 來檢視程式的是否在執行,程式號,被暫停的原因。 在gdb中,我們可以有以下幾種暫停方式:斷點(BreakPoint)、觀察點(WatchPoint)、捕捉點(CatchPoint)、訊號(Signals)、執行緒停止(Thread Stops),如果要恢復程式執行,可以使用c或是continue命令。

7、執行緒(Thread Stops)

如果程式是多執行緒,可以定義斷點是否在所有的執行緒上,或是在某個特定的執行緒。 
  break thread
  break thread if ... 
  linespec指定了斷點設定在的源程式的行號。threadno指定了執行緒的ID,注意,這個ID是GDB分配的,可以通過“info threads”命令來檢視正在執行程式中的執行緒資訊。如果不指定thread 則表示斷點設在所有執行緒上面。還可以為某執行緒指定斷點條件。如: 
  (gdb) break frik.c:13 thread 28 if bartab > lim 
當你的程式被GDB停住時,所有的執行執行緒都會被停住。這方便檢視執行程式的總體情況。而在你恢復程式執行時,所有的執行緒也會被恢復執行。

 

10.除錯core檔案

Core Dump:Core的意思是記憶體,Dump的意思是扔出來,堆出來。開發和使用Unix程式時,有時程式莫名其妙的down了,卻沒有任何的提示(有時候會提示core dumped),這時候可以檢視一下有沒有形如core.程式號的檔案生成,這個檔案便是作業系統把程式down掉時的記憶體內容扔出來生成的, 它可以做為除錯程式的參考

(1)生成Core檔案

  一般預設情況下,core file的大小被設定為了0,這樣系統就不dump出core file了。修改後才能生成core檔案。

  #設定core大小為無限
  ulimit -c unlimited
  #設定檔案大小為無限
  ulimit unlimited

  這些需要有root許可權, 在ubuntu下每次重新開啟中斷都需要重新輸入上面的第一條命令, 來設定core大小為無限

core檔案生成路徑:輸入可執行檔案執行命令的同一路徑下。若系統生成的core檔案不帶其他任何副檔名稱,則全部命名為core。新的core檔案生成將覆蓋原來的core檔案。

1)/proc/sys/kernel/core_uses_pid可以控制core檔案的檔名中是否新增pid作為擴充套件。檔案內容為1,表示新增pid作為副檔名,生成的core檔案格式為core.xxxx;為0則表示生成的core檔案同一命名為core。
可通過以下命令修改此檔案:
echo "1" > /proc/sys/kernel/core_uses_pid

2)proc/sys/kernel/core_pattern可以控制core檔案儲存位置和檔名格式。
可通過以下命令修改此檔案:
echo "/corefile/core-%e-%p-%t" > core_pattern,可以將core檔案統一生成到/corefile目錄下,產生的檔名為core-命令名-pid-時間戳
以下是引數列表:
    %p - insert pid into filename 新增pid
    %u - insert current uid into filename 新增當前uid
    %g - insert current gid into filename 新增當前gid
    %s - insert signal that caused the coredump into the filename 新增導致產生core的訊號
    %t - insert UNIX time that the coredump occurred into filename 新增core檔案生成時的unix時間
    %h - insert hostname where the coredump happened into filename 新增主機名
    %e - insert coredumping executable name into filename 新增命令名

(2)用gdb檢視core檔案

  發生core dump之後, 用gdb進行檢視core檔案的內容, 以定位檔案中引發core dump的行.
  gdb [exec file] [core file]
  如:
  gdb ./test core

  或gdb ./a.out
   core-file core.xxxx
  gdb後, 用bt命令backtrace或where檢視程式執行到哪裡, 來定位core dump的檔案->行.

  待除錯的可執行檔案,在編譯的時候需要加-g,core檔案才能正常顯示出錯資訊

  1)gdb -core=core.xxxx
  file ./a.out
  bt
  2)gdb -c core.xxxx
  file ./a.out
  bt

(3)用gdb實時觀察某程式crash資訊

  啟動程式
  gdb -p PID
  c
  執行程式至crash
  gdb會顯示crash資訊
  bt


相關文章