输入带有终止信号的 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的主要内容,如果未能解决你的问题,请参考以下文章

调试程序方法pdb

如何通过sqlplus登陆PDB数据库

如何在 QTableView 中发出输入单元格和离开单元格的信号

VHDL:当涉及时钟信号时,多路复用器输出不跟随输入

Qt waitforbyteswritten() 函数中的信号

10.21 作业控制信号