【问题标题】:gdb break when entering child process进入子进程时gdb中断
【发布时间】:2017-05-10 01:13:51
【问题描述】:

我很难弄清楚这一点;我有一个程序iverilog,它执行system() 调用以调用另一个程序ivl。我想在 gdb 中调试第二个程序 ivl,但是当我使用父进程调用 gdb 时,我无法让 gdb 在子进程中设置任何断点。程序如下所示:

//iverilog-main.cpp (Parent process)

int main(){
    //...
    system("ivl arg1 arg2");
    //...
    return 0;
}

.

//ivl-main.cpp (child process)

int main(){
    //...
    //stuff I want to debug
    //...
    return 0;
}

.

我正在运行的 gdb 命令是:gdb iverilog -x cmds.gdb

# cmds.gdb
set args hello.v
set follow-fork-mode child
set breakpoint pending on
break ivl-main.cpp:main
run

不幸的是,gdb 没有在ivl-main.cpp:main 处中断,它只是在没有中断的情况下完成;我得到的输出是:

Starting program: /usr/local/bin/iverilog hello.v
[New process 18117]
process 18117 is executing new program: /bin/dash
[Inferior 2 (process 18117) exited normally]

我确定 ivl-main.cpp:main 正在被调用,因为当我在 gdb 中运行 ivl 程序时,它成功地中断了那里。

我的想法是 gdb 在运行 gdb iverilog 时不会将 ivl-main.cpp 识别为源文件,并且当它进入包含 ivl-main.cpp 作为源文件。所以我认为如果我在gdb进入子进程时为ivl-main.cpp设置断点,它应该可以工作。我能想到的唯一方法是在system() 调用处手动中断并进入子进程,然后设置断点。是否有更优雅的方法可以强制 gdb 在进入子进程时中断?

【问题讨论】:

    标签: c++ c debugging gdb


    【解决方案1】:

    通常 GDB 一次只调试一个进程 - 如果您的程序分叉,那么您将调试父进程或子进程,但不能同时调试两者。默认情况下,GDB 在分叉后继续调试父级,但如果您愿意,可以使用以下命令更改此行为:

    set follow-fork-mode child

    或者,您可以告诉 GDB 让父级和子级都处于其控制之下。默认情况下 GDB 只跟随一个进程,但是你可以用这个命令告诉它跟随所有子进程:

    set detach-on-fork off

    GDB 将每个被调试的进程称为“劣等”。在调试多个进程时,您可以使用“inferiors”命令检查每个进程并与之交互,类似于使用“threads”检查多个线程或与多个线程交互的方式。

    在此处查看更多文档:

    https://sourceware.org/gdb/onlinedocs/gdb/Forks.html

    【讨论】:

    • 我已经使用了set fork-follow-mode child,但是gdb仍然无法在“劣质”进程中设置断点。
    • 您对系统的调用是否可能失败并且分叉没有发生?您需要做的就是设置follow-fork-mode childbreak main,GDB 应该在每次调用它遇到的“main”函数时中断。您甚至不需要设置要中断的特定源代码文件(甚至是尚未加载的文件)。
    • gdb 8.0-20.fc26 识别 follow-fork-mode,而不是 fork-follow-mode。
    【解决方案2】:

    This answer 提供了一种实现您想要的方式。

    理论上,set follow-fork-mode child 应该可以工作。

    实际上,iverilog 本身很可能是一个运行 (forks) 多个命令的 shell 脚本,因此在每个 fork 处,您需要决定是继续调试父级还是子级。一个错误的决定,你就失去了对最终执行程序的过程的控制。这很可能解释了为什么它不适合您。

    【讨论】:

    • 你是对的,system() 调用调用了多个程序,而我感兴趣的不是第一个,所以 gdb 会跟随第一个劣势并在它完成时停止。当它通过inferior 2 完成时,我能够通过切换到另一个劣质来解决这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2013-06-25
    • 2011-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多