如何使Sly的回溯变得明智?

问题描述 投票:-1回答:1

[每当出现错误时,Sly都会显示重新启动和回溯。我见过互联网上的人,他们的回溯是可读的,这些回溯是明智的函数调用。当我在副本中输入(fun duf)时,我得到的是这样的内容:

Backtrace:
 0: ((LAMBDA ()))
 1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FUN DUF) #<NULL-LEXENV>)
 2: (EVAL (FUN DUF))
 3: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 4: (SLYNK::CALL-WITH-RETRY-RESTART "Retry SLY mREPL evaluation request." #<CLOSURE (LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1) {100308AA1B}>)
 5: ((LAMBDA NIL :IN SLYNK-MREPL::MREPL-EVAL-1))
 6: ((LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER))
 7: (SLYNK::CALL-WITH-BINDINGS ((*PACKAGE* . #<PACKAGE "COMMON-LISP-USER">) (* . 13) (** . 10) (***) (/ 13) (// 10) ...) #<CLOSURE (LAMBDA NIL :IN SLYNK::CALL-WITH-LISTENER) {100308A68B}>)
 8: (SLYNK-MREPL::MREPL-EVAL-1 #<SLYNK-MREPL::MREPL mrepl-2-2> "(fun duf)")
 9: (SLYNK-MREPL::MREPL-EVAL #<SLYNK-MREPL::MREPL mrepl-2-2> "(fun duf)")
...

还有更多。这使我无法调试代码。我尝试过:(declaim (optimize (debug 3))),但没有区别。同样,即使调用是一个实际函数,输出也不是更好。我已经尝试了gnuclisp和sbcl。

debugging emacs common-lisp slime
1个回答
0
投票

[我认为您认为您看到的很多东西都是垃圾,只是因为您还不知道它是什么。

  • 在第9和8行中,您将看到REPL正在使用这些功能来处理您的输入。如您所见,在此阶段,输入是一个字符串。
  • 在第7行中,在堆栈上放置了一些绑定,以便使用正确的包,并且将****绑定到最后的结果(REPL的便捷功能)。
  • 在第6行中,call-with-listener可能确定输出应该转到Sly。
  • 在第5行中,此匿名函数是闭包中包含的一个,已成为第6行的参数。换句话说,是实现细节。
  • 在第4行中,建立了retry重新启动。如果您在调试器中调用Retry重新启动,则将在此帧中转移控制权。
  • 在第3行中,您再次看到函数参数正在执行。请注意call-with-…命名约定。
  • 在第2行中,您看到的输入是read,即e。转换为Lisp数据结构。现在使用标准功能eval对其进行评估。
  • 在第1行中,您将看到SBCL在这种情况下是如何实现的-实现细节。
  • 在第0行,您看到一些匿名函数,同样是来自eval的实现。

这里没什么可看的,因为eval首先要做的是评估duf,这失败了。

计算机不知道您要调试的当前堆栈上下文的哪一部分。因此,它[[必须向您显示整个回溯,否则将使那些对他们感兴趣的信息被隐瞒的人们感到痛苦。

您需要学习的是识别您感兴趣的东西从哪里开始。在这里,所有Slynk的东西(显然是?)都在您的上下文之下,因此您实际上只需要查看零件,直到第一行eval。在这种情况下,这只是第一行,这很有意义,因为您输入的行只会在第一次查找时失败。对于Sly开发人员而言,那些较低的堆栈框架可能很有趣。

当然,在更现实的情况下,有些实现的回溯比其他实现更清晰。那不是Sly可以做的事情。它的作用是为您提供从回溯中的任何行跳至相应源文件位置(如果可用)的选项(在SLIME中为v(视图),不了解Sly)。您可以做很多事情,例如G。检查本地绑定/变量/参数,并调用重新启动。看看手册。

© www.soinside.com 2019 - 2024. All rights reserved.