首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
299 阅读
2
从零开始配置 vim(15)——状态栏配置
175 阅读
3
nvim番外之将配置的插件管理器更新为lazy
164 阅读
4
2018总结与2019规划
154 阅读
5
PDF标准详解(五)——图形状态
128 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
emacs
elisp
学习笔记
windows
文本操作术
编辑器
NeoVim
Vim
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
467
篇文章
累计收到
33
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
1
篇与
的结果
2026-10-29
《elisp 每日一练》——调试
前面我们一直是通过message 打印信息,以及通过出错的调用栈来看问题在哪,这种对于一些简短的代码来说,人肉编译可能更快一些,但是一旦代码规模扩大,引入复杂的第三方包,可能就不那么直观了。而且有些elisp 函数返回的数据结构比较复杂,虽然文档有说明但是没有直观的看到具体数据,在使用它获取数据时仍然显得有点复杂。这个时候就可以祭出调试这个手段了。背景知识elisp 的调试目前没有好用的ide,可以让我们直接在某一处快速下断点。但是仍然有几种方式下断点进入调试状态。第一种方式是通过 edebug-defun 下一个函数断点,具体的操作是,我们要将光标放在被调试函数体的任意位置,然后执行 edebug-mode。只要函数被调用就会进入调试状态,此时会在当前buffer中启用一个 edebug-mode 的 minor mode。 我们可以通过下列快捷键进行调试:<SPC> 进入下一行i 进入被调函数的内部c 继续运行到下一个断点b 在光标所在位置下一个断点x 可以插入一个条件,只有条件为真时才启用断点q 退出调试模式e 对表达式或者变量进行求值,可以查看变量的值它的原理是在函数各个可能的位置进行插桩,插入调试钩子。代码运行到此处时就会触发钩子进入调试状态。后面如果修改了问题,不想再进入该函数调试,需要将光标放到函数内部,执行 eval-defun 取消之前的插桩edebug-defun 只能用来调试函数内部的代码,一旦出了函数就无法继续调试了,并且也看不到调用栈。因为它插入的调试钩子只在函数内部,如果想看到调用栈可以使用 debug-on-entry。此时我们操作的是弹出来的调用栈面板。可以在面板中按 d 进行单步求值。它没有 edebug-defun 那么直观的显示当前执行到了哪行代码,我们只能根据源码和面板的输出来判断。所以它只适合用来判断函数是否被调用,以及调用的栈是怎样的。不适合用来调试具体的函数代码。通过 debug-on-entry 下的断点可以使用 cancel-debug-on-entry 来取消如果你不想进行调试,而是希望打印目标函数每一次被调用时传入的参数以及返回的结果, 不进入调试, 可以使用 trace-function. 我们通过一个具体的例子来看它的输出(defun my-complex-data-processor (raw-list) "一个用于演示 调试的数据处理函数。" (let ((processed '())) (dolist (item raw-list) (let ((transformed (if (numberp item) (* item 2) (upcase item)))) (push transformed processed))) (nreverse processed))) (let* ((arg (list 10 "hello world" ?=)) (ret (my-complex-data-processor arg))) (setq ret (my-complex-data-processor arg)) (message "%s" ret))trace-function 会输出如下内容:1 -> (my-complex-data-processor (10 "hello world" 61)) 1 <- my-complex-data-processor: (20 "HELLO WORLD" 122) ====================================================================== 1 -> (my-complex-data-processor (10 "hello world" 61)) 1 <- my-complex-data-processor: (20 "HELLO WORLD" 122)前面的1 表示调用的深度,此时它被顶层代码调用,所以深度是1;-> 和 <-表示方向,前者表示调用函数,后者表示从函数出来第一行表示, 从顶层调用函数,参数为 (10 "hello world" 61),它对应着上面的let赋值第二行表示, 函数返回,返回值为 (20 "HELLO WORLD" 122)第三行表示, 第二次函数调用,此时参数为 (10 "hello world" 61), 它对应着后面的 setq第四行表示, 第二次调用的函数返回,返回值为 (20 "HELLO WORLD" 122)取消插桩我们可以使用 untrace-function除了这几种方式,我们还可以手动在对应代码位置插入 (debug) ,这样代码会在断点处断下来,然后弹出调用栈的窗口,它的效果就与 debug-on-entry 类似总结本篇我们介绍了几种elisp的调试方法,主要有以下几种:edebug-defun 调试函数, 不用时需要使用 eval-defun 解除debug-on-entry 会在函数被调用时弹出调用栈,不用时需要使用 cancel-debug-on-entry 解除trace-function 打印对于函数调用的信息,不用时需要使用 untrace-function 解除
2026年10月29日
1 阅读
0 评论
0 点赞