简体   繁体   English

我怎样才能追溯调试python异常

[英]How can I retrospectively debug a python exception

I'm looking for a way to debug a python exception "retrospectively". 我正在寻找一种方法来“回顾性地”调试python异常。 Essentially if my program raises an exception that isn't handled, I want it to save off the program state so I can go back later and debug the problem. 基本上,如果我的程序引发了一个未处理的异常,我希望它能够保存程序状态,以便我可以稍后返回并调试问题。

I've taken a look at the pdb docs, and it seems that you can do this, but only if you can interact with the program at the point of the exception. 我已经看了一下pdb文档,看起来你可以这样做,但前提是你可以在异常时与程序进行交互。 This won't work for me as the program will be run in the background (without a controlling terminal). 这对我不起作用,因为程序将在后台运行(没有控制终端)。

My first (doomed!) approach was to put a try/except block at the highest level of my program, and in the except block extract the traceback object from the current exception and write it to disk using pickle. 我的第一个(注定要做的)方法是在程序的最高级别放置一个try / except块,在except块中从当前异常中提取traceback对象并使用pickle将其写入磁盘。 I planned to then write a separate program that would unpickle the object and use pdb.post_mortem to debug the crashed program. 我打算然后编写一个单独的程序来解开对象并使用pdb.post_mortem来调试崩溃的程序。 But traceback objects aren't pickleable, but I wouldn't expect that to work anyway, as it wouldn't save off the entire program state. 但是追溯对象不是可选择的,但我不希望它仍然可以工作,因为它不会挽救整个程序状态。

As far as I know, there isn't any way to do what you're asking. 据我所知,没有办法做你所要求的。 That said, it sounds like you might be looking for a remote debugger. 也就是说,听起来你可能正在寻找一个远程调试器。 There are a couple of options: 有几种选择:

  • rconsole - This isn't really a debugger, but it allows you to get an interactive prompt inside another process. rconsole - 这不是一个真正的调试器,但它允许您在另一个进程内获得交互式提示。 This can be useful for debugging purposes. 这对于调试目的很有用。 I haven't tried this, but it looks relatively straightforward. 我没试过这个,但看起来相对简单。
  • rpdb2's embedded debugger - This lets you start a debugger and then connect to it from another shell. rpdb2的嵌入式调试器 - 这使您可以启动调试器,然后从另一个shell连接到它。

At the moment the exception is caught, before the stack is unwound, the state is available for inspection with the inspect module: http://docs.python.org/2/library/inspect.html 在捕获异常时,在堆栈展开之前,可以使用inspect模块检查状态: http//docs.python.org/2/library/inspect.html

Generically you would use inspect.getinnerframes on your traceback object. 通常,您将在traceback对象上使用inspect.getinnerframes。 The local variables in each stack frame are available as .f_locals so you can see what they are. 每个堆栈帧中的局部变量都以.f_locals形式提供,因此您可以看到它们是什么。

The hard part is serializing all of them correctly: depending on what types you have in the local scope you may or may not be able to pickle them, dump them to JSON, or whatever. 困难的部分是正确地序列化所有这些:根据您在本地范围内的类型,您可能或可能无法腌制它们,将它们转储到JSON,或其他任何东西。

I hope this helps (it helped me): 我希望这有帮助(它帮助了我):

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)

Also, in Python 3 there are a few new options like raise new_exc from original_exc or raise OtherException(...).with_traceback(tb) . 此外, 在Python 3中有一些新选项,raise new_exc from original_exc raise OtherException(...).with_traceback(tb)或者raise OtherException(...).with_traceback(tb)

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

Well, as far as I know there is no easy solution to this problem. 好吧,据我所知,这个问题没有简单的解决办法。 You might want to try this approach: How do I find what is using memory in a Python process in a production system? 您可能想尝试这种方法: 如何在生产系统中找到Python进程中使用内存的内容?

You could create an entirely separate execution environment in the top level: 您可以在顶级创建一个完全独立的执行环境:

myEnv = {}
myEnv.update(globals)

Then execute your code within that execution environment. 然后在该执行环境中执行您的代码。 If an exception occurs you have the traceback (stack) and all the globals, so you can pretty well reconstruct the program state. 如果发生异常,则会有traceback(堆栈)和所有全局变量,因此您可以很好地重建程序状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM