【问题标题】:How do I prevent slime from starting sldb on certain errors?如何防止粘液在某些错误上启动 sldb?
【发布时间】:2015-12-30 05:34:21
【问题描述】:

从连接了 Slime 的 Clack/Hunchentoot 提供大文件时,我有时会看到错误消息,例如 SB-IMPL::SIMPLE-STREAM-PERROR "Couldn't write to ~s"... 这些是由浏览器过早引起的断开连接(这完全可以)。问题是每次发生时,SLDB都会弹出。这很烦人。

有没有办法可以抑制 SLDB 中的某些错误,例如上述错误?我仍然希望在错误日志中看到它们,但绝对不是在 SLDB 中。

【问题讨论】:

    标签: emacs common-lisp sbcl slime hunchentoot


    【解决方案1】:

    您可以将PROCESS-CONNECTION 子类化为您的接受者,并对此错误进行自己的错误处理。

    让我们从定义一个自定义接受器开始:

    (defclass no-error-acceptor (hunchentoot:acceptor)
      ())
    

    然后我们可以围绕PROCESS-CONNECTION 创建一个包装器,以禁止打印针对此特定错误的消息:

    (defmethod hunchentoot:process-connection ((acceptor no-error-acceptor) (socket t))
      (handler-case
          (call-next-method)
        (sb-impl::simple-stream-perror (condition)
          ;; Perhaps log the error here?
          nil)))
    

    确保您确实使用此接受器启动服务器,以便使用它。

    【讨论】:

    • 谢谢。这绝对是一个好方法,但仍然:有没有办法在没有实际解决问题的情况下阻止 SLDB 启动?比如说,如果没有可用的源,就无法继承/覆盖或其他一些约束。只是好奇。
    • 您调用该函数以从某个地方启动 hunchentoot,如果您在该调用周围安装一个处理程序,它应该(我相信)处理发出的错误信号,并且只有未处理的错误才会触发调试器。
    • @Vatine - 不,这发生在另一个线程 => 在启动调用周围的处理程序之外。
    【解决方案2】:

    更新

    由于您的系统使用 Hunchentoot,您可以将全局变量 HUNCHENTOOT:*CATCH-ERRORS-P* 设置为 T。这应该保证 Hunchentoot 管理的代码中出现的所有条件都被 Hanchentoot 自己捕获,而不是传递给调试器。

    要在任何 Common Lisp 实现中禁用调试器(包括在 shell REPL 中以及在 Emacs 中的 Slime REPL),您可以使用预定义的全局变量 *debugger-hook*,通过为其分配两个参数函数。该函数在被调用时会接收到*debugger-hook*的条件和当前值,可以处理条件或者正常返回,此时调用调试器。例如,您可以简单地打印条件:

    * (defun my-debug(condition hook)
        (declare (ignore hook))
        (print condition)
        (abort))
    
    DEBUG-IGNORE
    * (setf *debugger-hook* #'my-debug)
    
    #<FUNCTION MY-DEBUG>
    

    但是,当将 Hunchentoot 与 Slime 一起使用时,第二种方法无法工作,因为这两个包在调试策略方面的交互方式。

    在这种情况下,可以采用solution found by Mike Ivanov,在启动 Swank 之前重新定义 swank-debugger-hook 函数:

    (in-package swank)
    
    (setq swank-debugger-hook-orig #'swank-debugger-hook)
    
    (defun swank-debugger-hook (condition hook)
      (etypecase condition
        (sb-int:simple-stream-error
          (progn
            (princ "*** Stream error" *error-output*)
            (abort)))
        (t (funcall swank-debugger-hook-orig condition hook))))
    
    (in-package cl-user)
    
    (swank:create-server :port 4008 :dont-close t)
    

    【讨论】:

    • 谢谢,但它实际上不适用于线程:CL-USER> debugger-hook => # 然后:CL-USER> (bordeaux-threads:make-thread (lambda () (princ debugger-hook))) => #
    • 可能是,通过使用 slime,swank 覆盖了 *debugger-hook* 的定义。我会看一下 slime 的文档。
    • 我认为可能有某种线程启动挂钩,粘液用于在新线程中设置调试器挂钩...
    • 在 slime 中有 sldb-hook "这个钩子在 SLDB 被调用后运行。钩子函数在初始化后从 SLDB 缓冲区中调用。一个示例使用是添加 sldb-print-condition到这个钩子,它使所有用 SLDB 调试的条件都记录在 REPL 缓冲区中。”。尝试改变这一点。
    • 文档是here
    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-08
    • 2018-07-11
    • 1970-01-01
    • 2011-01-30
    相关资源
    最近更新 更多