以多种方式控制子进程(特别是gdb)

时间:2012-04-05 03:04:24

标签: python subprocess popen

我正在使用python开发一个围绕gdb的包装器。基本上,我只是希望能够预先检测到一些设置烦恼并且能够运行单个命令来调用gdb,而不是每次都要记住的巨大字符串。

那就是说,我正在使用两种情况。第一个工作正常,是通过创建一个新进程并附加到它来调用gdb。这是我对这个代码的代码:

def spawnNewProcessInGDB():
    global gObjDir, gGDBProcess;
    from subprocess import Popen
    from os.path import join
    import subprocess
    binLoc = join(gObjDir, 'dist');
    binLoc = join(binLoc, 'bin');
    binLoc = join(binLoc, 'mycommand')

    profileDir = join(gObjDir, '..')
    profileDir = join(profileDir, 'trash-profile')

    try:
        gGDBProcess = Popen(['gdb', '--args', binLoc, '-profile', profileDir], cwd=gObjDir)
        gGDBProcess.wait()
    except KeyboardInterrupt:
        # Send a termination signal to the GDB process, if it's running
        promptAndTerminate(gGDBProcess)

现在,如果用户在运行时按CTRL-C,它会中断(即它将CTRL-C转发到GDB)。这是我想要的行为。

第二种情况有点复杂。可能是因为我已经在我的系统上运行了这个程序并且它崩溃了,但是被抓住了。在这种情况下,我希望能够使用gdb连接到它以获取堆栈跟踪(或者我可能已经在运行它,我现在只想连接到已经在内存中的进程)。

作为一个方便的功能,我创建了一个镜像函数,它将使用gdb连接到正在运行的进程:

def connectToProcess(procNum):
    global gObjDir, gGDBProcess
    from subprocess import Popen
    import subprocess
    import signal

    print("Connecting to mycommand process number " + str(procNum) + "...")

    try:
        gGDBProcess = Popen(['gdb', '-p', procNum], cwd=gObjDir)
        gGDBProcess.wait()
    except KeyboardInterrupt:
            promptAndTerminate(gGDBProcess)

同样,这似乎按预期工作。它启动gdb,我可以设置断点,运行程序等。唯一的问题是,如果我在程序运行时按下它,它不会将CTRL-C转发给gdb。相反,它会立即跳转到promptAndTerminate()

我想知道是否有人能看出为什么会发生这种情况 - 对subprocess.Popen()的两次调用看起来与我相同,尽管一个人在不同模式下运行gdb。

我还尝试使用以下内容替换subprocess.Popen()的调用:

gGDBProcess = Popen(['gdb', '-p', procNum], cwd=gObjDir, stdin=subprocess.PIPE)

但是这也会导致不良结果,因为它实际上并没有向子gdb进程传递任何内容(例如,如果我在从gdb连接中断后它再次运行,则会输入c来启动程序,它没有做任何事情)。同样,当我输入CTRL-C时,它会终止正在运行的python进程。

任何帮助将不胜感激!

0 个答案:

没有答案