7
votes

I have a application which forks a child process.

Child process does some work and somewhere in the middle it gives Segmentation fault. I used GDB to debug this, I used:

set follow-fork-mode child

I have also set a breakpoint to a function within the child. But GDB doesn't pause at my breakpoint.

Also the parent process handles the seg-fault so I had to ctrl-c to exit. Then when I use backtrace to print the stack all I got is

No stack

Why is the breakpoint not being set and why didn't I get the stack?

1
Is the child program written by you ?sirgeorge
no, but i do have the source with me.broun
GNU gprof is for profiling, not debugging. I'm (still) assuming you want to find out where you child process dies and not to profile it. To rebuild it in debug mode you should do export CFLAGS=-g in your shell (bash) before you do configure (I am assuming you know how to build programs from sources). I did a lot of debugging of child processes, and I cannot recall even one situation when follow-fork-mode in gdb worked as expected without giving me a headache, so I am trying to provide you with a workaround.sirgeorge
1) find the 'main' function of your child program and add infinite loop to it: volatile int iHang=1; while(iHang); 2) build it againsirgeorge
Attach to the child running in infinite loop: gdb -p <child'd-pid>. And then in gdb: set iHang=0. And (also in gdb): handle SIGSEGV stop. That should enable you to be able to see exactly when your child is crashing.sirgeorge

1 Answers

9
votes

Why is the breakpoint not being set

The breakpoint is being set, but it is not being hit because ...

and why didn't I get the stack?

... you are apparently debugging the wrong process.

With set follow-fork-mode child, GDB will follow the first child you create. Perhaps you create more than one?

One way to debug this is to establish a SIGSEGV handler using signal or sigaction.

In the handler, do this:

void handler(int signo)
{
  int i = 1;
  fprintf(stderr, "pid=%d, got signal=%d\n", getpid(), signo);
  while (i) { }
}

Once you see the message printed, in another window:

 gdb /proc/<pid>/exe <pid>
 (gdb) where