Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gdb break when entering child process

Tags:

c++

c

debugging

gdb

I'm having a tough time figuring this one out; I have a program, iverilog that executes a system() call to invoke another program, ivl. I want to debug the second program, ivl in gdb, but I can't get gdb to set any breakpoints in the child process when I invoke gdb with the parent process. Here's what the programs look like:

//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;
}

.

The gdb commands I'm running are: 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

Unfortunately, gdb doesn't break at ivl-main.cpp:main,it just completes without ever breaking; the output I get is:

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]

I'm certain ivl-main.cpp:main is being called because when I run the ivl program in gdb it successfully breaks there.

My thinking is that gdb doesn't recognize ivl-main.cpp as a source file when its running gdb iverilog, and it's not setting that breakpoint when it enters the child process which does contain ivl-main.cpp as a source file. So I think if I set the breakpoint for ivl-main.cpp when gdb enters the child process, it should work. The only way I can think of doing this is to manually break at the system() call and step into the child process, then set the breakpoint. Is there a more elegant approach that would force gdb to break whenever entering a child process?

like image 324
mtveezy Avatar asked May 10 '17 01:05

mtveezy


People also ask

How do I set a break in GDB?

To do this, just type "break [functionname]". gdb will stop your program just before that function is called. Breakpoints stay set when your program ends, so you do not have to reset them unless you quit gdb and restart it.

How do you debug a child process?

There is an alternative way of debugging the child process. After fork() is executed, put a sleep() call in the code where the child executes, get the PID of the child using the ps utility, then attach the PID. Now, you can debug the child process, like any other process.

How do I detach a process in GDB?

When you have finished debugging the attached process, you can use the detach command to release it from GDB control. Detaching the process continues its execution. After the detach command, that process and GDB become completely independent once more, and you are ready to attach another process or start one with run .


2 Answers

Normally GDB only debugs one process at a time- if your program forks then you will debug the parent or the child, but not both simultaneously. By default, GDB continues debugging the parent after a fork, but you can change this behavior if you so desire with the following command:

set follow-fork-mode child

Alternately, you can tell GDB to keep both the parent and the child under its control. By default GDB only follows one process, but you can tell it to follow all child processes with this command:

set detach-on-fork off

GDB refers to each debugged process as an "inferior". When debugging multiple processes you can examine and interact each process with the "inferiors" command similar to how you would use "threads" to examine or interact with multiple threads.

See more documentation here:

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

like image 66
David Avatar answered Sep 19 '22 23:09

David


This answer provides one way to achieve what you want.

In theory, set follow-fork-mode child should work.

In practice, the iverilog is likely itself a shell script that runs (forks) multiple commands, so at every fork you will need to decide whether you want to continue debugging the parent or the child. One wrong decision and you've lost control of the process that will eventually execute your program. This very likely explains why it didn't work for you.

like image 35
Employed Russian Avatar answered Sep 20 '22 23:09

Employed Russian