输入带有终止信号的 pdb
Posted
技术标签:
【中文标题】输入带有终止信号的 pdb【英文标题】:enter pdb with kill signal 【发布时间】:2015-08-23 02:39:16 【问题描述】:在最近的一个项目中,我想在生产使用状态下调试我的程序。生产环境很复杂,遇到问题就想调试一下。
这就是我想要实现的:每当我想调试时,我都会向程序发送一个终止信号,希望 pdb 调试器会出现。是这样的:
import pdb
import signal
import time
def handler(signal, frame):
pdb.set_trace()
signal.signal(signal.SIGTERM, handler)
a=1
while True:
a+=1
time.sleep(1)
但是,由于我必须使用nohup
运行程序,所有输出都将重定向到 nohup.out,所以我无法与 pdb 交互。
有没有类似的方法?
【问题讨论】:
【参考方案1】:如果您从终端运行程序,您可以使用tty
命令来记下
tty 设备,并将其传递给环境中的程序:
TTY=`tty` nohup ./myprog.py
然后在处理程序中再次打开 tty 并将 stdin 和 stdout 设置为文件:
import sys,os
def handler(signal, frame):
tty = os.getenv('TTY')
sys.stdin = sys.stdout = open(tty,"r+")
pdb.set_trace()
如果您在评论中将程序与当前 tty 分离,那么您 可以尝试类似的东西,使用相同的 python 代码。这次运行你的程序:
TTY=/tmp/link nohup ./myprog.py &
然后关闭终端。打开一个新终端并创建这个新 tty 的缺失链接:
ln -s `tty` /tmp/link
然后在一行中给出 kill 命令以向 python 进程发出信号,然后
然后立即执行sleep
。这样外壳就不再与
pdb 用于来自 tty 的输入。例如,在一行上:
kill -term $pid; sleep 99999
然后您将让 pdb 连接到 /tmp/link,这是您的 tty。当你退出 pdb 时,输入 ctrl-c 将停止睡眠。
如果你需要在pdb中使用ctrl-c,并且你使用的是bash,
将sleep 99999
替换为suspend
。退出 pdb 时,使用终端的菜单发送信号 sigcont
到进程来取回暂停的 bash。
【讨论】:
我必须使用nohup python myprog.py &
来运行程序。当我杀死进程时,它似乎没有正确进入pdb:wangc@lion:~/workspace/temp> kill 2684 wangc@lion:~/workspace/temp> --Return-- > /home/wangc/workspace/temp/wwtest.py(10)handler()->None -> pdb.set_trace()
您有 2 个进程争夺终端。对于此示例,您不能使用“&”将 python 作为背景。从另一个终端杀死。
哦,我必须关闭原来的终端,因为我正在使用来自 windows 的 ssh。我不能让 ssh 程序永远打开。
我添加了关闭原始终端的解决方案。
你打开终端运行 shell,然后我们告诉另一个进程 pdb 也使用终端。他们都会从 tty 进行读取,并且将随机获取您键入的字符。因此,我们需要让 shell 停止读取,这样只有 pdb 的读取才会成功。 sleep 是一种简单的方法,因为 sleep 不做任何阅读或写作。【参考方案2】:
我认为更简单、更优雅的一种完全不同的方法是使用rpyc
。我已经在我的复杂系统中使用这种方法很长时间了,它使实时调试变得非常容易。
基本上,您需要做的是定义一个简单的 rpyc API 服务,其中包含“公开的”方法来返回对您系统中最有趣的对象的引用(“netrefs”)。然后,在启动时在进程中启动一个 rpyc ThreadedServer。
然后,只要您愿意,您就可以简单地创建一个 rpyc 客户端,并连接到进程,通过 API 检索对对象的引用,并检查它们(透明地,就好像那些 netrefs 是本地对象一样)。使用正确的 API 方法,您几乎可以在实时过程中访问任何内容。
此方法的其他优点是(1)此交互式会话甚至不必影响正在运行的进程(当然,除非您调用会导致副作用等的方法),(2)它不会不必是交互式的,即您可以轻松编写一个连接到进程并从中打印一些信息的脚本。
【讨论】:
以上是关于输入带有终止信号的 pdb的主要内容,如果未能解决你的问题,请参考以下文章
如何在 QTableView 中发出输入单元格和离开单元格的信号