DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Using the command line interface of debug

Session 7: can I ignore a forked process?

  1. Insert ``"get"'' as the second argument in the call to execl in sget.c to fix the bug in Session 6:
       (void) execl("/usr/ccs/bin/get", "get", path, 0);
    

  2. Compile sget.

  3. Run sget. Although it doesn't give you an error message, this output doesn't look correct either, because main.c is not an empty file:
       $ sget <files
       file1: 0 characters, 0 words, 0 lines
       main.c: 0 characters, 0 words, 0 lines
       $ wc -c main.c
       6231  main.c
    
    The bug must be after get(1) finishes or you would have seen the same error message you saw earlier.

  4. Get into debug and set a breakpoint in the function get after the call to wait:
       debug> create sget <files
       New program sget (process p1) created
       HALTED p1 [main in sget.c]
       132:   (void)signal(SIGHUP,handler);
       debug> stop sget.c@64
       EVENT [1] assigned
    

  5. When you run the program, it will stop when the process forks (just like last time).
       debug> run
    
    The debugger displays the following:
       file1: 0 characters, 0 words, 0 lines
       Process p1 forked; new process p2 now controlled
    

  6. This time you don't care about the child process. If you release the child, it will run to completion with no more help or hindrance from you, and you can continue debugging the parent process.
       debug> release -p p2
    
    The debugger displays the following:
       releasing and running p2
    


    NOTE: See ``Releasing or ignoring processes and threads'' for more information.

  7. When you run the parent, it will wait for the SIGCLD letting it know the child process has exited. If you tell debug to ignore SIGCLD, you won't have to do anything else with the child process; the parent will wait until the child finishes, then go on until it hits the breakpoint:
       debug> signal -i sigcld
       debug> run
    
    The debugger displays the following:
       STOP EVENT TRIGGERED: sget.c@64  in p1 [get in sget.c]
       64:             if ((infile = fopen(newfile, "r")) == 0)
    

  8. Now you can continue debugging the parent as if it were a simple, one-process program:
       debug> step
    
    The debugger displays the following:
       STEPPED p1 [get in sget.c]
       70:             while(fgets(buf, BUFSIZ, infile) == 0)
    
    The problem is the infamous backwards test; it should keep looping as long as fgets succeeds (i.e., returns a non-zero value).

  9. Exit the debugger.

Releasing or ignoring processes and threads

When you released p2, you relinquished all control over it. If you had defined any events for it, they would be deleted. If it goes on to fork another process or exec another program, debug will not tell you about it, and it no longer shows up in the debugger's process list. You may release grabbed processes (release is the inverse operation of grab), processes created within the debugger, and threads.

When you create or grab a process and you are not interested in any of the process's children, you can avoid seeing them at all with the -f option (for ``follow'') to the create and grab commands. Typing -f none tells the debugger not to follow (control) any of the process's children. Typing -f all or -f procs tells the debugger to follow all the children; this is the default behavior. Therefore, in
Session 7, you could have used this sequence of commands to get to the offending function:

   debug> create -f none sget <files
   New program sget (process p1) created
   debug> stop sget.c@64
   EVENT [1] assigned
   debug> signal -i sigcld
   debug> run
   file1: 0 characters, 0 words, 0 lines
   STOP EVENT TRIGGERED: sget.c@64  in p1 [get in sget.c]
   64:		if ((infile = fopen(newfile, "r")) == 0)

Using the -f option affects only the processes in the individual create or grab command. You may change the default behavior for all instances of those commands by setting the debugger variable %follow to all, procs, or none. Unlike processes, you cannot tell the debugger not to follow threads, since the debugger must know about all the threads in a process to maintain the correct state information internally. You can, however, tell it that you do not want to know about a particular thread by releasing that thread. That thread will no longer show up in the ps output, and you will not be able to do anything with it, even though the debugger itself still knows about it.

You can also fine-tune the amount of information you see for the thread that you control by setting the debugger variable %thread_change appropriately. The default value of this variable is stop, which means the debugger will print a message and stop the thread whenever a thread:

By setting %thread_change to announce, you can tell debug to print the message but not stop the thread. Setting the variable to ignore will make it suppress the message as well. The thread will still show up in the ps output, and will stop on any event that you create. Unlike %follow, %thread_change applies to all existing threads, not just the ones created since the %thread_change was set.
Next topic: Session 8: which end of the pipe is broken?
Previous topic: fork(2), exec(2), and system(3S)

© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004