用kill信号输入pdb

时间:2015-08-23 02:39:16

标签: python ipc pdb nohup interprocess

在最近的一个项目中,我想在生产使用状态下调试我的程序。生产环境非常复杂,所以我想在遇到问题时调试程序。

这就是我想要实现的:每当我想调试时,我都会向程序发送一个kill信号,希望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交互。

有什么类似的吗?

2 个答案:

答案 0 :(得分:2)

如果从终端运行程序,可以使用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。这样shell就不再竞争了 pdb用于来自tty的输入。例如,在一行:

kill -term $pid; sleep 99999

然后你将pdb连接到/ tmp / link,这是你的tty。当您退出pdb时,键入 ctrl-c 会停止睡眠。

如果你需要在pdb中使用 ctrl-c ,并且你正在使用bash, 将sleep 99999替换为suspend。退出pdb时,使用终端的菜单发送信号sigcont 到了暂停bash的过程。

答案 1 :(得分:0)

我认为一种完全不同的方法是使用rpyc,这种方法更简单,更优雅。我已经在我的复杂系统中使用这种方法很长一段时间了,它使得实时调试变得非常容易。

基本上,您需要做的是定义一个简单的rpyc API服务,其中包含" exposed"将引用(" netrefs")返回给系统中最有趣的对象的方法。然后,在启动时启动进程中的rpyc ThreadedServer

然后,只要您愿意,您就可以创建一个rpyc客户端,并连接到该进程,通过API检索对对象的引用,并检查它们(透明地,就像那些netref是本地对象一样)。使用正确的API方法,您几乎可以在实时流程中访问所需的任何

这个评价的其他优点是:(1)这个交互式会话甚至不会影响正在运行的过程(当然,除非你调用导致副作用的方法等),(2)它不必具有交互性,即您可以轻松编写连接到流程的脚本并从中打印一些信息。