[comp.unix.questions] Debugging programs with fork

chris@mimsy.UUCP (Chris Torek) (10/03/88)

In article <12523@oberon.USC.EDU> pgarg@pollux.usc.edu (Pankaj K. Garg) writes:
> I am having trouble debugging programs which fork other
>processes. Dbx doesn't seem to handle them easily.

> I am using sun workstations running Unix 4.3.

[Sun workstations do not run `Unix 4.3', by which I guess that you mean
`4.3BSD': Sun workstations run SunOS and Mach.  This question should
have been directed to a Unix-specific group, not comp.lang.c; I have
redirected followups to comp.unix.questions.]

You are quite right; the existing Unix debuggers cannot handle programs
that fork.  SunOS 4.0 provides new facilities that make it possible,
but if you are dealing with older Unixes, you must either delete the
fork, or fall back on more `traditional' debugging schemes.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

hiebeler@rpics (Dave Hiebeler) (10/03/88)

In article <13819@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <12523@oberon.USC.EDU> pgarg@pollux.usc.edu (Pankaj K. Garg) writes:
>> I am having trouble debugging programs which fork other
>>processes. Dbx doesn't seem to handle them easily.
>> I am using sun workstations...
>
>
>You are quite right; the existing Unix debuggers cannot handle programs
>that fork.  SunOS 4.0 provides new facilities that make it possible,
>but if you are dealing with older Unixes, you must either delete the
>fork, or fall back on more `traditional' debugging schemes.
>-- 

     I am curious, what facilities are in 4.0 that help you debug (dbx)
forking processes?  I haven't seen anything about that, and am quite
interested; just a pointer to where I can find info would be nice.

     Occasionally, when I just HAD to dbx something that was forking, I
would move it over to our Sequent Balance, which has a parallel version
of dbx.  I'd change the fork() to m_fork(), so the forked child would
run on a different processor, and then the "pdbx" as it's called allows
you to go to different processors and debug what's running on any given
one.  Sometimes that's infeasible, however, and of course not everyone
has a Balance either.
----
Dave Hiebeler      Internet: hiebeler@cs.rpi.edu  (preferred address)
R.D. Box 225A                userfrzk%mts@itsgw.rpi.edu
Chatham, NY 12037    Bitnet: userfrzk@rpitsmts.bitnet
  "xue zai xao"

bak@csd-v.UUCP (Bruce A. Kern) (10/04/88)

In article <13819@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <12523@oberon.USC.EDU> pgarg@pollux.usc.edu (Pankaj K. Garg) writes:
>> I am having trouble debugging programs which fork other
>>processes. Dbx doesn't seem to handle them easily.
>
>You are quite right; the existing Unix debuggers cannot handle programs
>that fork.  SunOS 4.0 provides new facilities that make it possible,
>but if you are dealing with older Unixes, you must either delete the
>fork, or fall back on more `traditional' debugging schemes.
>-- 

I'm not sure what Chris here means by 'traditional' schemes (print statements,
etc.?).

In the case where a executable is execed after the fork, I've had success
by relpacing the execed program with an execed debugger as in the following
example:

/******************************************************************************/

/* Code for parent process */

#include <stdio.h>
#include <fcntl.h>

void
main( argc, argv )
	int argc; char **argv;
	{

	fprintf( stderr, "Here is some output from the parent\n" );

	switch( fork() )
		{
		case -1:
		fprintf( stderr, "failed fork\n" );
		exit( 1 );

		case 0:
		fprintf( stderr, "Here is child output prior to the exec\n" );
#		ifdef DEBUG
		execl( "/usr/bin/sdb", "/usr/bin/sdb", "kid", NULL );
#		else
		execl( "kid", "kid", NULL );
#		endif
		fprintf( stderr, "failed exec\n" );
		exit( 2 );

		default:
		fprintf( stderr, "more output from the parent\n" );
		break;
		}
	}

/******************************************************************************/

/* Code for child process */

#include <stdio.h>
#include <fcntl.h>

void
main( argc, argv )
	int argc; char **argv;
	{
	fprintf( stderr, "this is the child\n" );
	}

/******************************************************************************/


In the case of purely forked code (but not execed) the above technique
of course doesn't work.  Also the above only allows debugging of the
child, but sometimes that is what is required.
-- 
Bruce A. Kern                                  1-203-270-0399 
Computer Systems Design                        Voice: 730 - 1700 Mon. thru Fri.
29 High Rock Road                              Data:  All other times  
Sandy Hook, Ct.  06482                         

chris@mimsy.UUCP (Chris Torek) (10/04/88)

>In article <13819@mimsy.UUCP> I wrote:
>>... the existing Unix debuggers cannot handle programs
>>that fork.  SunOS 4.0 provides new facilities that make it possible,
>>but if you are dealing with older Unixes, you must either delete the
>>fork, or fall back on more `traditional' debugging schemes.

In article <175@csd-v.UUCP> bak@csd-v.UUCP (Bruce A. Kern) writes:
>I'm not sure what Chris here means by 'traditional' schemes (print
>statements, etc.?).

Actually, I prefer *thinking* :-) about the bug (it *does* have a
remarkable success rate%).  But being able to inspect the state, and in
particular the call stack, of a process is handy.

Several people have asked what the new facilities are.  I do not know;
but I do know that something new exists.  (Apparently dbx acquired an
`attach' command.  SunOS 3.2 dbx does not have this command.)
-----
% For me, at any rate.  I find that any time I am `thrashing' with
some particular bug, it helps to stop, see what data look like
when they are wrong, see which procedures modify those data, and
then decide what assertions should be made about the data in each
place.  It usually becomes obvious just which assertions are false.
Of course, the fix may still not be obvious. . . .
-----
>In the case where a executable is execed after the fork, I've had success
>by relpacing the execed program with an execed debugger ....

A nice trick.

Under 4BSD, you can also stop the child process and use `gcore' to get
a core image, which you can then inspect with dbx.  (You can use gcore
on a running process, but you will get inconsistent data.)  Stopping
is rather hit-or-miss unless you change the child code itself, however.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris