【问题标题】:How can I retrospectively debug a python exception如何追溯调试 python 异常
【发布时间】:2011-05-16 09:08:56
【问题描述】:

我正在寻找一种“追溯”调试 python 异常的方法。本质上,如果我的程序引发了未处理的异常,我希望它保存程序状态,以便稍后返回并调试问题。

我查看了 pdb 文档,您似乎可以这样做,但前提是您可以在异常点与程序进行交互。这对我不起作用,因为程序将在后台运行(没有控制终端)。

我的第一个(注定失败!)方法是在我的程序的最高级别放置一个 try/except 块,并在 except 块中从当前异常中提取回溯对象并使用 pickle 将其写入磁盘。然后我计划编写一个单独的程序来解开对象并使用 pdb.post_mortem 来调试崩溃的程序。但是回溯对象不是可腌制的,但我不希望它能够正常工作,因为它不会保存整个程序状态。

【问题讨论】:

  • 这并不能以任何方式解决您的问题,但与其将整个程序包装在 try 语句中,不如通过将其分配给 sys.excepthook 来为未捕获的异常设置处理程序可能会更好.

标签: python debugging


【解决方案1】:

据我所知,没有任何方法可以满足您的要求。也就是说,听起来您可能正在寻找远程调试器。有两种选择:

  • rconsole - 这不是真正的调试器,但它允许您在另一个进程中获得交互式提示。这对于调试目的很有用。这个我没试过,但是看起来比较简单。
  • rpdb2's embedded debugger - 这让您可以启动调试器,然后从另一个 shell 连接到它。

【讨论】:

  • 谢谢,我会调查的。
【解决方案2】:

您可以做的是使用 twisted.python 并将回溯写入文件,它会为您提供准确的回溯,包括异常

【讨论】:

  • 还有traceback 模块。但我认为这不是 OP 想要的。
  • 我不确定这是否符合我的要求。当异常被捕获时,我可以将回溯转储到文件中,但我真正想要的是一种事后交互式调试程序的方法(就像你用 gdb 调试核心文件一样)。
【解决方案3】:

在捕获到异常的那一刻,在堆栈展开之前,状态可以通过检查模块进行检查:http://docs.python.org/2/library/inspect.html

通常你会在你的回溯对象上使用inspect.getinnerframes。每个堆栈帧中的局部变量都以 .f_locals 的形式提供,因此您可以看到它们是什么。

困难的部分是正确地序列化所有它们:取决于您在本地范围内拥有的类型,您可能会或可能无法腌制它们,将它们转储到 JSON 或其他方式。

【讨论】:

    【解决方案4】:

    您可以在顶层创建一个完全独立的执行环境:

    myEnv = {}
    myEnv.update(globals)
    

    然后在该执行环境中执行您的代码。如果发生异常,您将拥有回溯(堆栈)和所有全局变量,因此您可以很好地重建程序状态。

    【讨论】:

      【解决方案5】:

      我希望这会有所帮助(它帮助了我):

      import logging, traceback
      _logger = logging.getLogger(__name__)
      
      try:
          something_bad()
      except Exception as error:
          _logger.exception("Oh no!") # Logs original traceback
          store_exception_somewhere(error)
      

      另外,in Python 3 there are a few new options 喜欢 raise new_exc from original_exc raise OtherException(...).with_traceback(tb)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-09
        • 1970-01-01
        • 2019-02-15
        • 2013-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多