我一直在使用Python程序,这些程序需要几个小时才能完成,但偶尔会崩溃。为了调试,到目前为止,我一直在添加条件断点,每当出现问题时,这些断点都会让我进入PDB会话。这很好,因为很难确定问题的确切原因,而且交互式会话可以让我探索整个程序(包括所有堆栈帧等等(。
唯一的问题是,如果我不小心关闭或破坏了调试会话,我需要重新启动整个程序!到达断点需要几个小时!我真的非常,真的喜欢序列化PDB会话并多次重新打开它的方式。像这样的东西存在吗?我已经研究了dill来序列化解释器会话,不幸的是,我的一些类型无法序列化(它也不适合后续的代码更改(。谢谢
您还没有指定您选择的操作系统,但在linux世界中有一个criu实用程序-https://criu.org/Main_Page,可用于保存应用程序状态。现在有很多陷阱,尤其是基于tty的应用程序(请参阅https://criu.org/Advanced_usage#Shell_jobs_C.2FR)但这里有一个例子。
-
我得到了一个带有pdb调试点的简单python应用程序,让我们称之为
app.py
:print("hello") import pdb; pdb.set_trace() print("world")
-
使用
python app.py
运行此应用程序后,您将获得预期的hello > /home/user/app.py(3)<module>() -> print("world")
-
用
pgrep -f app.py
获取你的pid,在我的情况下是17060 -
创建一个文件夹来转储您的流程
mkdir /tmp/criu
-
使用转储您的流程
sudo criu dump -D /tmp/criu -t 17060 --shell-job
请注意,您当前的进程将被终止(AFAIK由于--shell作业密钥,请参阅上面的链接(。你会看到
(Pdb) [1] 17060 killed python app.py
在你的tty 中
-
使用恢复您的流程
sudo criu restore -D /tmp/criu --shell-job
您的tty将在使用此命令的同一窗口中恢复。
-
由于附加了调试器,您可以键入
c
并输入以查看它是否真的工作。这是我的机器上的结果:(Pdb) c world
希望这有帮助,有很多陷阱可能会使这种方法对你来说不可行。
另一种方法是每次在VM、快照磁盘和内存中运行代码。从资源角度来看,这可能不是最好的解决方案,但许多管理程序都有一个很好的UI,甚至可以使用shell实用程序来控制虚拟机的状态。快照技术现在在任何系统管理程序中都很成熟,你不应该遇到任何问题。设置远程调试,并在恢复快照后连接到您喜爱的IDE。
编辑:如果你在容器中运行应用程序,并且你的操作系统支持podman和criu 3.11+,也有一种简单的方法可以做到这一点
https://criu.org/Podman
你可以使用类似的东西
podman run -d --name your_container_name your_image
使用进行快照
podman container checkpoint your_container_id
要恢复,请使用
podman container restore your_container_id
所有这些命令都需要root权限。不幸的是,我没能测试它,因为我的发行版提供了criu3.8,而podman3.11是必需的。
Docker中提供了与实验标志相同的功能,请参阅https://criu.org/Docker