[comp.unix.internals] abort may return

jfh@rpp386.cactus.org (John F. Haugh II) (11/01/90)

In article <8508@scolex.sco.COM> seanf (Sean Fagan) writes:
>In article <18658@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes:
>>so, you will always assume that failing asserts never return?  
>
>Yes.  I believe that's what ANSI (and POSIX) says.

i checked my 1988 X3J11 draft and it was silent - the only documentation
i found supporting the claim that abort never returns was in XPG3.  still,
the point is simply that to maximize portability you always assume the
worst.  posix just says to do whatever ANSI C says to do.

>                                                    At least one
>implementation (ours, to be honest 8-)) makes sure that abort() will not
>return.  The only way, from my glancing of the object code (disassembled, of
>course), to get it to return would be to send the process a signal it *does*
>catch, and then longjmp() out of that signal handler.

sigh.

% uname -s
XENIX

this =is= SCO's implementation.  perhaps the newer versions work the
way you say, but just saying "we don't do it" isn't clear enough - and
again points to how unreliable the statement is.

i checked my System III-derived microsoft xenix machine also this
morning, and the assert macro doesn't even call abort - it just calls
exit() and gets it over and done with ;-(.

>But there's now way I know of to make sure that such a thing doesn't happen.
>(Well, you could, in abort(), block all signals, I suppose, and, now that I
>think about it, I think I'll see about getting us to do so 8-).)

the normal trick is to set SIGIOT to SIG_DFL, which prevents the signal
handler from ever catching SIGIOT.  this isn't all that far-fetched as
other library routines catch certain signals, dork around a bit, then
re-send the same signal they just caught.

a conforming implementation might be

void 
abort (void)
{
	signal (SIGABRT, SIG_DFL);
	kill (getpid (), SIGABRT);
	exit (1);
}

i believe the old-time implementation was something to the effect of

int
abort ()
{
	return kill (getpid (), SIGABRT);
}

which is why the problems come up.
-- 
John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
"SCCS, the source motel!  Programs check in and never check out!"
		-- Ken Thompson

seanf@sco.COM (Sean Fagan) (11/03/90)

In article <18665@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes:
>i checked my 1988 X3J11 draft and it was silent - 

Section 4.2.1.1

	#include <assert.h>
	void assert(int expression);
	The assert macro puts diagnostics into programs. [...]
	It then calls the abort function.

Section 4.10.4.1

	#include <stdlib.h>
	void abort(void);
	The abort function causes abnormal program termination to occur,
	unless the signal SIGABRT is being caught and the signal handler
	does not return.

December 7 1988 X3J11.

Seems to say quite a bit on it.  First of all, you cannot check the return
value of assert() or abort(), since both are void's.  Second, even if you 
catch or ignore SIGABRT, the implementation is required to exit, still (it
seems).  (In that respect, SCO's is wrong, I just found out...)

>% uname -s
>XENIX

Repeat after me, john.  SCO also sells UNIX.  Repeat it a hundred times.
Since that's what I'd been working on for about 1.5 years, that's what I was
talking about.

>a conforming implementation might be
>	kill (getpid (), SIGABRT);

Nope.  raise(SIGABRT).

It's still possible to get it to fail:  a function set up via atexit() could
simply longjmp back to main (*shudder*!).

Followup's to c.l.c, ok?

-- 
-----------------+
Sean Eric Fagan  | "*Never* knock on Death's door:  ring the bell and 
seanf@sco.COM    |   run away!  Death hates that!"
uunet!sco!seanf  |     -- Dr. Mike Stratford (Matt Frewer, "Doctor, Doctor")
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

jim@segue.segue.com (Jim Balter) (11/04/90)

In article <18665@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes:

>i checked my 1988 X3J11 draft and it was silent

Check your eyes.  X3J11/88-001, dated January 11, 1988, page 155, section
4.10.4.1 (The abort function), last line on the page:

	The abort function cannot return to its caller.

This line also occurs in all subsequent versions of the draft, as well
as the Standard itself.

You lose, factually and conceptually.  Can we now please drop this?

gwc@root.co.uk (Geoff Clare) (11/05/90)

In <18665@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes:

>the normal trick is to set SIGIOT to SIG_DFL, which prevents the signal
>handler from ever catching SIGIOT.  this isn't all that far-fetched as
>other library routines catch certain signals, dork around a bit, then
>re-send the same signal they just caught.

>a conforming implementation might be

>void 
>abort (void)
>{
>	signal (SIGABRT, SIG_DFL);
>	kill (getpid (), SIGABRT);
>	exit (1);
>}

If SIGABRT is being caught, the above will prevent the signal handler
from being called.  It should be:

void 
abort (void)
{
	(void) raise(SIGABRT);
	(void) signal(SIGABRT, SIG_DFL);
	(void) raise(SIGABRT);
	exit (1);
}

A POSIX version should unblock SIGABRT as well.
-- 
Geoff Clare <gwc@root.co.uk>  (Dumb American mailers: ...!uunet!root.co.uk!gwc)
UniSoft Limited, Hayne Street, London EC1A 9HH, England.   Tel: +44-71-315-6600