如何在SBCL中显示错误的行号和源文件? [英] How do I show the line number and source file of an error in SBCL?

查看:58
本文介绍了如何在SBCL中显示错误的行号和源文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的〜/.sbclrc 看起来像这样:

(sb-ext:restrict-compiler-policy 'debug 3)

(setf *debugger-hook* #'(lambda (condition original-hook)
                          (declare (ignore original-hook))
                          (print-backtrace)
                          (format *error-output* "~%~A~%" condition)
                          (finish-output *error-output*)
                          (abort)))

假设我有一个包含错误功能的程序 my-program.lisp :

Suppose I have a program my-program.lisp containing a bad function:

;; ...
(defun calculate (x)
  (/ x 0))
;; ...

如果我跑步:

$ sbcl --load my-program.lisp
* (calculate 100)

我收到此错误:

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005E85B3}>
0: (SB-KERNEL::INTEGER-/-INTEGER 100 0)
1: (CALCULATE 100)
2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (CALCULATE 100) #<NULL-LEXENV>)
3: (EVAL (CALCULATE 100))
4: (INTERACTIVE-EVAL (CALCULATE 100) :EVAL NIL)
5: (SB-IMPL::REPL-FUN NIL)
6: ((LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL))
7: (SB-IMPL::%WITH-REBOUND-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-IMPL::TOPLEVEL-REPL) {10046268FB}>)
8: (SB-IMPL::TOPLEVEL-REPL NIL)
9: (SB-IMPL::TOPLEVEL-INIT)
10: ((FLET SB-UNIX::BODY :IN SAVE-LISP-AND-DIE))
11: ((FLET "WITHOUT-INTERRUPTS-BODY-36" :IN SAVE-LISP-AND-DIE))
12: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))

arithmetic error DIVISION-BY-ZERO signalled
Operation was (/ 100 0).

但是运行时错误的行号和源文件在哪里?想象一下,如果我有数百个文件和数千个功能.知道错误的文件,行号和列号是否会有所帮助?如何显示错误的行号和源文件?

But where is the line number and the source file of the runtime error? Imagine if I have hundreds of files, and thousands of functions. Wouldn't it be helpful to know the file, the line number, and the column number of the error? How do I show the line number and source file of the error?

令我惊讶的是,当几乎所有其他解释器和编译器都能够轻松做到这一点时,该编程语言默认情况下就没有此功能.

I am surprised that this programming language does not have this feature by default when just about all other interpreters and compilers are able to do this easily.

推荐答案

通过Slime(或Sly)进行工作即可立即使用此功能,但实际上这是可行的,因为底层环境已经存储了足够的信息.如果您查看代码的实现方式(通过在Emacs中使用 M-. 进行导航,则可以看到在SBCL中,源代码位置部分取决于 sb-introspect .

Working from Slime (or Sly) gives this feature out of the box, but in fact this is made possible because the underlying environment already stores enough information. If you look at how the code is implemented (by navigating with M-. in Emacs, you can see that in SBCL, source code location depends partly from sb-introspect.

在您的示例中,加载包含 calculate 的文件后,如果您 require 此模块,则如下所示:

In your example, after loading the file that contains calculate, if you require this module, as follows:

* (require 'sb-introspect)
("SB-INTROSPECT")

您可以通过调用 find-definition-source 查找所有相关信息:

You can find all the relevant information by calling find-definition-source:

* (sb-introspect:find-definition-source #'calculate)
#S(SB-INTROSPECT:DEFINITION-SOURCE
   :PATHNAME #P"/tmp/mp.lisp"
   :FORM-PATH (2)
   :FORM-NUMBER 0
   :CHARACTER-OFFSET 51
   :FILE-WRITE-DATE 3817139822
   :PLIST NIL
   :DESCRIPTION NIL)

除文件外,SBCL还将位置存储为字符偏移量,还存储该文件中的表格数量(因此,如果在文件前面添加空格或注释,即使在文件已修改).

In addition to the file, SBCL also stores the location as character offsets, but also the number of forms in that file (so if you add whitespaces or comments in front of it, the editor can still find it location even after the file is modified).

回溯打印机功能还具有更多或更少信息的选项.

The backtrace printer function also have options to have more or less information.

这篇关于如何在SBCL中显示错误的行号和源文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