本文的內容基本來自
這篇教程,我在使用裡面的示例程式時遇到了」is not a file or directory」 的錯誤,因此修改了一下原來到源程式。
這個示例程式很簡單,包含兩個類:node和linkedlist。為了方便除錯,我們將這兩個類放到乙個檔案中。
首先檢查是否安裝gdb。如果您的系統中有g++,那麼gdb就已經安裝了。可以通過在命令列中輸入gdb -v來檢查是否安裝gdb。
gdb只能使用g++產生的symbol進行除錯。如果讀者使用sun cc編譯器,那麼可以使用乙個和gdb很類似到除錯工具:dbx
在除錯帶有debugging symbol的程式時,gdb才能如魚得水。使用g++的-g選項,即可編譯出帶有gdb的debugging symbol的程式。除-g選項外,還可以使用-ggdb選項,本文的makefile裡面即使用了-ggdb選項。
make -f makefile
編譯完成後,會生成乙個名為main的可執行檔案。
使用gdb main命令即可將main可執行檔案載入到gdb中。在我的終端,使用這個命令的結果如下:
gnu gdb (ubuntu/linaro 7.2-1ubuntu11) 7.2
license gplv3+: gnu gpl version 3 or later
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 "i686-linux-gnu".
for bug reporting instructions, please see:
...reading symbols from /home/jubin/downloads/gdb_sample/main...done.
(gdb)
(注:在emacs中,您可以使用m-x gdb來在emacs中使用gdb。emacs將分成兩個視窗,第二個視窗將顯示**,並有個箭頭指向正在執行的指令所在的**行。)
gdb啟動後,此時正在等待使用者輸入下乙個指令。因為需要檢視程式錯在**,所以首先需要執行這個程式,輸入run命令:
(gdb) run
starting program: /home/jubin/downloads/gdb_sample/main
creating node, 1 are in existence right now
creating node, 2 are in existence right now
creating node, 3 are in existence right now
creating node, 4 are in existence right now
the fully created list is:43
21now removing elements:
creating node, 5 are in existence right now
destroying node, 4 are in existence right now43
21program received signal sigsegv, segmentation fault.
0x08048cb4 in node::next (this=0x0) at main.cc:30
30node* next () const
(gdb)
顯然,這段程式出錯了,下面我們來分析下錯誤出在什麼地方。
從上面的出錯資訊可以看出在main.cc的第30行,this指標指向了0。但同時我們還想知道誰呼叫了第30行,以及呼叫程式的當時狀態。在gdb提示符中輸入:backtrace
(gdb) backtrace
#0 0x08048cb4 in node::next (this=0x0) at main.cc:30
#1 0x08048bea in linkedlist::remove (this=0x804c008, item_to_remove=@0xbffff2c4)at main.cc:79
#2 0x080488d6 in main (argc=1, argv=0xbffff3a4) at main.cc:122
(gdb)
從上面的資訊不僅可以看到出錯的方法和區域性變數,還可以找到呼叫第30行的程式以及呼叫時使用的引數item_to_remove的儲存位址。x命令可以使我們根據item_to_remove的位址獲得item_to_remove的值:
(gdb) x 0xbffff2c4
0xbffff2c4:0x00000001
(gdb)
從上面的資訊可以看出,當使用引數「1」呼叫
linkedlist::remove時,程式出錯。
現在我們知道**出錯了,下一步要做的是檢視在出錯前程式的狀態。一種方法是步進,直到快出錯的那個位置,另一種就是設定斷點,在gdb中這樣實現:
(gdb) break linkedlist::remove
breakpoint 1 at 0x8048ab3: file main.cc, line 54.
(gdb)
這樣位於 linkedlist::remove的斷點「1」就設定好了。如果我們只想檢視item_to_remove==1時的狀態,那麼需要使用條件斷點,在gdb中輸入:
(gdb) condition 1 item_to_remove == 1
(gdb)
這個命令的意思是只有在「item_to_remove == 1」的情況下,斷點「1」才會生效。
gdb中步進的命令是step。gdb有乙個很好的特性,當使用者只輸入回車時預設執行上乙個命令,因此步進時只需在第一步輸入step,後面直接敲擊回車就可以了。
(gdb) run
the program being debugged has been started already.
start it from the beginning? (y or n) y
starting program: /home/jubin/downloads/gdb_sample/main
creating node, 1 are in existence right now
creating node, 2 are in existence right now
creating node, 3 are in existence right now
creating node, 4 are in existence right now
the fully created list is:43
21now removing elements:
creating node, 5 are in existence right now
destroying node, 4 are in existence right now43
21breakpoint 1, linkedlist::remove (this=0x804c008, item_to_remove=@0xbffff2f4)
at main.cc:54
54node*marker = head_;
(gdb) step
55node*temp = 0; // temp points to one behind as we iterate
(gdb)
57while (marker != 0)
(gdb)
linkedlist::remove (this=0x804c008, item_to_remove=@0xbffff2f4) at main.cc:77
77marker = 0; // reset the marker
(gdb)
78temp = marker;
(gdb)
79marker = marker->next();
(gdb)
node::next (this=0x0) at main.cc:30
30node* next () const
(gdb)
program received signal sigsegv, segmentation fault.
0x08048cb4 in node::next (this=0x0) at main.cc:30
30node* next () const
(gdb)
離開gdb的命令:quit
GDB 簡單易上手的新人教程
gdb,又稱gnu偵錯程式,是用來幫助除錯我們程式的工具。gdb可以幹以下幾件事 1.給程式設定 特定條件下的 斷點 2.當程式停在斷點處時,我們檢視所有變數 暫存器的值 3.當程式停在斷點處時,我們除了能檢視所有變數 暫存器的值以外,還能在不改變源 的情況下改變這些值 這個確實屌 在我們學習使用g...
GDB 簡單易上手的新人教程
gdb,又稱gnu偵錯程式,是用來幫助除錯我們程式的工具。gdb可以幹以下幾件事 1.給程式設定 特定條件下的 斷點 2.當程式停在斷點處時,我們檢視所有變數 暫存器的值 3.當程式停在斷點處時,我們除了能檢視所有變數 暫存器的值以外,還能在不改變源 的情況下改變這些值 這個確實屌 在我們學習使用g...
GDB教程 檢視記憶體)
先看 n f u是可選的引數,表示乙個記憶體位址 1 n 是乙個正整數,表示顯示記憶體的長度,也就是說從當前位址向後顯示幾個位址的內容 2 f 表示顯示的格式 3 u 表示將多少個位元組作為乙個值取出來,如果不指定的話,gdb預設是4個bytes,如果不指定的話,預設是4個bytes。當我們指定了位...