GDB實用的調試工具

來源:互聯網
上載者:User

標籤:

GDB它是GNU Debuger縮寫,它是GNU發表了unix通過應用程式調試工具。

它被廣泛應用於在各種各種生產內部應用。GDB和所有的調試工具經常使用相同的,其主要特點是:監視變數的值、設定斷點及單步運行。


注意,在來源程式編譯時間。要使用gcc -g 或 cc -g 或 g++ -g將來源程式編譯成可運行檔案,然後才幹使用gdb進行調試。

僅僅有這樣,產生的可運行檔案才包括調試資訊。
參考別人的寫一個簡單的c程式,在linux下使用gcc編譯成可運行檔案,然後使用gdb進行調試。

程式源碼例如以下

#include <stdio.h>    int func(int n)  {          int sum=0,i;          for(i=0; i<n; i++)          {                  sum+=i;          }          return sum;  }    int main()  {          int i;          long result = 0;          for(i=1; i<=100; i++)          {                  result += i;          }           printf("result[1-100] = %d \n\r", result );         printf("result[1-250] = %d \n\r", func(250) );  }
使用gcc -g變成產生可運行檔案miki,方法為 gcc -g miki.c  -o miki
使用gdb開始調試miki應用。例如以下:

$gdb miki  GNU gdb (GDB) CentOS (7.0.1-42.el5.centos)  Copyright (C) 2009 Free Software Foundation, Inc.  License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>  This is free software: you are free to change and redistribute it.  There is NO WARRANTY, to the extent permitted by law.  Type "show copying"  and "show warranty" for details.  This GDB was configured as "x86_64-redhat-linux-gnu".  For bug reporting instructions, please see:  <http://www.gnu.org/software/gdb/bugs/>…  Reading symbols from /u01/home/oracle/miki…done.  (gdb) l 1  1       #include <stdio.h>  2  3       int func(int n)  4       {  5               int sum=0,i;  6               for(i=0; i<n; i++)  7               {  8                       sum+=i;  9               }  10              return sum;  (gdb)  11      }  12  13  14      main()  15      {  16              int i;  17              long result = 0;  18              for(i=1; i<=10; i++)  19              {  20                      result += i;  (gdb)  21              }  22  23             printf("result[1-10] = %d \n\r", result );  24             printf("result[1-5] = %d \n\r", func(5) );  25      }  (gdb)  Line number 26 out of range; miki.c has 25 lines.  (gdb) r  Starting program: /u01/home/oracle/miki  warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000  result[1-10] = 55  result[1-5] = 10  Program exited with code 023.  

l 1         表示顯示原始碼第一行開始的10行記錄。能夠寫成list 1
l           表示顯示原始碼中間的前後10行記錄,能夠寫成list 
空白斷行符號     表示反覆上一次命令操作
r            表示程式開始執行

(gdb) b 23  Breakpoint 1 at 0x4004f2: file miki.c, line 23.  (gdb) info b  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:23  (gdb) i b  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:23  (gdb) break func  Breakpoint 2 at 0x40049f: file miki.c, line 5.  (gdb) info break  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:23  2       breakpoint     keep y   0x000000000040049f in func at miki.c:5      (gdb) i b  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:23  2       breakpoint     keep y   0x000000000040049f in func at miki.c:5  3       breakpoint     keep y   0x000000000040049f in func at miki.c:2  (gdb) d 2  (gdb) i b  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:23  3       breakpoint     keep y   0x000000000040049f in func at miki.c:2  (gdb) delete 3  (gdb) i b  Num     Type           Disp Enb Address            What  1       breakpoint     keep y   0x00000000004004f2 in main at miki.c:2

break 23 表示設定第23行為斷點,能夠簡寫成 b 23
break func 表示設定func函數入口為斷點。能夠簡寫成 b func
info break 表示查詢設定的斷點,能夠簡寫成 i b
delete 2 表示刪除第二個斷點。能夠簡寫成 d 2

(gdb) r  Starting program: /u01/home/oracle/miki  warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000    Breakpoint 1, main () at miki.c:23  23             printf("result[1-10] = %d \n\r", result );  (gdb) n  result[1-10] = 55  24             printf("result[1-5] = %d \n\r", func(5) );  (gdb)    Breakpoint 2, func (n=5) at miki.c:5  5               int sum=0,i;  (gdb) p n  $1 = 5  (gdb) p i  $2 = 10922  (gdb) p sum  $3 = -1431642112  (gdb) n  6               for(i=0; i<n; i++)  (gdb) p i  $4 = 10922  (gdb) n  8                       sum+=i;  (gdb) p i  $5 = 0  (gdb) p sum  $6 = 0  (gdb) n  6               for(i=0; i<n; i++)  (gdb) p i  $7 = 0  (gdb) p n  $8 = 5  (gdb) p i  $9 = 0  (gdb) n  8                       sum+=i;  (gdb) p i  $10 = 1  (gdb) p sum  $11 = 0  (gdb) n  6               for(i=0; i<n; i++)  (gdb) p sum  $12 = 1  (gdb) n  8                       sum+=i;  (gdb) n  6               for(i=0; i<n; i++)  (gdb) p sum  $13 = 3  (gdb) n  8                       sum+=i;  (gdb) n  6               for(i=0; i<n; i++)  (gdb) n  8                       sum+=i;  (gdb) c  Continuing.  result[1-5] = 10    Program exited with code 023.  (gdb) 

r 表示程式開始執行
n 表示運行下一條語句
c 表示繼續運行
p i 表示列印出變數i的值
p sum 表示列印出變數sum的值
gdb的調試方法我就知道這麼多了。

