精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-20
调试GNU Emacs中有两个高度器,debug和edebug。第一个是Emacs内建的可以随时使用它;第二个需要借助一些函数才能使用。 debug假设你编写了用于加1的函数。但函数有个bug。你误将1-输入为1=了。函数定义如下: (defun triangle-bugged (number)当传递4给这个函数时: (triangle-bugged 4)在Emacs 21中,将产生一个*Backtrace*缓冲区,并进入这个缓冲区: ---------- Buffer: *Backtrace* ----------(重新格式化了一下;调试不会自动折行。可以用q退出调试器) 实际上,像这样简单的bug,'Lisp error'这行告诉了我们如何修改定义。函数1=为'void'。 在Emacs 20中,你将看到: Symbol's function definition is void: 1=这与21版中的*Backtrace*缓冲区中的意思是一样的。 假设你还不是很清楚要如何做?你可以阅读完整的回溯信息。 在GNU Emacs 21中,它将自动启动调试器,并将信息放到*Backtrace*缓冲区中;如果有使用Emacs21,可能需要按下面的方法手工启动调试器。 在*Backtrace*中从下向上读;它说明了Emacs是如何出错的。Emacs执行了一个交互式命令C-x C-e(eval-last-sexp),它执行了triangle-bugged语句。上面的每一行显示了Lisp解释器执行内容。 缓冲区的顶部是: (setq number (1= number)) Emacs试图执行这个语句;依次来执行,它首先执行内部的语句: (1= number) 这里发生了错误,如错误信息所说: Debugger entered--Lisp error: (void-function 1=) 你可以修正这个错误,然后重新执行函数定义,再运行测试代码。 debug-on-entryGNU Emacs 21在函数出错时自动启动了调试器。GNU Emacs 20不会这样做;它只显示一条出错信息。你需要手工启动调试器。 手工启动的好处是在程序没有bug的时候也可以调试。 你可以调用debug-on-entry函数进入调试器。 输入: M-x debug-on-entry RET triangle-bugged RET 然后,执行下面的语句: (triangle-bugged 5)所有版本的Emacs都将产生一个*Backtrace*缓冲区告诉你它将执行triangle-debugged函数: ---------- Buffer: *Backtrace* ----------在*Backtrace*缓冲区中输入d。Emacs将执行triangle-bugged的第一行语句;缓冲区看起来如下: ---------- Buffer: *Backtrace* ---------- 现在,再次输入d,连续8次慢慢的输入d,Emacs将执行函数定义的另一个语句。 最后缓冲区看起来如下: ---------- Buffer: *Backtrace* ----------最后再输入两次d,Emacs将到达错误的位置,*Backtrace*缓冲区顶部的两行将显示: ---------- Buffer: *Backtrace* ---------- 输入d可以单步执行函数。 可以输入q退出*Backtrace*缓冲区;这将退出跟踪,但并不会退出debug-on-entry。 要退出debug-on-entry,需要调用cancel-debug-on-entry并输入函数名称: M-x cancel-debug-on-entry RET triangle-bugged RET debug-on-quit和(debug)除了debug-on-error或调用debug-on-entry,还有另外两种方法启动debug。 可以通过将变量debug-on-quit设置为t,随时输入C-g(keyboard-quit)来启动debug。这在调试无限循环时很用效。 或者,你可以在代码中插入(debug)以启动调试器,比如: (defun triangle-bugged (number) edebug源码级的调试器Edebug是一个源码级的调试器。Edebug通常显示你要调试的源码,并在左边用箭头指出当前执行的行。 你可以单步执行函数,或者快速的执行到断点位置。 下面是tringle-recursively的调试函数: (defun triangle-recursively-bugged (number)同样,你可以在函数定义后面使用C-x C-e(eval-last-sexp)安装函数,或者将光标放到定义的内部输入C-M-x(eval-defun)。(缺省情况下,eval-defun命令只在Emacs Lisp或Lisp交互模式下才可以工作。) 但是,为了使用Edebug调试函数,你必须使用另一个命令。可以将停留在函数内部然后输入 M-x edebug-defun RET 这将使Emacs自动加载Edebug。在加载完成后,可以将光标放在下面语句的后面输入C-x C-e(eval-last-sexp): (triangle-recursively-bugged 3)将跳到triangle-recursively-bugged的源码,光标被设置在函数if语句所在的开始行。并且,可以在这行的左边看到一个箭头。箭头标明了函数当前执行的位置。(在例子中,我们使用=>代替;在窗口系统中,你可以看到一个实心的三角形) =>-!-(if (= number 1)在这里,point的位置显示为-!-。 如果你输入<spc>,point将移到下一个语句;这行将显示如下:</spc> =>(if -!-(= number 1) 如果继续输入<spc>,point将继续从一个语句移到另一个语句。每次只要语句返回了值,它都会显示到回显区。比如,在point移过number时,你将看到:</spc> Result: 3 = C-c这表示number的值为3,它的ASCII值是'control-c'。 你可以继续执行,直到错误的位置。在执行之前,这行如下: => -!-(1= number))))) ; Error here. 当再次输入<spc>时,将产生错误信息:</spc> Symbol's function definition is void: 1= 输入q退出Edebug。 要从函数上移除调试的机制,可以重新使用C-x C-e执行函数定义。 Edebug除了跟踪执行外可以做更多的工作。你可以设置它在遇到错误时停止;可以让它显示或修改变量的值;你可以查找出函数被执行了多少次,等等。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 4883 次