[comp.unix.questions] core files under SV

mrd@sun.soe.clarkson.edu (Michael DeCorte) (11/15/89)

There has got to be a little function I can call that will generate a
core file of my process but I sure can't find it in sections 2 or 3.
Anybody know what it is?

NOTE I want to generate a core file but NOT exit.  Yup I just want to
go along on my merry way.

thanks
--

Michael DeCorte // H215-546-0497 W386-8164 Fax386-8252 // mrd@clutx.bitnet
2300 Naudain St. "H", Phil, PA 19146 // mrd@sun.soe.clarkson.edu
---------------------------------------------------------------------------
Clarkson Archive Server // commands = help, index, send, path
archive-server@sun.soe.clarkson.edu
archive-server%sun.soe.clarkson.edu@omnigate.bitnet
dumb1!dumb2!dumb3!smart!sun.soe.clarkson.edu!archive-server
---------------------------------------------------------------------------

chris@mimsy.umd.edu (Chris Torek) (11/15/89)

In article <MRD.89Nov15011304@image.clarkson.edu> mrd@sun.soe.clarkson.edu
(Michael DeCorte) writes:
>NOTE I want to generate a core file but NOT exit.  Yup I just want to
>go along on my merry way.

(You are not going to like this :-) )

int
make_core_file() {
	int pid = fork(), w, status;
	extern int errno;

	switch (pid) {

	case -1:
/*DEBUG*/	/* perror("cannot fork to make core file"); */
		return (-1);

	case 0: /* child */
		abort();
/*DEBUG*/	/* (void) write(2, "could not make core file\n", 25); */
		_exit(1);
		/* NOTREACHED */
	}
	/* parent */
	/* should use wait4() here, but no one has it yet */
	while ((w = wait(&status)) != pid)
		if (w == -1 && errno != EINTR)
			break;
	if (status & 0200)	/* made a core file */
		return (0);
	return (1);		/* fork succeeded, but no core dump */
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

cpcahil@virtech.uucp (Conor P. Cahill) (11/16/89)

In article <MRD.89Nov15011304@image.clarkson.edu>, mrd@sun.soe.clarkson.edu (Michael DeCorte) writes:
> 
> There has got to be a little function I can call that will generate a
> core file of my process but I sure can't find it in sections 2 or 3.
> Anybody know what it is?
> 
> NOTE I want to generate a core file but NOT exit.  Yup I just want to
> go along on my merry way.

There is no system or library call to do this, but you could just do 
the following:

	if( fork() == 0 )
	{
		abort();
	}

which will result in a core file being generated and letting your
current program continue executing. If you do this alot, without performing
a wait(2), you will eventually run out of process table slots.  So either
do a wait() after the fork(), or limit the number of times you do this.


-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/16/89)

In article <MRD.89Nov15011304@image.clarkson.edu> mrd@sun.soe.clarkson.edu (Michael DeCorte) writes:
>There has got to be a little function I can call that will generate a
>core file of my process but I sure can't find it in sections 2 or 3.
>Anybody know what it is?
>NOTE I want to generate a core file but NOT exit.  Yup I just want to
>go along on my merry way.

I could say all sorts of disparaging things about people who think
UNIX would have a single function that performs a particular action
not of general utilit, but I won't :-)

	if ( fork() == 0 )
		abort();

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/16/89)

In article <11613@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>	if ( fork() == 0 )
>		abort();

As somebody else pointed out, if you do lots of these you also need
to reap the zombies.  The simplest solution to that is

	if ( (pid = fork()) == 0 )
		abort();
	else
		while ( wait( (int*)0 ) != pid )
			;

If you don't want to wait for the core dump to complete before
proceeding, arrange for the dumping child to be detached:

	if ( (pid = fork()) == 0 )
		if ( fork() == 0 )
	                abort();
		else
			_exit( 0 );
	else
		while ( wait( (int*)0 ) != pid )
			;

Note that I've assumed that you aren't performing any wait()s in
signal handlers, because you really shouldn't.

bobmon@iuvax.cs.indiana.edu (RAMontante) (11/17/89)

gwyn@brl.arpa (Doug Gwyn) <11616@smoke.BRL.MIL> :
-
-	if ( fork() == 0 )
-                abort();
  !			/* [ child not cleaned from proc. table? ] */
-
-As somebody else pointed out, if you do lots of these you also need
-to reap the zombies.
		[ . . . ]
-If you don't want to wait for the core dump to complete before
-proceeding, arrange for the dumping child to be detached:
-
-	if ( (pid = fork()) == 0 )
-		if ( fork() == 0 )
-	                abort();
-		else
-			_exit( 0 );
-	else
-		while ( wait( (int*)0 ) != pid )
-			;

