1. 程式人生 > >vim gdb ddd xxgdb精彩的程式除錯

vim gdb ddd xxgdb精彩的程式除錯

來源:
ChinaUnix部落格  日期:
2008.03.14 19:10 (共有0條評論)
我要評論


//------------------------------------------------------------------------------------------------------------------------------------------------
圖形GDB1.sudo apt-get install xxgdb
圖形GDB2.sudo apt-get install ddd
圖形GDB3.使用vimgdb補丁在vim中執行(強烈建議使用vimgdb除錯程式,極其好用gliethttp_20080314)
//------------------------------------------------------------------------------------------------------------------------------------------------
一下文字轉載自:http://blog.csdn.net/easwy/archive/2007/10/17/1828678.aspx
本節所用命令的幫助入口:
:help vimgdb
         在UNIX系統最初設計時,有一個非常重要的思想:每個程式只實現單一的功能,通過管道等方式把多個程式連線起來,使之協同工作,以完成更強大的功能。程式只實現單一功能,一方面降低了程式的複雜性,另一方面,也讓它專注於這一功能,把這個功能做到最好。就好像搭積木一樣,每個積木只提供簡單的功能,但不同的積木壘在
一起,就能搭出大廈、汽車等等複雜的東西。
        從UNIX系統(及其變種)的命令列就可以看出這一點,每個命令只專注於單一的功能,但通過管道、指令碼等把這些命令揉合起來,就能完成複雜的任務。VI/VIM的設計也遵從這一思想,它只提供了文字編輯功能(與Emacs的大而全剛好相反),而且正如大家所看到的,它在這一領域做的是如此的出色。
        也正因為如此,VIM自身並不提供整合開發環境所需的全部功能(它也不準備這樣做,VIM只想成為一個通用的文字編輯器)。它把諸如編譯、除錯這樣功能,交給更專業的工具去實現,而VIM只提供與這些工具的介面。
        我們在前面已經介紹過VIM與編譯器的介面(見quickfix主題),VIM也提供了與偵錯程式的介面,這一介面就是netbeans。除此之外,還可以給VIM打一個補丁,以使其支援GDB偵錯程式。我們在本篇以及下一篇分別介紹這兩種方式。
        由於netbeans介面只能在gvim中使用,而打上vimgdb補丁後,無論在終端的vim,還是gvim,都可以除錯。所以我更喜歡打補丁的方式,本篇先介紹這種方法。
        打補丁的方式,需要重新編譯VIM,剛好借這個機會,介紹一下VIM的編譯方法。我只介紹Linux上編譯方法,如果你想在windows上編譯vim,可以參考這篇文件:

Vim: Compiling HowTo: For Windows 。

[ 下載VIM原始碼 ]

首先我們需要下載VIM的原始碼。到
http://www.vim.org/sources.php
下載當前最新的VIM 7.1的原始碼,假設我們把程式碼放到~/install/目錄,檔名為vim-7.1.tar.bz2。

[ 下載vimgdb補丁 ]

接下來,我們需要下載vimgdb補丁,下載頁面在:
http://sourceforge.net/project/showfiles.php?group_id=111038&package_id=120238
在這裡,選擇vim 7.1的補丁,把它儲存到~/install/vimgdb71-1.12.tar.gz。

[ 打補丁 ]

執行下面的命令,解壓原始碼檔案,並打上補丁:
cd ~/install/
tar xjf vim-7.1.tar.bz2
tar xzf vimgdb71-1.12.tar.gz
patch -d vim71 --backup -p0
[ 定製VIM的功能 ]

         預設的VIM配置已經適合大多數人,但有些時候你可能需要一些額外的功能,這時就需要自己定製一下VIM。定製VIM很簡單,進入~/install/vim71/src檔案,編輯Makefile檔案。這是一個註釋很好的文件,根據註釋來選擇:
- 如果你不想編譯gvim,可以開啟--disable-gui選項;
- 如果你想把perl, python, tcl, ruby等介面編譯進來的話,開啟相應的選項,例如,我打開了--enable-tclinterp選項;
- 如果你想在VIM中使用cscope的話,開啟--enable-cscope選項;
- 我們剛才打的vimgdb補丁,自動在Makefile中加入了--enable-gdb選項;
- 如果你希望在vim使用中文,使能--enable-multibyte和--enable-xim選項;
- 可以通過--with-features=XXX選項來選擇所編譯的VIM特性集,預設是--with-features=normal;
- 如果你沒有root許可權,可以把VIM裝在自己的home目錄,這時需要開啟prefix = $(HOME)選項;

      編輯好此檔案後,就可以編輯安裝vim了。如果你需要更細緻的定製VIM,可以修改config.h檔案,開啟/關閉你想要的特性。

[ 編譯安裝 ]

