標籤:
GDB概述
GDB是GNU開源組織發布的一個強大的UNIX下的程式調試工具。或許,各位比較喜歡那種圖形介面方式的,像VC、BCB等IDE的調試,但如果你是在UNIX平台下做軟體,你會發現GDB這個調試工具有比VC、BCB的圖形化調試器更強大的功能。所謂“寸有所長,尺有所短”就是這個道理。
一般來說,GDB主要幫忙你完成下面四個方面的功能:
- 啟動你的程式,可以按照你的自訂的要求隨心所欲的運行程式。
- 可讓被調試的程式在你所指定的調置的斷點處停住。(斷點可以是條件運算式)
- 當程式被停住時,可以檢查此時你的程式中所發生的事。
- 動態改變你程式的執行環境。
從上面看來,GDB和一般的調試工具沒有什麼兩樣,基本上也是完成這些功能,不過在細節上,你會發現GDB這個調試工具的強大,大家可能比較習慣了圖形化的調試工具,但有時候,命令列的調試工具卻有著圖形化工具所不能完成的功能。讓我們一一看來。
一個調試樣本
//test.c#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", result ); printf("result[1-250] = %d \n", func(250) );}
編譯產生:
gcc -g test.c -o test./testresult[1-100] = 5050result[1-250] = 31125
使用GDB調試:
gdb test <---------- 啟動GDBGNU gdb (GDB) SUSE (7.1-8.9.1)Copyright (C) 2010 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-suse-linux".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/linzj/public_html/test/test...done.(gdb) l <-------------------- l命令相當於list,閱讀源碼。2 int func(int n) {3 int sum=0,i;4 for(i=0; i<n; i++){5 sum+=i;6 }7 return sum;8 }9 int main() {10 int i;11 long result = 0;(gdb) <-------------------- 直接斷行符號表示,重複上一次命令12 for(i=1; i<=100; i++){13 result += i;14 }15 printf("result[1-100] = %d \n", result );16 printf("result[1-250] = %d \n", func(250) );17 }(gdb) break 10 <-------------------- 設定斷點,在來源程式第10行處。Breakpoint 1 at 0x400642: file test.c, line 10.(gdb) break func <-------------------- 設定斷點,在函數func()入口處。Breakpoint 2 at 0x400613: file test.c, line 3.(gdb) info b <-------------------- 查看斷點資訊。Num Type Disp Enb Address What1 breakpoint keep y 0x0000000000400642 in main at test.c:102 breakpoint keep y 0x0000000000400613 in func at test.c:3(gdb) r <--------------------- 運行程式,run命令簡寫Starting program: /home/linzj/public_html/test/testMissing separate debuginfo for /lib64/ld-linux-x86-64.so.2Missing separate debuginfo for /lib64/libc.so.6Breakpoint 1, main () at test.c:11 <---------- 在斷點處停住。11 long result = 0;(gdb) n <--------------------- 單條語句執行,next命令簡寫。12 for(i=1; i<=100; i++){(gdb) n13 result += i;(gdb) n12 for(i=1; i<=100; i++){(gdb) n13 result += i;(gdb) c <--------------------- 繼續運行程式,continue命令簡寫。Continuing.result[1-100] = 5050 <----------程式輸出。Breakpoint 2, func (n=250) at test.c:3 <---------- 在斷點func處停住。3 int sum=0,i;(gdb) n4 for(i=0; i<n; i++){(gdb) p i <--------------------- 列印變數i的值,print命令簡寫。$1 = -1431539712(gdb) n5 sum+=i;(gdb) n4 for(i=0; i<n; i++){(gdb) p sum$3 = 0(gdb) n5 sum+=i;(gdb) p i$4 = 1(gdb) n4 for(i=0; i<n; i++){(gdb) p sum$5 = 1(gdb) bt <--------------------- 查看函數堆棧。#0 func (n=250) at test.c:4#1 0x0000000000400686 in main () at test.c:16(gdb) finish <--------------------- 退出函數。Run till exit from #0 func (n=250) at test.c:40x0000000000400686 in main () at test.c:1616 printf("result[1-250] = %d \n", func(250) );Value returned is $6 = 31125(gdb) c <--------------------- 繼續運行。Continuing.result[1-250] = 31125 <----------程式輸出。Program exited with code 027. <--------程式退出,調試結束。(gdb) q <--------------------- 退出gdb。
好了,有了以上的感性認識,還是讓我們來系統地認識一下gdb吧。
使用GDB
一般來說GDB主要調試的是C/C++的程式。要調試C/C++的程式,首先在編譯時間,我們必須要把調試資訊加到可執行檔中。使用編譯器(cc/gcc/g++)的 -g 參數可以做到這一點。如:
> cc -g hello.c -o hello> g++ -g hello.cpp -o hello
如果沒有-g,你將看不見程式的函數名、變數名,所代替的全是運行時的記憶體位址。當你用-g把調試資訊加入之後,並成功編譯目標代碼以後,讓我們來看看如何用gdb來調試他。
啟動GDB的方法有以下幾種:
gdb : program也就是你的執行檔案,一般在當然目錄下。
gdb core :用gdb同時調試一個運行程式和core檔案,core是程式非法執行後core dump後產生的檔案。
gdb : 如果你的程式是一個服務程式,那麼你可以指定這個服務程式運行時的進程ID。gdb會自動attach上去,並調試他。program應該在PATH環境變數中搜尋得到。
GDB啟動時,可以加上一些GDB的啟動開關,詳細的開關可以用gdb -help查看。我在下面只例舉一些比較常用的參數:
- -symbols / -s :從指定檔案中讀取符號表。
- -se file :從指定檔案中讀取符號表資訊,並把他用在可執行檔中。
- -core / -c :調試時core dump的core檔案。
- -directory / -d :加入一個源檔案的搜尋路徑。預設搜尋路徑是環境變數中PATH所定義的路徑。
GDB的命令
啟動gdb後,就你被帶入gdb的調試環境中,就可以使用gdb的命令開始偵錯工具了,gdb的命令可以使用help命令來查看,如下所示:
gdbGNU gdb (GDB) SUSE (7.1-8.9.1)Copyright (C) 2010 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-suse-linux".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.(gdb) helpList of classes of commands:aliases -- Aliases of other commandsbreakpoints -- Making program stop at certain pointsdata -- Examining datafiles -- Specifying and examining filesinternals -- Maintenance commandsobscure -- Obscure featuresrunning -- Running the programstack -- Examining the stackstatus -- Status inquiriessupport -- Support facilitiestracepoints -- Tracing of program execution without stopping the programuser-defined -- User-defined commandsType "help" followed by a class name for a list of commands in that class.Type "help all" for the list of all commands.Type "help" followed by command name for full documentation.Type "apropos word" to search for commands related to "word".Command name abbreviations are allowed if unambiguous.(gdb)
gdb的命令很多,gdb把之分成許多個種類。help命令只是例出gdb的命令種類,如果要看種類中的命令,可以使用help 命令,如:help breakpoints,查看設定斷點的所有命令。也可以直接help 來查看命令的協助。
gdb中,輸入命令時,可以不用打全命令,只用打命令的前幾個字元就可以了,當然,命令的前幾個字元應該要標誌著一個唯一的命令,在Linux下,你可以敲擊兩次TAB鍵來補齊命令的全稱,如果有重複的,那麼gdb會把其例出來。
樣本一:在進入函數func時,設定一個斷點。可以敲入break func,或是直接就是b func
(gdb) b funcBreakpoint 1 at 0x400613: file test.c, line 3.
樣本二:敲入b按兩次TAB鍵,你會看到所有b打頭的命令:
(gdb) bbacktrace bookmark break bt
樣本三:只記得函數的首碼,可以這樣:
(gdb) b f <按兩次TAB鍵>frame_dummy funcGDB把所有make開頭的函數全部例出來給你查看。
樣本四:調試C++的程式時,有可以函數名一樣。如:
(gdb) b bubble( <按兩次TAB鍵>bubble(double,double) bubble(int,int)你可以查看到C++中的所有的重載函數及參數。(註:M-?和“按兩次TAB鍵”是一個意思)
要退出gdb時,只用發quit或命令簡稱q就行了。
GDB中運行UNIX的shell程式
在gdb環境中,你可以執行UNIX的shell的命令,使用gdb的shell命令來完成:
(gdb) shell lstest.c test test.o
還有一個gdb命令是make,可以在gdb中執行make命令來重新build自己的程式
(gdb) make
在GDB中運行程式
當以gdb 方式啟動gdb後,gdb會在PATH路徑和目前的目錄中搜尋的源檔案。如要確認gdb是否讀到源檔案,可使用l或list命令,看看gdb是否能列出原始碼。
在gdb中,運行程式使用r或是run命令。程式的運行,你有可能需要設定下面四方面的事。
程式運行參數。
- set args :可指定運行時參數。(如:set args 10 20 30 40 50)
- show args :命令可以查看設定好的運行參數。
運行環境。
- path [dir] :可設定程式的運行路徑。
- show paths :查看程式的運行路徑。
- set environment varname [=value] :設定環境變數。如:set env USER=hchen
- show environment [varname] :查看環境變數。
工作目錄。
- cd [dir] :相當於shell的cd命令。
- pwd :顯示當前的所在目錄。
程式的輸入輸出。
- info terminal :顯示你程式用到的終端的模式。
- 使用重新導向控製程序輸出。如:run > outfile
- tty命令可以指寫輸入輸出的終端裝置。如:tty /dev/ttyb
來自為知筆記(Wiz)
Linux進階編程--04.GDB偵錯工具(入門概述)