进入子进程时gdb中断

mtv*_*ezy 5 c c++ debugging gdb

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

//iverilog-main.cpp (Parent process)

int main(){
    //...
    system("ivl arg1 arg2");
    //...
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

.

//ivl-main.cpp (child process)

int main(){
    //...
    //stuff I want to debug
    //...
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

.

我正在运行的 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
Run Code Online (Sandbox Code Playgroud)

不幸的是,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]
Run Code Online (Sandbox Code Playgroud)

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

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

Dav*_*vid 5

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

set follow-fork-mode child

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

set detach-on-fork off

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

在此处查看更多文档:

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

  • 是否有可能您对系统的调用失败并且分叉没有发生?您需要做的就是设置“follow-fork-mode child”和“break main”,GDB 应该在每次调用“main”函数时中断。您甚至不需要设置要中断的特定源代码文件(即使是尚未加载的文件)。 (2认同)
  • gdb 8.0-20.fc26 识别 follow-fork-mode,而不是 fork-follow-mode。 (2认同)

Emp*_*ian 3

这个答案提供了一种实现你想要的方法。

理论上set follow-fork-mode child应该有效。

实际上,它iverilog本身可能是一个运行fork多个命令的 shell 脚本,因此每次fork您都需要决定是否要继续调试父级或子级。一个错误的决定,你就会失去对最终执行你的程序的过程的控制。这很可能解释了为什么它对你不起作用。