I have a Python application in a strange state. I don't want to do live debugging of the process. Can I dump it to a file and examine its state later? I know I've restored corefiles of C programs in gdb later, but I don't know how to examine a Python application in a useful way from gdb.
我有一个处于奇怪状态的Python应用程序。我不想做这个过程的实时调试。我可以将其转储到文件中并稍后检查其状态吗?我知道我以后在gdb中恢复了C程序的核心文件,但我不知道如何从gdb以有用的方式检查Python应用程序。
(This is a variation on my question about debugging memleaks in a production system.)
(这是关于在生产系统中调试memleaks的问题的变体。)
4 个解决方案
#1
4
There is no builtin way other than aborting (with os.abort(), causing the coredump if resource limits allow it) -- although you can certainly build your own 'dump' function that dumps relevant information about the data you care about. There are no ready-made tools for it.
除了中止之外没有内置的方法(使用os.abort(),如果资源限制允许,则导致coredump) - 尽管你当然可以建立自己的'dump'函数来转储关于你关心的数据的相关信息。没有现成的工具。
As for handling the corefile of a Python process, the Python source has a gdbinit file that contains useful macros. It's still a lot more painful than somehow getting into the process itself (with pdb or the interactive interpreter) but it makes life a little easier.
至于处理Python进程的核心文件,Python源代码包含一个包含有用宏的gdbinit文件。它仍然比以某种方式进入流程本身(使用pdb或交互式解释器)更痛苦,但它使生活更容易一些。
#2
1
Someone above said that there is no builtin way to perform this, but that's not entirely true. For an example, you could take a look at the pylons debugging tools. Whene there is an exception, the exception handler saves the stack trace and prints a URL on the console that can be used to retrieve the debugging session over HTTP.
上面有人说没有内置的方法来执行此操作,但这并非完全正确。例如,您可以查看pylons调试工具。如果存在异常,则异常处理程序会保存堆栈跟踪并在控制台上输出可用于通过HTTP检索调试会话的URL。
While they're probably keeping these sessions in memory, they're just python objects, so there's nothing to stop you from pickling a stack dump and restoring it later for inspection. It would mean some changes to the app, but it should be possible...
虽然他们可能会将这些会话保存在内存中,但它们只是python对象,所以没有什么可以阻止你腌制堆栈转储并在以后恢复以进行检查。这将意味着应用程序的一些变化,但它应该是可能的......
After some research, it turns out the relevant code is actually coming from Paste's EvalException module. You should be able to look there to figure out what you need.
经过一些研究,结果证明相关代码实际上来自Paste的EvalException模块。你应该能够在那里找出你需要的东西。
#3
0
This answer suggests making your program core dump and then continuing execution on another sufficiently similar box.
这个答案建议让你的程序核心转储,然后继续执行另一个足够相似的盒子。
#4
0
It's also possible to write something that would dump all the data from the process, e.g.
也可以编写一些可以转储进程中所有数据的东西,例如:
- Pickler that ignores the objects it can't pickle (replacing them with something else) (e.g. Python: Pickling a dict with some unpicklable items)
- Method that recursively converts everything into serializable stuff (e.g. this, except it needs a check for infinitely recursing objects and do something with those; also it could try
dir()
andgetattr()
to process some of the unknown objects, e.g. extension classes).
Pickler忽略了它无法腌制的对象(用其他东西替换它们)(例如Python:用一些不可剔除的物品腌制一个字典)
递归地将所有内容转换为可序列化的东西的方法(例如,除了它需要检查无限递归对象并对其执行某些操作;还可以尝试使用dir()和getattr()来处理一些未知对象,例如扩展类) 。
But leaving a running process with manhole or pylons or something like that certainly seems more convenient when possible.
但是,如果可能的话,留下带有沙井或挂架或类似东西的运行过程肯定会更方便。
(also, I wonder if something more convenient was written since this question was first asked)
(另外,我想知道自从这个问题被问到以来是否更方便了)
#1
4
There is no builtin way other than aborting (with os.abort(), causing the coredump if resource limits allow it) -- although you can certainly build your own 'dump' function that dumps relevant information about the data you care about. There are no ready-made tools for it.
除了中止之外没有内置的方法(使用os.abort(),如果资源限制允许,则导致coredump) - 尽管你当然可以建立自己的'dump'函数来转储关于你关心的数据的相关信息。没有现成的工具。
As for handling the corefile of a Python process, the Python source has a gdbinit file that contains useful macros. It's still a lot more painful than somehow getting into the process itself (with pdb or the interactive interpreter) but it makes life a little easier.
至于处理Python进程的核心文件,Python源代码包含一个包含有用宏的gdbinit文件。它仍然比以某种方式进入流程本身(使用pdb或交互式解释器)更痛苦,但它使生活更容易一些。
#2
1
Someone above said that there is no builtin way to perform this, but that's not entirely true. For an example, you could take a look at the pylons debugging tools. Whene there is an exception, the exception handler saves the stack trace and prints a URL on the console that can be used to retrieve the debugging session over HTTP.
上面有人说没有内置的方法来执行此操作,但这并非完全正确。例如,您可以查看pylons调试工具。如果存在异常,则异常处理程序会保存堆栈跟踪并在控制台上输出可用于通过HTTP检索调试会话的URL。
While they're probably keeping these sessions in memory, they're just python objects, so there's nothing to stop you from pickling a stack dump and restoring it later for inspection. It would mean some changes to the app, but it should be possible...
虽然他们可能会将这些会话保存在内存中,但它们只是python对象,所以没有什么可以阻止你腌制堆栈转储并在以后恢复以进行检查。这将意味着应用程序的一些变化,但它应该是可能的......
After some research, it turns out the relevant code is actually coming from Paste's EvalException module. You should be able to look there to figure out what you need.
经过一些研究,结果证明相关代码实际上来自Paste的EvalException模块。你应该能够在那里找出你需要的东西。
#3
0
This answer suggests making your program core dump and then continuing execution on another sufficiently similar box.
这个答案建议让你的程序核心转储,然后继续执行另一个足够相似的盒子。
#4
0
It's also possible to write something that would dump all the data from the process, e.g.
也可以编写一些可以转储进程中所有数据的东西,例如:
- Pickler that ignores the objects it can't pickle (replacing them with something else) (e.g. Python: Pickling a dict with some unpicklable items)
- Method that recursively converts everything into serializable stuff (e.g. this, except it needs a check for infinitely recursing objects and do something with those; also it could try
dir()
andgetattr()
to process some of the unknown objects, e.g. extension classes).
Pickler忽略了它无法腌制的对象(用其他东西替换它们)(例如Python:用一些不可剔除的物品腌制一个字典)
递归地将所有内容转换为可序列化的东西的方法(例如,除了它需要检查无限递归对象并对其执行某些操作;还可以尝试使用dir()和getattr()来处理一些未知对象,例如扩展类) 。
But leaving a running process with manhole or pylons or something like that certainly seems more convenient when possible.
但是,如果可能的话,留下带有沙井或挂架或类似东西的运行过程肯定会更方便。
(also, I wonder if something more convenient was written since this question was first asked)
(另外,我想知道自从这个问题被问到以来是否更方便了)