在Emacs和SLIME中调试Common Lisp的有效方法是什么?

20

我想知道如何使用Emacs和SLIME以交互方式高效地调试Common Lisp代码。

之前我的做法:作为一个在VS和PyCharm中学习C和Python的人,我习惯于设置断点、添加监视器并进行单步调试。但是当我开始使用CL时,我发现调试工作流程根本不同。我没有找到好的方法来设置断点,逐行执行代码并查看变量如何变化。

我之前使用的笨拙方法是在代码中添加“print”语句,一遍又一遍地运行代码,这非常低效。我知道我们可以在SLIME中“inspect”变量,但不确定如何以交互方式进行。

我找到的:我最近看到了一个莫尔斯电码翻译器开发的视频,其中展示了如何在SLIME中进行交互式调试的完整过程,这对我非常有启发和帮助。就好像我们可以与编译器“交谈”一样。

我想要的:我在网上搜索,但很少找到演示有经验的Lisper们如何实际开发和调试程序的教程。我渴望学习这些经验。

  • 如何进行交互式调试?
  • 有哪些好的做法和技巧?如何设置断点和逐步执行?
  • 在调试时,您最频繁使用/发现最有用的快捷键/工具/工作流程是什么?

6
这是一篇有关Lisp调试的好博客系列文章。 - jkiiski
1
@jkiiski 这正是我想要的!非常感谢!你还遇到过其他类似的资源吗? - Jian Xu
1
我刚刚发现这本书《Common Lisp Recipes》对学习者非常有帮助:第16章是关于调试,第17章是关于优化的。 - Jian Xu
2个回答

14

以下是您可以采取的几种方法:

  • 您可以追踪函数调用(请参见Common Lisp中的TRACEUNTRACEslime-toggle-trace-fdefinition*)。这对于递归调用很有帮助:您可以看到每个级别传递了什么以及它们返回了什么。
  • 常规方法:在需要的地方添加(format t ...)。我想不需要注释。
  • 如果代码出错,您将进入调试器。从那里,您可以检查堆栈,查看调用了什么以及传递了什么参数。请参阅@jkiiski的链接:其中包括(break)表单,它将充当断点并将您带到调试器中。 剧透警告:您可以在检查器中更改值,可以更改和重新编译代码,并从堆栈中的(几乎)任何位置重新启动。
  • 最后但同样重要的是:要调试宏,您将需要slime-macroexpand-1MACROEXPAND-1的包装器),甚至更好的是使用宏步进器C-c M-e

最后一个建议:如果您要进行严格的调试,请在文件中包含(declaim (optimize (debug 3))),否则某些CL实现有一种倾向,会优化掉堆栈上的调用或使参数无法访问。


", 你将需要 slime-macroexpand-1(对 MACROEXPAND-1 的包装)以及更好的 C-c M-e 宏步进器。" - 能详细解释一下吗? - Philipp Ludwig

1
使用Common Lisp和Slime,您可以设置断点,查看变量的值,使用检查器查看包括类实例在内的复合数据结构,并逐步执行代码-原则上与像PyCharm这样的IDE非常相似。 Rainer Joswig的视频Debugging CL-HTTP,使用Clozure Common Lisp,GNU Emacs和SLIMEhttps://vimeo.com/77004324)演示了所有这些功能,因此您可以看到如何在Slime中实践完成。
实际上,在Common Lisp + Slime中,我特别喜欢的一个功能是,您可以正常运行程序,并直接进入调试器以处理错误,而调试器默认会在引发未捕获异常的位置停止。相比之下,使用PyCharm,您运行程序,遇到错误,然后再次使用调试器启动程序,并手动设置断点或要求PyCharm在任何异常处中断。 PyCharm目前不支持仅在未捕获异常处自动中断。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接