4

设想:

有一个复杂的软件,手动启动很烦人。我所做的是创建一个 python 脚本来启动可执行文件并附加gdb进行调试。

进程启动脚本:

  • 确保设置了环境变量。
  • 确保将本地构建目录添加到环境LD_LIBRARY_PATH变量中。
  • 将当前工作目录更改为可执行文件期望的位置(不是我的设计)
  • 使用配置文件启动可执行文件是唯一的命令行选项
  • 将可执行文件的输出通过管道传输到第二个日志记录进程
  • 记住可执行文件的 PID,然后启动并将 gdb 附加到正在运行的可执行文件。

该脚本有效,但有一个警告。ctrl-c 不会中断被调试者并将控制权返回给 gdb。因此,如果我在没有活动断点的情况下“继续”,我将永远无法再次停止该进程,它必须被另一个 shell 杀死/中断。顺便说一句,运行“kill -s SIGINT <pid>”,其中 <pid> 是被调试者的 pid,确实让我回到了 gdb 的提示符......但是必须以这种方式做事真的很烦人

起初我以为 Python 正在抓取 SIGINT 信号,但情况似乎并非如此,因为我设置了信号处理程序将信号转发给被调试者,但这并不能解决问题。

我已经尝试了对 python 脚本的各种配置(调用 os.spawn* 而不是子进程等)。似乎无论我怎么做,如果 python 启动子进程,SIGINT (ctrl-c) 信号不要路由到 gdb 或子进程。

目前的思路

  • 这可能与被调试者和 gdb 需要一个单独的进程组 ID 相关......对此有任何信任吗?
  • SELinux 可能的错误?

信息:

  • 数据库 6.8
  • Python 2.5.2(Python 2.6.1 也存在问题)
  • SELinux 环境(向进程传递信号的错误?)

我考虑过的替代方案:

  • 设置一个 .gdbinit 文件来完成脚本所做的工作、环境变量和当前工作目录是这种方法的一个问题。
  • 手动启动可执行文件并附加 gdb (yuck)

问题: 您如何自动化大型项目的启动/调试?

更新: 我在下面尝试了 Nicholas Riley 的示例,在我家里的 Macintosh 上,它们都允许 cntl-c 以不同的程度工作,在生产 boxen(我现在相信它可能正在运行 SELinux)上它们不...

4

3 回答 3

3

您可以尝试忽略它,而不是将信号从 Python 转发给被调试者。以下对我有用:

import signal
signal.signal(signal.SIGINT, signal.SIG_IGN)

import subprocess
cat = subprocess.Popen(['cat'])
subprocess.call(['gdb', '--pid=%d' % cat.pid])

有了这个,我能够在 GDB 中重复 ^C 并毫无问题地中断被调试者,但是我确实看到了一些奇怪的行为。

顺便说一句,将信号转发到目标进程时我也没有问题。

import subprocess
cat = subprocess.Popen(['cat'])

import signal, os
signal.signal(signal.SIGINT,
              lambda signum, frame: os.kill(cat.pid, signum))

subprocess.call(['gdb', '--pid=%d' % cat.pid])

那么,也许您的情况还发生了其他事情?如果您发布了一些中断的代码,它可能会有所帮助。

于 2009-04-11T01:41:29.397 回答
0

您的评论指出您正在使用腻子...您有控制 tty 吗?使用 openssh 您可能想要添加 -T 选项,我不知道腻子如何/是否会按照您使用它的方式执行此操作。

另外:您可以尝试使用 cygwin 的 ssh 而不是 putty。

于 2009-04-15T02:52:24.043 回答
0

如果您已经设置了一个当前脚本来执行此操作,但在自动化其中的一部分时遇到问题,也许您可​​以抓住 expect 并使用它来提供设置,然后回到交互模式以启动该过程。然后你仍然可以让你的 ctrl-c 可以中断。

于 2009-04-15T21:05:18.487 回答