要想在vim中调试,除了使用vimgdb外,还可使用clewn和pyclewn,这两个工具也是vimgdb的做者提供的,用法基本相同。区别在于,clewn是使用C语言编写的,而pyclewn是使用python语言编写的,具备更好的跨平台能力。本文主要介绍pyclewn工具。 python
使用pyclewn须要计算机上安装有python 2.4(或以上版本)以及gvim 7.0或以上版本。需注意的是,pyclewn只能与gvim配合使用,它不支持终端中的vim(clewn也是如此) (update 2011/12/27: 在vim 7.3中,最新的pyclew已经支持终端中的vim调试)。另外,gvim在编译时须要使能netbeans_intg特性和autocmd特性。 linux
pyclewn启动时,它会启动一个gvim窗口,咱们的调试将在这个gvim窗口中进行。运行pyclewn的终端将作为gdb的控制终端,所调试程序的输入输出都会经过这个终端进行(固然,你也能够在gdb中经过tty命令更改控制终端)。 app
前面三条命令是标准的vim命令,切换到示例程序所在目录,编译该程序,并打开文件main.c。后面两条命令以大写字母C作为起始,这是pyclewn自定义的命令,pyclewn将会把字母C后的命令内容传递给GDB调试器。因此上面两条命令至关于在GDB中执行file factor和break 14,加载factor作为被调试的程序,并在main.c的第14行设置一个断点。
从上面的调试过程能够看出,使用pyclewn调试很方便。并且,使用pyclewn也能够在windows上进行调试,不过我没有试过,有兴趣的朋友能够试一下。在windows上调试,可能须要使用cygwin中所带的gdb。
在之前的文章中,Easwy介绍了如何使用pyclewn在gvim中调试。网友yorker留言询问如何在vim中远程调试服务器上的程序而不须要登陆服务器。这就涉及到远程调试的话题了。
所谓远程调试,顾名思义,就是在本地调试运行在远端设备上的程序。远程调试在嵌入式系统的开发上应用的比较多。嵌入式设备上内存、磁盘空间都比较有限,可能没法容纳整个gdb的调试环境和符号表;即使能够容纳,也须要对gdb进行交叉编译,比较麻烦,因此更经常使用远程调试的办法。像网友yorker这样在本地调试远端服务器上的程序,也是一种应用。
远程调试最简单的办法是使用gdbserver。gdbserver是一个很是小的程序,大小不到100K,所以能够方便的拷贝到嵌入式设备上,交叉编译也很简单。使用gdbserver,就可使你的程序与远端的GDB调试器通信,接收并执行调试命令。
gdbserver在大多数Linux系统中已经包含,不须要特别安装。若是你须要交叉编译,到GNU GDB网站上下载gdb的源代码,在里面你能够找到gdbserver。
本文将主要介绍如何在vim使用pyclewn进行远程调试(关于pyclewn的介绍,参见Easwy的的另一篇文章:vim使用进阶: 在vim中进行GDB调试 – 使用pyclewn)。实际上,本文中所涉及的命令都是经常使用的远程调试命令,你能够直接使用gdb或ddd来执行这些命令,进行远程调试。
咱们还使用在pyclewn一文中的程序作为调试示例,对那个程序作了一点修改,原来该程序须要由标准输入读取一个数字,如今则改成由命令行参数中传入。修改后的程序在这里下载。
如今咱们准备开始调试。咱们把编译好的二进制程序拷贝到一个名为Easwy_remote的计算机,而后在Easwy_remote上执行:
gdbserver Easwy_local:333 ./factorial 4
上面的命令执行完后,屏幕输出以下(你的输出可能稍有不一样):
Process ./factorial created; pid = 7532
Listening on port 333
上面的gdbserver命令的含义是:使用gdbserver启动./factorial程序,并传入参数4,而gdbserver监听在333端口上,等待远程GDB程序中的链接。命令中的Easwy_local代表容许来自主机Easwy_local的链接,不过目前的gdbserver版本其实是不检测所链接的主机的。
如今,咱们在Easwy_local主机上启动pyclewn,并在所打开的gvim窗口中执行下面的命令:
:e main.c
:Cmapkeys
:Cfile factorial
:Cbreak 15
:Ctarget remote Easwy_remote:333
:Ccontinue
上面的命令,首先打开main.c文件,而后执行pyclewn提供的mapkeys命令,加载pyclewn的按键映射。而后使用file命令加载所要调试的程序,并在main.c的第15行设置一个断点。
须要注意的是target remote命令。这条命令告诉GDB链接到主机Easwy_remote的333端口,进行调试。执行完这条命令,咱们就链接到了远端运行的程序。接下来就能够像调试本地程序那样进行调试了,在上面Easwy使用的continue命令,使程序执行到断点处,而后继续调试。
下面是远程调试的屏幕抓图:
gdbserver不只能够像本文中这样启动一个调试进程,它还能够链接到一个已经运行的进程上对其进行调试,例如,用gdbserver Easwy_local:333 –attach 1235命令就可使gdbserver链接到进程ID为1235的进程。
更多关于vi的内容,请参见Easwy的博客上的其它文章。
<< 返回vim使用进阶: 目录
本节所用命令的帮助入口:
:help vimgdb
在UNIX系统最初设计时,有一个很是重要的思想:每一个程序只实现单一的功能,经过管道等方式把多个程序链接起来,使之协同工做,以完成更强大的功能。程序只实现单一功能,一方面下降了程序的复杂性,另外一方面,也让它专一于这一功能,把这个功能作到最好。就好像搭积木同样,每一个积木只提供简单的功能,但不一样的积木垒在一块儿,就能搭出大厦、汽车等等复杂的东西。
从UNIX系统(及其变种,包括Linux)的命令行就能够看出这一点,每一个命令只专一于单一的功能,但经过管道、脚本等把这些命令揉合起来,就能完成复杂的任务。
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的源码。到vim主页下载当前最新的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 < vimgdb/vim71.diff
[ 定制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 <stdio.h>
extern int factor(int n, int *rt);
int main(int argc, char **argv)
{
int i;
int result = 1;
for (i = 1; i < 6; i++)
{
factor(i, &result);
printf("%d! = %d\n", i, result);
}
return 0;
}
文件~/tmp/factor/factor.c内容以下,定义了子函数factor()。之因此把它放到子目录factor/,是为了演示vimgdb能够根据调试位置自动打开文件,无论该文件在哪一个目录下:
/* ~/tmp/factor/factor.c */
int factor(int n, int *r)
{
if (n <= 1)
*r = n;
else
{
factor(n - 1, r);
*r *= n;
}
return 0;
}
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,咱们已经在剑不离手 – quickfix一文中讲过,再也不赘述。
如今,假设已经完成连接,生成了最终的sample文件,咱们就能够进行调试了。
vimgdb补丁已经定义了一些键绑定,咱们先加载这些绑定:
:run macros/gdb_mappings.vim
加载后,一些按键就被定义为调试命令(vimgdb定义的键绑定见”:help gdb-mappings“)。按<F7>能够在按键的缺省定义和调试命令间切换。
好了,咱们如今按空格键,在当前窗口下方会打开一个小窗口(command-line窗口),这就是vimgdb的命令窗口,能够在这个窗口中输入任何合法的gdb命令,输入的命令将被送到gdb执行。如今,咱们在这个窗口中输入”gdb“,按回车后,command-line窗口自动关闭,而在当前窗口上方又打开一个窗口,这个窗口是gdb输出窗口。如今vim的窗口布局以下(我又按空格打开了command-line窗口):
小技巧: 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看起来是这样:
断点所在的行被置以蓝色,并在行前显示标记1和2代表是第几个断点;程序当前运行到的行被置以黄色,行前以”=>”指示,代表这是程序执行的位置(显示的颜色用户能够调整)。
接下来,咱们再按”C“,运行到第2个断点处,如今,咱们输入下面的vim命令,在右下方分隔出一个名为gdb-variables的窗口:
:bel 20vsplit gdb-variables
而后用”v“命令选中变量i,按”CTRL-P“命令,把变量i加入到监视窗口,用一样的方式把变量result也加入到监视窗口,这里能够从监视窗口中看到变量i和result的值。
如今咱们按”S“步进到factor函数,vim会自动打开factor/factor.c文件并标明程序执行的位置。咱们再把factor()函数中的变量n加入到监视窗口;而后按空格打开command-line窗口,输入下面的命令,把变量*r输入到变量窗口:
createvar *r
如今,vim看起来是这样的:
如今,你能够用”S“、”CTRL-N“或”C“来继续执行,直至程序运行结束。
若是你是单步执行到程序结束,那么vim最后可能会打开一个汇编窗口。是的,vimgdb支持汇编级的调试。这里咱们不用进行汇编级调试,忽略便可。
若是你发现程序有错误,那么能够按”Q“退出调试(gdb会提示是否退出,回答y便可),而后修改代码、编译、调试,直到最终完成。在修改代码时,你可能并不喜欢vimgdb的键映射(例如,它把CTRL-B映射为设置断点,而这个键又是经常使用的翻页功能),你能够按<F7>取消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后,按<F7>,就进入调试模式以及设定调试的键映射。在第一次进入调试模式时,会提示你输入要调试的文件名,之后就没必要再输入了。再按一次<F7>,就退出调试模式,取消调试的键映射。
利用vim的键映射(map)机制,你能够把你喜欢的gdb命令映射为vim的按键,方便多了。映射的例子能够参照~/.vim/macros/ gdb_mappings.vim。
再附上一张抓图,这是使用putty远程登陆到linux上,在终端vim中进行调试。这也是我为何喜欢vimgdb的缘由,由于它能够在终端vim中调试,而clewn只支持gvim:
由于我不常使用gdb调试,因此本文仅举了个简单的例子,以抛砖引玉。欢迎你们共享本身的经验和心得。
我在文章vimgdb调试时的常见问题及解决中列出了一些常见问题及其解决方法,但愿对你们有帮助。
最后,让咱们感谢vimgdb做者xdegaye的辛勤劳动,咱们后续文章会介绍pyclewn,这是vim与gdb结合的另一种形式,它和vimgdb同属一个项目。