1
votes

Hi I'm working through some exercise from Advanced Programming Unix System. I'm interested in how the fork and execlp function works. From the text the author specifies that fork creates a new process. It is called once - by the parent - but returns twice - in the parent and in the child.

So fork returns a non negative pid to the parent and 0 to the child. I would like to step through this sequence of calls with GDB, however my break points causes the child not to run or interrupt system calls which cause the parent to terminate.

1 - if I set a break point - else if(pid == 0) -> the process does not run.

2 - if I set a break point - execlp(buf, buf, (char *)0);

I the get the following error:

waitpid error: Interrupted system call [Inferior 1 (process 461) exited with code 01]

What options do I have to set in GDB to debug the parent and child? Where should set the breakpoints?

int main(int argc, char *argv[])
{
    char buf[MAXLINE];
    pid_t pid;
    int status;

    printf("%% ");

    while(fgets(buf, MAXLINE, stdin) != NULL)
    {
        if(buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0; 
        if((pid = fork()) < 0)
        {
            err_sys("fork error");
        }
        else if(pid == 0)
        {
            execlp(buf, buf, (char *)0);
            err_ret("could'nt execute: %s", buf);
            exit(127);
        }
        if((pid = waitpid(pid, &status, 0)) < 0)
            err_sys("waitpid error");
        printf("%% ");
    }
    exit(0);
}
1

1 Answers

1
votes

You may find some help in the gdb documentation: https://sourceware.org/gdb/onlinedocs/gdb/Forks.html

I think you may set set detach-on-fork off to trace the child process as well.

you may then put the breakpoint on fork an see both finishing the call

here my output:

$ gdb ./a.out 
GNU gdb (GDB) 7.6-6.mga4 (Mageia release 4)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-mageia-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/a.out...done.
(gdb) set detach-on-fork off
(gdb) b fork
Breakpoint 1 at 0x400710
(gdb) r
Starting program: /tmp/a.out 
% dddd

Breakpoint 1, 0x00007ffff7ae0e04 in fork () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.18-9.11.mga4.x86_64
(gdb) bt
#0  0x00007ffff7ae0e04 in fork () from /lib64/libc.so.6
#1  0x0000000000400880 in main (argc=1, argv=0x7fffffffdc38) at delme.c:19
(gdb) info inferior 
  Num  Description       Executable        
* 1    process 8272      /tmp/a.out        
(gdb) n
Single stepping until exit from function fork,
which has no line number information.
[New process 8287]
main (argc=1, argv=0x7fffffffdc38) at delme.c:23
23              else if(pid == 0)
Missing separate debuginfos, use: debuginfo-install glibc-2.18-9.11.mga4.x86_64
(gdb) info inferior 
  Num  Description       Executable        
  2    process 8287      /tmp/a.out        
* 1    process 8272      /tmp/a.out        
(gdb) p pid
$1 = 8287
(gdb) inferior 2
[Switching to inferior 2 [process 8287] (/tmp/a.out)]
[Switching to thread 2 (process 8287)] 
#0  0x00007ffff7ae0eac in fork () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function fork,
which has no line number information.
main (argc=1, argv=0x7fffffffdc38) at delme.c:23
23              else if(pid == 0)
(gdb) p pid
$2 = 0