将GDB作为具有完全用户交互作用的进程运行

问题描述 投票:0回答:1

我正在尝试创建一个简单的python程序,该程序调用gdb进程并允许用户与gdb进行双向交互。首先,我做了这样的事情:

import subprocess
import sys

def runProcessNonBlocking(command, shell=False, cwd = None):

    if not shell:
        command = command.split()

    p = subprocess.Popen(command,
                        shell=shell,
                        cwd=cwd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
                        bufsize=1)

    while(True):
        # returns None while subprocess is running
        retcode = p.poll()
        line = p.stdout.readline()
        yield line
        if retcode is not None:
            break

if __name__ == "__main__":

    cmd = "gdb"

    try:
        for line in runProcessNonBlocking(cmd, shell=True):
            line_encoded = line.decode('utf-8', 'ignore')
            print(line_encoded)

    except Exception as E:
        print("    Error: cannot run the command: %s" % E)
        sys.exit(2)

该代码将GDB作为进程运行,我可以键入命令并获取输出。但是,问题是我看不到我在GDB提示符下键入的内容。我在这里想念什么?

python
1个回答
1
投票

您的代码有1个问题,而运行方式则有1个问题。

 while(True):
        # returns None while subprocess is running
        retcode = p.poll()
        line = p.stdout.readline()
        yield line
        if retcode is not None:
            break

在上面的代码块中,您自己就是在阻塞过程输出,直到产生一行为止。这将导致没有任何回声,直到换行符出现为止,从而使您感到没有键入任何内容。

第二个问题是,默认情况下python在缓冲模式下运行。您需要禁用它。现在有多种方法可以做到这一点

$ PYTHONUNBUFFERED=true python3 test.py

$ python3 -u test.py

但是这将取决于我们的运行方式。因此,我们甚至通过确保使用它们后立即刷新打印语句来解决代码本身中的问题。

下面是更新的代码

import subprocess
import sys

def runProcessNonBlocking(command, shell=False, cwd = None):

    if not shell:
        command = command.split()

    p = subprocess.Popen(command,
                        bufsize=1,
                        shell=shell,
                        cwd=cwd,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT                        )

    while(True):
        # returns None while subprocess is running
        retcode = p.poll()
        line = p.stdout.read(1)
        yield line
        if retcode is not None:
            break

if __name__ == "__main__":

    import os
    cmd = ["gdb"]

    try:
        for line in runProcessNonBlocking(cmd, shell=True):
            line_encoded = line.decode('utf-8', 'ignore')
            print(line_encoded, end='',flush=True)

    except Exception as E:
        print("    Error: cannot run the command: %s" % E)
        sys.exit(2)

Working now

© www.soinside.com 2019 - 2024. All rights reserved.