我如何运行GDB并通过Java输出控制台接受GDB命令?

huangapple 未分类评论53阅读模式
英文:

How do I run GDB and accept GDB commands through Java output console?

问题

我正在尝试为GCC构建一个GUI,其中包括一些基本功能,如使用Java编译、链接、执行、调试等来处理C++程序。我正在创建命令字符串,然后将其传递给ProcessBuilder,并通过命令提示符和GCC运行它。

这是编译文件的示例代码:

command = "cd src & cd Resources & g++ " + compileFile.cpp + " -Wall "+ " -o "+ "tempOut";

这是用于编译文件的示例代码。

其中的一部分是用于调试功能,我正在使用GDB。现在的问题是,GDB需要附加的输入来添加断点、移除断点等。我在如何通过Java终端将这些必要的输入传递给GDB方面遇到了困扰。如果我在命令提示符中传递命令,它可以正常工作并且我可以获得所需的输出。

但是,无论何时我从Java程序中触发GDB命令,都无法从IDE的终端传递任何输入。我知道每个GDB命令使用不同的进程,我尝试将Java的进程ID附加到GDB,但我只能获得一个空白的输出控制台。看起来GDB会话已经启动,但无法通过IDE的输出控制台与该进程进行交互。

int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
command = "gdb attach "+ pid;
fireCommand();

编辑

这是与命令提示符交互以在IDE的输出控制台中接收输入并显示输出的方法:

public void fireCommand() {
    String line;
    String os = System.getProperty("os.name");
    ProcessBuilder builder;
    if (os.startsWith("Win")) {
        builder = new ProcessBuilder("cmd.exe", "/c", command);
    } else {
        builder = new ProcessBuilder("bash", "-c", command);
    }
    try {

        process = builder.start();

        BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()));

        while ((line = reader.readLine()) != null) {
            if (line.contains("Input the value")) {
                // 在非调试执行中的其他用户输入
                String value = JOptionPane.showInputDialog(line);
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(process.getOutputStream()));
                writer.write(value, 0, value.length());
                writer.newLine();
                writer.close();
            } else {
                output.append(line).append("\n");
            }
        }
        int exitVal = process.waitFor();
        if (exitVal == 0) {
            // 显示"Success!"
            display(output.toString());
        } else {
            String lineErr;
            BufferedReader readerErr = new BufferedReader(
                    new InputStreamReader(process.getErrorStream()));
            while ((lineErr = readerErr.readLine()) != null) {
                outputErr.append(lineErr).append("\n");
            }
            // 显示exitVal
            display(outputErr.toString()); // 显示未捕获的错误
        }

    } catch (IOException e) {
        display("I/O存在问题");
        e.printStackTrace();
    } catch (InterruptedException e) {
        display("执行中断");
        e.printStackTrace();
    }
    if (!outputErr.toString().isEmpty())
        errorFormatDisplay(); // 显示错误输出函数
}

对于这个问题的任何线索将非常有帮助。谢谢。

英文:

I am trying to build a GUI for GCC which has some basic functionalities like compile, link, execute, debug, etc for C++ programs using Java. I am creating strings of command which I pass to the ProcessBuilder and run it via command prompt and GCC.

command = "cd src & cd Resources & g++ " + compileFile.cpp +" -Wall "+ " -o "+ "tempOut";

This is a sample code for compiling the file.

Part of this is the debug functionality for which I am using GDB. Now the problem is GDB needs additional input to add breakpoints, remove breakpoints and so on. I am having trouble on how to pass these necessary inputs to GDB via Java terminal. If I pass the commands in the command prompt, it is working fine and I get the desired output.
enter image description here

But whenever I fire the GDB command from the Java program, I cannot pass any inputs from the IDE's terminal. I am aware that each GDB command uses a different process and I tried attaching Java's process ID to GDB but I just get a blank output console. It seems that the GDB session has started but there is no way to interact with that process through the IDE's output console.

int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
command = "gdb attach "+ pid;
fireCommand();

EDIT

This is the method that interacts with command prompt to take input and display output in the IDE's output console:

public void fireCommand() {
        String line;
        String os = System.getProperty("os.name");
        ProcessBuilder builder;
        if(os.startsWith("Win")) {
            builder = new ProcessBuilder("cmd.exe", "/c", command);
        }
        else{
            builder = new ProcessBuilder("bash", "-c", command);
        }
        try {

            process = builder.start();

            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));

            while ((line = reader.readLine()) != null) {
                if(line.contains("Input the value")) {
                    //any other user input in non debug execution
                    String value = JOptionPane.showInputDialog(line);
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(process.getOutputStream()));
                    writer.write(value, 0, value.length());
                    writer.newLine();
                    writer.close();
                }
                else {
                    output.append(line).append("\n");
                }
            }
            int exitVal = process.waitFor();
            if (exitVal == 0) {
                //display("Success!");
                display(output.toString());
            } else {
                String lineErr;
                BufferedReader readerErr = new BufferedReader(
                        new InputStreamReader(process.getErrorStream()));
                while ((lineErr = readerErr.readLine()) != null) {
                    outputErr.append(lineErr).append("\n");
                }
                //display(exitVal);
                display(outputErr.toString()); //Display the uncatched errors
            }

        } catch (IOException e) {
            display("There was a problem with the I/O");
            e.printStackTrace();
        } catch (InterruptedException e) {
            display("There was a interruption with the execution");
            e.printStackTrace();
        }
        if(!outputErr.toString().isEmpty())
        errorFormatDisplay();                                                   //display Error output function
    }

Any leads on this would be very helpful. Thank you.

答案1

得分: 0

我知道每个 GDB 命令都使用不同的进程

不是的,gdb 作为一个进程运行。你是不是想说,每次尝试传递 gdb 命令时,都会创建一个新的 gdb 进程?

似乎 GDB 会话已启动,但无法通过 IDE 的输出控制台与该进程进行交互。

也许你应该使用 GDB/MI 接口,例如 Emacs 的调试器模式 gud 就使用了这个接口。

英文:

> I am aware that each GDB command uses a different process

No, gdb runs as one process. Did you mean to say that you are creating a new gdb process every time you try to pass it a gdb command ?

> It seems that the GDB session has started but there is no way to interact with that process through the IDE's output console.

Maybe you should use The GDB/MI Interface, which e.g. the Emacs debugger mode gud uses.

huangapple
  • 本文由 发表于 2020年4月5日 05:19:47
  • 转载请务必保留本文链接:https://java.coder-hub.com/61034937.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定