7

我用 Common Lisp 开发已经快一年了,这真的开始让我感到不安。我开始使用 CLISP 编写 CL,但后来为了速度我切换到 SBCL。我做了很多相当低级的事情,所以我需要与很多 C 代码交互。我真的很喜欢 CL 的增量开发方面(但是我不使用 Emacs - 我在 Vim 中运行 SLIMV),但我发现自己的开发速度比在 Python、Perl、C 甚至 NASM 中的开发速度要慢。问题的根源在于 SBCL 的错误消息。我曾经被迫搜索近 500 行代码,因为 SBCL 决定给我一个ERROR: Invalid number of arguments on foreign function #< some memory address >. 没有指定调用什么函数,没有行号,什么都没有。最近,我很高兴得到The loaded code expects an incompatible layout for class SB-PRETTY:PRETTY-STREAM.随机。该代码在 CLISP 上运行良好,但在 SBCL 上出现模糊错误而失败。有什么方法可以使这些消息更具信息性吗?我写 C 和汇编已经快 6 年了,甚至他们会给你一个行号。我见过的唯一合理的 SBCL 错误是阅读器错误,它们几乎没有用,因为它们通常等于缺少括号。同样,是否有任何声明/命令行开关可用于更改此设置?在这一点上,我什至可以编写自己的错误打印机。

编辑:一个例子,(sb-ext:restrict-compiler-policy 'debug 3)在我的 ~/.sbclrc 中(使用 --load 而不是 --script 所以 .sbclrc 被加载)

debugger invoked on a SB-INT:SIMPLE-PROGRAM-ERROR in thread
#<THREAD "main thread" RUNNING {AB09931}>:
  invalid number of arguments: 0

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-KERNEL::INVALID-ARG-COUNT-ERROR-HANDLER
 #<unavailable argument>
 #.(SB-SYS:INT-SAP #XB78CDAE0)
 #<SB-ALIEN-INTERNALS:ALIEN-VALUE :SAP #XB78CD7DC :TYPE (*
                                                         (STRUCT
                                                          SB-VM::OS-CONTEXT-T-STRUCT))>
 (79))
0] print
(SB-KERNEL::INVALID-ARG-COUNT-ERROR-HANDLER
    #<unavailable argument>
    #.(SB-SYS:INT-SAP #XB78CDAE0)
    #<SB-ALIEN-INTERNALS:ALIEN-VALUE :SAP #XB78CD7DC :TYPE (*
                                                            (STRUCT
                                                             SB-VM::OS-CONTEXT-T-STRUCT))>
    (79))
0] down
(SB-KERNEL:INTERNAL-ERROR
    #.(SB-SYS:INT-SAP #XB78CD7DC)
    #<unavailable argument>)
1] down
("foreign function: #x805FCBB")
2] down

Bottom of stack.

不完全提供信息。

4

5 回答 5

4

我想你正在寻找:(sb-ext:restrict-compiler-policy 'debug 3)

您可以将它放入您~/.sbclrc的 REPL 或 REPL 中,SBCL 的调试器(尤其是在 SLIME 中)将产生更有用的结果。

于 2012-12-23T18:49:51.243 回答
4

这是“自定义”构建脚本的发行版的常见问题;Arch Linux 是一个常犯。从 sbcl.org 安装二进制文件是最可靠的方法。如果一个人想要最新最好的,那么从源代码构建是相当容易的。

于 2013-05-23T13:54:07.097 回答
2

我最近学到的另一件事,这可能对您的情况有用:

  1. 确保以足够的调试级别编译所有内容。
  2. 将您怀疑的代码包装成(step ...)表格。从那里您可以跟踪重新启动,您会发现它与 GDB 和其他步进调试器非常相似(您可以从那里步进、步进、步进和步进计数)。如果你完全不知道它来自哪里,那么获得你需要的函数可能有点乏味,但如果你将它用作一种方法,并测试更小的代码片段,它会有所帮助。

更多信息:http ://www.sbcl.org/manual/#Single-Stepping

于 2012-12-23T20:19:11.880 回答
2

我迟到了将近 7 年,但我会添加一些有用的建议。在厌倦了看到粘液中的错误并且只知道它们在什么函数中,但没有行号或任何东西之后,我发现了这个堆栈溢出问题。这并没有太大帮助,所以我终于阅读了粘液手册。https://common-lisp.net/project/slime/#documentation

不确定它是否会对原始海报有所帮助,但是当弹出错误并且您在 slime 调试器中时,点击“v”(在 emacs 中,不确定 vim)将向您显示引发错误的源代码. 您还可以向下浏览到堆栈跟踪中的其他条目并点击“v”。

在调试部分的粘液手册中还有其他有用的提示。能够在错误起源的同一堆栈帧中评估表达式真的很好。

于 2019-09-23T02:33:46.340 回答
1

如果您遇到运行时错误(我怀疑invalid number of arguments属于该类别),您应该进入调试器(除非您已明确禁用它)并且回溯可能会向您显示调用的确切位置.

loaded code expects a different layout...表示您正在查看两段编译后的代码,在不同的时间点编译,或者代码过于深入地挂钩到内部。首先,强制重新编译所有代码并查看警告是否消失。

于 2012-12-23T18:45:39.353 回答