Checking Exit Codes (was: Re: Trojan Horses)

Dave Burton daveb at nostromo.austin.ibm.com
Tue Oct 30 06:04:23 AEST 1990


In article <18647 at rpp386.cactus.org> jfh at rpp386.cactus.org (John F. Haugh II) writes:
|In article <8645:Oct2521:49:5790 at kramden.acf.nyu.edu> brnstnd at kramden.acf.nyu.edu (Dan Bernstein) writes:
|>This might be true for calls that give me information, but
|>close() is not such a call. Do you check the return value of assert()?
|
|Sure, why not.  You do know that assert() is documented as returning
|to the invoker?  You have to read the abort() page to find this out,

Bzzt.  assert() only "returns" to the invoker when the assertion is false.
Asserts are handled in

XPG3 by calling abort(), about which it states:
	"The _abort_() function does not return." [emphasis theirs]
	and
	"SIGABRT is not intended to be caught."

BSD4.3 by:
	directly calling exit(2).

SVR2.1 by:
	calling _assert(), which calls abort(), which calls
	kill(getpid(), SIGIOT);
	which, admittedly, could be caught.

SVR3.x by:
	<reference not available; hopefully better than SVR2.1>

AIX3.x by:
	calling _assert(), which calls abort(), which raise()s SIGABRT.
	If SIGABRT is caught and returns, it is masked out, and raise()d
	again.  If that doesn't make it, then exit() is called.  If SIGABRT
	doesn't return then the point is moot; the handler exit()d.
	
|but coding
|	assert (some impossible condition);
|	function (! some impossible condition allowed);
|is naive in non-user code.  What is going to happen one day when the
|user does
|	for (i = 1;i < NSIG;i++)
|		(void) signal (i, SIG_IGN);
|You better start checking the return code for assert() as well.

See the above "citations" regarding signal trapping.

All manuals (I have seen) state that the _assert_() macro returns no value.
And what happens to code _if_ assert() _did_ return a value?
Consider:

	#define	NDEBUG
	if (assert(x==y) == -1) {		/* bogus usage */
		perror("assert returned");
		exit(1);
	}

Since assert() is usually (XPG3, SVR2.x, BSD4.3, AIX3) defined as a null macro
if NDEBUG is #define'd, such code would not be portable (nor correct).

No, John.  The intent of assert() is that it compile away to nothing
in the presence of NDEBUG, without the baggage of #ifdef/#endif blocks.
The design of assert() is that it behave as a null statement when the
assertion is true, otherwise it should abort() the program.  This also
corresponds nicely to the kernel functionality of assert() - it panic()s.
--
Dave Burton
inet: daveb at bach.austin.ibm.com
uucp: cs.utexas.edu!ibmchs!auschs!nostromo!daveb



More information about the Comp.unix.internals mailing list