編譯和安裝VIM非常簡單,使用下面兩個命令:
make
make install
你不需要手動執行./configure命令,make命令會自動呼叫configure命令。
上面的命令執行完後,VIM就安裝成功了。
我在編譯時打開了prefix = $(HOME)選項,因此我的VIM被安裝在~/bin目錄。這時需要修改一下PATH變數,以使其找到我編輯好的VIM。在~/.bashrc檔案中加入下面這兩句話:
PATH=$HOME/bin:$PATH
export PATH
退出再重新登入,現在再敲入vim命令,發現已經執行我們編譯的VIM了。

[ 安裝vimgdb的runtime檔案 ]

執行下面的命令,解壓vimgdb的runtime檔案到你的~/.vim/目錄:
cd ~/install/vimgdb/
tar zxf vimgdb_runtime.tgz –C~/.vim/
現在啟動VIM,在VIM中執行下面的命令以生成幫助檔案索引:
:helptags ~/.vim/doc
現在,你可以使用“:help vimgdb”命令檢視vimgdb的幫助了。
至此,我們重新編譯了VIM,併為之打上了vimgdb補丁。下面我以一個例子來說明如何在VIM中完成“編碼—編譯—除錯”一條龍服務。

[ 在VIM中除錯 ]

首先確保你的計算機上安裝了GDB ,Vimgdb支援5.3以上的GDB版本,不過最好使用GDB 6.0以上的版本。
我使用下面這個簡單的例子,來示例一下如何在VIM中使用GDB除錯。先來看示例程式碼:
檔案~/tmp/sample.c內容如下,這是主程式,呼叫函式計算某數的階乘並列印:
/* ~/tmp/sample.c */
#include
extern int factor(int n, int *rt);
int main(int argc, char **argv)
{
int i;
int result = 1;
for (i = 1; i
檔案~/tmp/factor/factor.c內容如下,定義了子函式factor()。之所以把它放到子目錄factor/,是為了演示vim可以自動根據除錯位置開啟檔案,不管該檔案在哪個目錄下:
/* ~/tmp/factor/factor.c */
int factor(int n, int *r)
{
if (n
Makefile檔案,用來編譯示例程式碼,最終生成的可執行檔名為sample。
# ~/tmp/Makefile
sample: sample.c factor/factor.c
gcc -g -Wall -o sample sample.c factor/factor.c
假設vim的當前工作目錄是~/tmp(使用“:cd
~/tmp”命令切換到此目錄)。我們編輯完上面幾個檔案後,輸入命令“:make”,vim就會根據Makefile檔案進行編譯。如果編譯出錯,
VIM會跳到第一個出錯的位置,改完後,用“:cnext”命令跳到下一個錯誤,以此類推。這種開發方式被稱為quickfix,我們已經在前面的文章中
講過,不再贅述。
現在,假設已經完成連結,生成了最終的sample檔案,我們就可以進行除錯了。
Vimgdb補丁已經定義了一些鍵繫結,我們先載入這些繫結:
:run macros/gdb_mappings.vim
載入後,一些按鍵就被繫結為除錯命令(Vimgdb定義的鍵繫結見“:help gdb-mappings”)。按鍵可以在按鍵的預設定義和除錯命令間切換。
好了,我們現在按空格鍵,在當前視窗下方會開啟一個小視窗(command-line視窗),這就是vimgdb的命令視窗,可以在這個視窗中輸入任何合
法的gdb命令,輸入的命令將被送到gdb執行。現在,我們在這個視窗中輸入“gdb”,按回車後,command-line視窗自動關閉,而在當前視窗
上方又開啟一個視窗,這個視窗是gdb輸出視窗。現在VIM的窗口布局如下(我又按空格打開了command-line視窗):
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://p.blog.csdn.net/images/p_blog_csdn_net/easwy/279129/o_vimgdb1.JPG');}" onmousewheel="return imgzoom(this);" alt="" />

Tips:
command-line視窗是一個特殊的視窗,在這種視窗中,你可以像編輯文字一樣編輯命令,完成編輯後,按回車,就會執行此命令。你要重複執行某條命
令,可以把游標移到該命令所在的行,然後按回車即可;你也可以對歷史命令進行修改後再執行。詳見“:help cmdline-window”。

接下來,在command-line視窗中輸入以下命令:
cd ~/tmp
file sample
這兩條命令切換gdb的當前工作目錄,並載入我們編譯的sample程式準備除錯。
現在使用VIM的移動命令,把游標移動到sample.c的第7行和14行,按“CTRL-B”在這兩處設定斷點,然後按“R”,使gdb執行到我們設定
的第一個斷點處(“CTRL-B”和“R”都是gdb_mappings.vim定義的鍵繫結,下面介紹的其它除錯命令相同)。現在VIM看起來是這樣:

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://p.blog.csdn.net/images/p_blog_csdn_net/easwy/279129/o_vimgdb2.PNG');}" onmousewheel="return imgzoom(this);" alt="" />
斷點所在的行被置以藍色,並在行前顯示標記1和2表明是第幾個斷點;程式當前執行到的行被置以黃色,行前以“=>”指示,表明這是程式執行的位置(顯示的顏色使用者可以調整)。
接下來,我們再按“C”,執行到第2個斷點處,現在,我們輸入下面的vim命令,在右下方分隔出一個名為gdb-variables的視窗:
:bel 20vsplit gdb-variables
然後用“v”命令選中變數i,按“CTRL-P”命令,把變數i加入到監視視窗,用同樣的方式把變數result也加入到監視視窗,這裡可以從監視視窗中看到變數i和result的值。

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://p.blog.csdn.net/images/p_blog_csdn_net/easwy/279129/o_vimgdb3.PNG');}" onmousewheel="return imgzoom(this);" alt="" />
現在我們按“S”步進到factor函式,VIM會自動開啟factor/factor.c檔案並標明程式執行的位置。我們再把factor()函式中的變數n加入到監視視窗;然後按空格開啟command-line視窗,輸入下面的命令,把變數*r輸入到變數視窗:
createvar *r
現在,VIM看起來是這樣的:

screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://p.blog.csdn.net/images/p_blog_csdn_net/easwy/279129/o_vimgdb4.PNG');}" onmousewheel="return imgzoom(this);" alt="" />
現在,你可以用“S”、“CTRL-N”或“C”來繼續執行,直至程式執行結束。
如果你是單步執行到程式結束,那麼VIM最後可能會開啟一個彙編視窗。是的,vimgdb支援彙編級的除錯。這裡我們不用進行彙編級除錯,忽略即可。
如果你發現程式有錯誤,那麼可以按“Q”退出除錯(gdb會提示是否退出,回答y即可),然後修改程式碼、編譯、除錯,直到最終完成。在修改程式碼時,你可能
並不喜歡vimgdb的鍵對映(例如,它把CTRL-B對映為設定斷點,而這個鍵又是常用的翻頁功能),你可以按取消vimgdb的鍵對映,或者你直接修
改gdb_mappings.vim檔案中定義的對映。
看,用VIM GDB除錯是不是很簡單?!

我們可以再定製一下,使除錯更加方便。
開啟~/.vim/macros/ gdb_mappings.vim檔案,在“let s:gdb_k = 0”這一行下面加上這段內容:
" easwy add
if ! exists("g:vimgdb_debug_file")
let g:vimgdb_debug_file = ""
elseif g:vimgdb_debug_file == ""
call inputsave()
let g:vimgdb_debug_file = input("File: ", "", "file")
call inputrestore()
endif
call gdb("file " . g:vimgdb_debug_file)
" easwy end
在“let s:gdb_k = 1”這一行下面加上這段內容:
" easwy add
call gdb("quit")
" end easwy
註釋掉最後一行的“call s:Toggle()”。
然後在你的vimrc中增加這段內容:
""""""""""""""""""""""""""""""
" vimgdb setting
""""""""""""""""""""""""""""""
let g:vimgdb_debug_file = ""
run macros/gdb_mappings.vim
現在,在啟動vim後,按,就進入除錯模式、定義除錯的鍵對映。在第一次進入除錯模式時,會提示你輸入要除錯的檔名,以後就不必再輸入了。再按一次,就退出除錯模式,取消除錯的鍵對映。
利用VIM的鍵對映機制,你可以把你喜歡的GDB命令對映為VIM的按鍵,方便多了。對映的例子可以參照~/.vim/macros/ gdb_mappings.vim。
再附上一張抓圖,這是使用putty遠端登入到linux上,在終端vim中進行除錯。這也是我為什麼喜歡vimgdb的原因,因為它可以在終端vim中除錯,而clewn只支援gvim:
screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('http://p.blog.csdn.net/images/p_blog_csdn_net/easwy/279129/o_vimgdb5.PNG');}" onmousewheel="return imgzoom(this);" alt="" />

因為我不常使用GDB除錯,所以本文僅舉了個簡單的例子,以拋磚引玉。歡迎大家共享自己的經驗和心得。
最後,讓我們感謝vimgdb作者xdegaye的辛勤勞動,我們下一篇會介紹clewn,這是VIM與GDB結合的另外一種形式,它和vimgdb同屬一個專案。

[參考文件]
1. VIM幫助檔案
2.
http://vimcdoc.sourceforge.net/

3.
http://clewn.sourceforge.net/index.html

[尾記]
本文可以自由應用於非商業用途。轉載請註明出處。
原文連結:
http://blog.csdn.net/easwy

[版本]
15Oct07, easwy, v0.1, initial version