Um, I don't see why this "reaps the zombies".  I thought the `wait(pid)'
call was added to clean up the aborted child --- here the child is
wait()'ed on, but the grandchild looks just like the child did in the
original version.

gwyn@smoke.BRL.MIL (Doug Gwyn) (11/18/89)

In article <29843@iuvax.cs.indiana.edu> bobmon@iuvax.cs.indiana.edu (RAMontante) writes:
>Um, I don't see why this "reaps the zombies".

Finally, we found a way to tell who's a UNIX wizard!

Hint: after the child terminates, who is the parent of the grandchild?
(Yes, there is one..)

cpcahil@virtech.uucp (Conor P. Cahill) (11/19/89)

In article <29843@iuvax.cs.indiana.edu>, bobmon@iuvax.cs.indiana.edu (RAMontante) writes:
> gwyn@brl.arpa (Doug Gwyn) <11616@smoke.BRL.MIL> :
    [example of using double fork to not have to wait for children to die AND
     still not have to worry about zombies...]

> Um, I don't see why this "reaps the zombies".  I thought the `wait(pid)'
> call was added to clean up the aborted child --- here the child is
> wait()'ed on, but the grandchild looks just like the child did in the
> original version.

Because when your parent dies init then becomes your parent.  init spends
most of it's time waiting to clean up orphaned processes.

In the example the child forked the grand-child and immediatly exited
therefore the grandchild was an orphaned process.

-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

brnstnd@stealth.acf.nyu.edu (Dan Bernstein) (11/20/89)

If you use double-forking to avoid ten lines of child-handling code, you
risk a (very improbable) race condition. And the extra fork wastes more
time than a signal handler. And you may run out of processes.

---Dan

cpcahil@virtech.uucp (Conor P. Cahill) (11/20/89)

In article <3991@sbcs.sunysb.edu>, brnstnd@stealth.acf.nyu.edu (Dan Bernstein) writes:
> If you use double-forking to avoid ten lines of child-handling code, you
> risk a (very improbable) race condition. And the extra fork wastes more
> time than a signal handler. And you may run out of processes.

What race condition?  Maybe you think it is a race condition if the grandchild
aborts prior to the child exiting?  That is no problem because zombies of 
processes that die/exit are still inherited by init.

Older forks were very ineffecient, but with system V.3 forks, the kernel does
not make a complete copy of your process, it only flags the pages of the
current process as "copy on write" and copies the page table entries for the
new process.  This makes fork() a much faster, by orders of magnitude I would
guess, system call.

Yes, you may run out of processes, but if you are so near your process limit
that a double fork to perform a core dump causes you to run into the limit,
the limit needs to be raised.  The duration of these two processes will be
so short as to make them almost unnoticable (that is, of course, unless your
process is an 8meg process and you have slow disk drives).

The double fork serves two purposes.  The first, and primary, reason is to
let you continue processing while the child process dumps the core.  If you
want to do this and not have to worry about too many zombies attacking you
when you do this to often in the same process, the easiest solution is to 
use the double fork.   Of course, if you will never be executing any children
you could do a signal(SIGCLD,SIG_IGN);
-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

guy@auspex.auspex.com (Guy Harris) (11/21/89)

>There is no system or library call to do this, but you could just do 
>the following:
>
>	if( fork() == 0 )
>	{
>		abort();
>	}

As long as the following causes no problems (from the SunOS 4.0
ABORT(3), but it comes from the S5 documentation and reflects S5's
implementation as well):

   NAME
        abort - generate a fault

	...

   DESCRIPTION
        abort() first closes all open files if possible...

"Open files" here refers not just to file descriptors but to standard
I/O streams; i.e., buffered output will be flushed.  This could cause
that buffered output to be printed twice, if it gets flushed later in
the parent as well.

merlyn@iwarp.intel.com (Randal Schwartz) (11/21/89)

In article <29843@iuvax.cs.indiana.edu>, bobmon@iuvax (RAMontante) writes:
| Um, I don't see why this "reaps the zombies".  I thought the `wait(pid)'
| call was added to clean up the aborted child --- here the child is
| wait()'ed on, but the grandchild looks just like the child did in the
| original version.

Ahhh, yes, but the grandchild is inherited by init, having been
orphan-ed by its parent.  The original process will not see the
grandchild as a potential child to be "wait"-ed for.

I don't like the presented code though, in that it will reap other
children that have not yet been wait-ed for.  There's no way around
that, though.  (Cursory glancing at the wait4() manpage under SunOS4
does not tell me if wait4() suffers from the same deficiency.  Anyone
know, offhand?  Mail please.)

Just another wait()-person,
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel's iWarp project, Hillsboro, Oregon, USA, Sol III  |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/