更具體的能夠去看這個文檔。
調試工具gdb的命令還有非常多,gdb把它分成很多個種類。help命令僅僅是列出gdb的命令種類。假設要看種類中的命令。能夠使用help <class> 命令,如:help breakpoints,查看設定斷點的全部命令。也能夠直接help <command>來查看命令的協助。


gdb中,輸入命令時。能夠不用打全命令,僅僅用打命令的前幾個字元就能夠了,當然,命令的前幾個字元應該要標誌著一個唯一的命令。在Linux下,你能夠敲擊兩次TAB鍵來補齊命令的全稱,假設有反覆的,那麼gdb會把其例出來。
示範範例一:在進入函數func時,設定一個斷點。

能夠敲入break func,或是直接就是b func
(gdb) b func
Breakpoint 1 at 0×8048458: file hello.c, line 10.
示範範例二:敲入b按兩次TAB鍵,你會看到全部b打頭的命令:
(gdb) b
backtrace break bt
(gdb)
示範範例三:僅僅記得函數的首碼,能夠這樣:
(gdb) b make_ <按TAB鍵>
(再按下一次TAB鍵,你會看到:)
make_a_section_from_file make_environ
make_abs_section make_function_type
make_blockvector make_pointer_type
make_cleanup make_reference_type
make_command make_symbol_completion_list
(gdb) b make_
GDB把所有make開頭的函數所有例出來給你查看。



示範範例四:調試C++的程式時。有能夠函數名一樣。如:
(gdb) b ‘bubble( M-?
bubble(double,double) bubble(int,int)
(gdb) b ‘bubble(
你能夠查看到C++中的全部的重載函數及參數。

(註:M-?和“按兩次TAB鍵”是一個意思)

要退出gdb時,僅僅用發quit或命令簡稱q即可了。
GDB中執行UNIX的shell程式
————————————
在gdb環境中,你能夠運行UNIX的shell的命令,使用gdb的shell命令來完畢:
shell <command string>
調用UNIX的shell來運行<command string>,環境變數SHELL中定義的UNIX的shell將會被用來運行<command string>。假設SHELL未定義。那就使用UNIX的標準shell:/bin/sh。(在Windows中使用Command.com或cmd.exe)
另一個gdb命令是make:
make <make-args>
能夠在gdb中運行make命令來又一次build自己的程式。這個命令等價於“shell make <make-args>”。


在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/tty
調試已執行的程式
————————
兩種方法:
1、在UNIX下用ps查看正在執行的程式的PID(進程ID),然後用gdb <program> PID格式掛接正在執行的程式。


2、先用gdb <program>關聯上源碼,並進行gdb。在gdb中用attach命令來掛接進程的PID。

並用detach來取消掛接的進程。
暫停 / 恢複程式執行
—————————
偵錯工具中,暫停程式執行是必須的,GDB能夠方便地暫停程式的執行。

你能夠設定程式的在哪行停住。在什麼條件下停住,在收到什麼訊號時停往等等。以便於你查看執行時的變數,以及執行時的流程。


當進程被gdb停住時,你能夠使用info program 來查看程式的是否在執行。進程號,被暫停原因。


在gdb中。我們能夠有下面幾種暫停方式:斷點(BreakPoint)、觀察點(WatchPoint)、捕捉點(CatchPoint)、訊號(Signals)、線程停止(Thread Stops)。假設要恢複程式執行,能夠使用c或是continue命令。


一、設定斷點(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命令沒有參數時。表示在下一條指令處停住。
break … if <condition>
…能夠是上述的參數。condition表示條件,在條件成立時停住。

比方在迴圈境體中。能夠設定break if i=100。表示當i為100時停住程式。


查看斷點時,可使用info命令,例如以下所看到的:(註:n表示斷點號)
info breakpoints [n]
info break [n]
二、設定觀察點(WatchPoint)
觀察點一般來觀察某個運算式(變數也是一種運算式)的值是否有變化了。假設有變化,立即停住程式。我們有以下的幾種方法來設定觀察點:
watch <expr>
為運算式(變數)expr設定一個觀察點。

一量運算式值有變化時,立即停住程式。
rwatch <expr>
當運算式(變數)expr被讀時。停住程式。


awatch <expr>
當運算式(變數)的值被讀或被寫時。停住程式。


info watchpoints
列出當前所設定了的全部觀察點。


三、設定捕捉點(CatchPoint)
你可設定捕捉點來補捉程式執行時的一些事件。

如:載入共用庫(動態連結程式庫)或是C++的異常。設定捕捉點的格式為:
catch <event>
當event發生時,停住程式。event能夠是以下的內容:
1、throw 一個C++拋出的異常。(throw為keyword)
2、catch 一個C++捕捉到的異常。(catch為keyword)
3、exec 調用系統調用exec時。(exec為keyword。眼下此功能僅僅在HP-UX下實用)
4、fork 調用系統調用fork時。(fork為keyword,眼下此功能僅僅在HP-UX下實用)
5、vfork 調用系統調用vfork時。(vfork為keyword。眼下此功能僅僅在HP-UX下實用)
6、load 或 load <libname> 載入共用庫(動態連結程式庫)時。(load為keyword,眼下此功能僅僅在HP-UX下實用)
7、unload 或 unload <libname> 卸載共用庫(動態連結程式庫)時。

(unload為keyword,眼下此功能僅僅在HP-UX下實用)
tcatch <event>
僅僅設定一次捕捉點。當程式停住以後,應點被自己主動刪除。


著作權聲明:本文博主原創文章,部落格,未經同意不得轉載。

GDB實用的調試工具

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.