Emacs高级调试方法

常规调试方法

一般Emacs在崩溃或者出现错误的时候,可以用命令 toggle-debug-on-error 来打开Emacs调试器,当Emacs或者插件出错时,Emacs会自动在 *Backtrace* buffer中显示错误堆栈,方便开发者定位错误。

高级调试方法

Emacs还有一些高级调试方法用于非错误场景的调试,举个例子:

sdcv.el基于posframe来实现翻译窗口的弹出,但是有个小问题,每次EAF网页中弹出翻译窗口的时候,鼠标都会跳到Emacs的左上角,翻译以后要重新移动光标, 非常的不方便。

但是这时候我们往往不知道到底是哪个Emacs插件引入的这种行为, 一个一个的排查非常消耗时,但是我知道Emacs底层API中设置光标位置的函数是 set-mouse-position, 所以这时候可以调用命令 (debug-on-entry 'set-mouse-position) 来设置当Emacs调用 set-mouse-position 函数的时候弹出堆栈,方便开发者定位Emacs运行时的函数调用堆栈。

这时,只要调用翻译函数,一旦光标被插件移动后,就会弹出类似下面的堆栈信息:

Debugger entered--entering a function:
* set-mouse-position(#<frame emacs@manjaro 0x11bbc30> 0 0)
  (progn (set-mouse-position frame 0 0))
  (if (and posframe-mouse-banish (not (equal (cdr (mouse-position)) (quote (0 . 0))))) (progn (set-mouse-position frame 0 0)))
  posframe--mouse-banish(#<frame emacs@manjaro 0x11bbc30>)
  ...

通过上面的堆栈信息,定位到是 posframe--mouse-banish 函数来设置的光标位置,最后通过 (setq posframe-mouse-banish nil) 来解决posframe弹出时移动光标的问题。

解决问题后可以通过命令 (cancel-debug-on-entry 'set-mouse-position) 取消运行时调试。

Happy hacking! :wink:

10赞

可以,不过我习惯用rg找到调用底层函数的插件函数后C-u eval-defun给那个函数加断点,然后开始单步调试

3赞

我比较懒,当知道底层API后,可以直接通过这种方法进入堆栈,简单直接,哈哈哈哈。

患有土鳖princ插入法,我最常用的方法

3赞

关键还是得心里有点谱,知道该在哪儿断点。有时候也可能 print 更合适,一设断点反而把复现条件给破坏了。

2赞

很好,但是不知道函数还是不行啊

我到现在都不知道edebug那个条件断点怎么设。还有以前死都不知道怎么取消instrument,后来才知道只要正常eval-defun一遍就成了 :joy:

当时写parinfer的时候调试要疯,这些方法都不是太好用。。。

edebug 有什么经验分享吗?这玩意儿实在不好用。

edebug很好用了,只要不是调各种hook。

找个buffer往里面写日志可能是最通用的办法了。

确实,很多时候都是在写message调试

哈哈 我也是, 原来我跟了哪个老师 就变成什么样了 。。。:smile_cat:

:hushed:我以为只有我一个。。。

好像还有个二分调试法,但是就不知道怎么操作了 :sweat_smile: