jfh@rpp386.cactus.org (John F. Haugh II) (10/31/90)
In article <4093@awdprime.UUCP> daveb@bach.austin.ibm.com (Dave Burton) writes: >The only way for a SVR2,3 assert() to return is _if_ SIGIOT is not >SIG_DFL. Most programs do not blithely SIG_IGN all signals. Further, >BSD/AIX/other asserts can _never_ return. So, yes, I always% assume >failing asserts() never return - that is their design. As for portability, >see below. > >% given the caveat of SIGIOT peculiarities on SVR2,3 systems yes, quite a few of my programs do run off on a tear and blithely ignore all of their signals. one thing you are ignoring is how many systems have the behavior which i describe. it is not just limited to SVR2 and SVR3, it includes every AT&T release prior to SVR2, such as 3.0, 4.0, 7th Edition, etc, and non-AT&T versions of UNIX-like operating systems as well. it is reasonable to expect abort() to return if SIGIOT is ignored. it doesn't matter what you think assert() is designed to do, there is so much prior art which contradicts your expectation. unfortunately there is also some prior art which agrees with what you are saying, and that is why i say to expect the worst - you lose nothing if you do, but if you don't you may have expected return conditions you aren't prepared to handle. i checked the old X3J11 draft i have - it was silent on the issue. now, i don't know if ANSI C requires abort() to exit, but if it doesn't, we still have this problem in ANSI C. using unspecified or undefined behavior is the very definition of non-portable. even if ANSI C, X/OPEN and half a dozen other standards all agree with you, there is simply too much prior experience with other behavior. >It is obvious that you did not read what I wrote. >Repeat after me: "assert() is a macro, not a function." >If I put an exit() after an assert() call, it looks like: then don't do it that way. > if (assert(argc==2) == -1) > exit(1); > >Oh. Syntax error. Looking at assert.h reveals the definition: > > #define assert(EX) if (EX) ; else _assert("EX", __FILE__, __LINE__) > >Gee, "Uncle Fred", how do you put a conditional exit() in your code? >Surely you wouldn't do: > > assert(argc==2),exit(1); > >would you? What happens when NDEBUG is #define'd? Syntax error. >The only way to put an exit() after a failing assert() is to >rework the macro, which is not portable. this is too easy. you put a conditional. then you put an exit. this gives you a conditional exit statement. most programmers don't have trouble with this. many of them even write code like if (! (chunk = malloc (sizeof *chunk))) { perror ("oops"); exit (1); } how about (gee, just a suggestion, i normally charge for my programming lessons, so this isn't a programming lesson) if (! (chunk = malloc (sizeof *chunk))) { perror ("oops"); assert (chunk != 0); exit (1); } now, i'd never actually do this, so don't think i am advocating this exact code fragment. but gee, dave, it isn't that hard. >|but the kernel assert() function is not defined >|in the System V Programmer's Reference Manual sitting next to me. >|i checked the namelist on the kernel running here. > >This could be my fault for not accurately describing the kernel assert >mechanism for you. The _macro_ name (it _won't_ appear in any namelist, >just like user asserts) is ASSERT(). It invokes assfail() the same way >user assert() invokes _assert(). And assfail() will _not_ return. >Refer to <sys/debug.h>. % grep -y ASSERT /usr/include/sys/debug.h % hmmm. no ASSERT (or assert) in my <sys/debug.h>. perhaps this really is just another IBMism. perhaps this is implementation specific details which have no bearing in a discussion of portable programming practices? furthermore, i don't recall any requirement in any of the documentation i've read requiring assert() invoke _assert() or assfail() or any of the stuff you keep talking about. please, try to limit this discussion to documented features. let's start with this documented feature - "assert(S) if expression is false (zero), it displays ... on the standard error file and aborts." and then this documented feature - "abort(S) abort can return control if the calling process is set to catch or ignore SIGIOT ..." 5.0 documentation is even more explicit. >I admit, I did look at the sources to verify my understanding >before posting to the net. That's generally considered wise. >Perhaps you would fare better if you did the same. are you in the habit of violating your non-disclosure agreements with IBM and AT&T just so you can make your postings? many of the people in this group have access to source code as well, but most of us don't run off and read it then report what we find to the net. just so you get to see how this =really= works in the =real= world, try this - Script is typescript, started Wed Oct 31 08:09:42 1990 rpp386-> cat abort.c #include <signal.h> #include <assert.h> #include <stdio.h> main (argc, argv) int argc; char **argv; { signal (SIGIOT, SIG_IGN); assert (argc == 2); printf ("hi dave!\n"); } rpp386-> cc -o abort abort.c abort.c rpp386-> ./abort Assertion failed: expr, file abort.c, line 10 hi dave! rpp386-> exit Script done Wed Oct 31 08:10:00 1990 -- 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
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/01/90)
In article <18662@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: : In article <4093@awdprime.UUCP> daveb@bach.austin.ibm.com (Dave Burton) writes: : >I admit, I did look at the sources to verify my understanding : >before posting to the net. That's generally considered wise. : >Perhaps you would fare better if you did the same. : : are you in the habit of violating your non-disclosure agreements : with IBM and AT&T just so you can make your postings? many of the : people in this group have access to source code as well, but most : of us don't run off and read it then report what we find to the : net. But the best sources of advice will generally double-check the sources and then pretend they wrote it out of their head. :-) [To whom it may concern: the undersigned does not at this time have access to any AT&T proprietary sources. (Which is obviously why I've been giving such bad advice lately... :-)] Larry Wall lwall@jpl-devvax.jpl.nasa.gov
daveb@nostromo.austin.ibm.com (Dave Burton) (11/09/90)
[ I'm ignoring advice from the adage "Never argue with a fool." ] [ But this is the last time :-) ] In article <4093@awdprime.UUCP> daveb@bach.austin.ibm.com (Dave Burton) writes: # The only way to put an exit() after a failing assert() is to # rework the macro, which is not portable. In article <18662@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: | you put a conditional. then you put an exit. this gives you | a conditional exit statement. most programmers don't have | trouble with this. many of them even write code like | | if (! (chunk = malloc (sizeof *chunk))) { | perror ("oops"); | exit (1); | } | | how about (gee, just a suggestion, i normally charge for my | programming lessons, so this isn't a programming lesson) | | if (! (chunk = malloc (sizeof *chunk))) { | perror ("oops"); | assert (chunk != 0); | exit (1); | } | | now, i'd never actually do this, so don't think i am advocating | this exact code fragment. but gee, dave, it isn't that hard. If this is your idea of "programming lessons", I hope your charge is that nobody reveals you taught them. You're nobody's teacher (especially after this thread) and not my "Uncle Fred". Lose the flippant 'tude, dude, and get back to reality. Your example is ludicrous. Of what use would assert be in such a case? Then you disclaim your example with "now, i'd never actually do this". Why did you give this example then? If you have a clear idea how to do what you propose, show us. #|but the kernel assert() function is not defined #|in the System V Programmer's Reference Manual sitting next to me. #|i checked the namelist on the kernel running here. I ignored this the first time around: The System V Programmer's Reference Manual also does not include namei() or major(), does this mean they're not there, or can't be relied upon in kernel code? | hmmm. no ASSERT (or assert) in my <sys/debug.h>. perhaps this really | is just another IBMism. perhaps this is implementation specific ... SVR2.1 has it. My SVR3.2 (ESIX) has it. I've used it in AT&T's SVR3.2 i386 and 3b2 offerings. I'd say it's not an IBMism, nor is it implementation specific. The UNIX SVR3 BCI Driver Development Guide documents it quite well. See pp 13:13,14 for a discussion. It's also quite well known to SV kernel hacks. | furthermore, i don't recall any requirement in any of the documentation | i've read requiring assert() invoke _assert() or assfail() or any of | the stuff you keep talking about. Nobody ever said there was. I mentioned _assert() and assfail() simply to enlighten you, since you didn't seem to understand about the macro nature of assert(), and couldn't find ASSERT/assert in your kernel's namelist. It was never mentioned in the context of portability except to elucidate why various assert() "band-aids" were not portable. # I admit, I did look at the sources to verify my understanding # before posting to the net. That's generally considered wise. # Perhaps you would fare better if you did the same. | are you in the habit of violating your non-disclosure agreements | with IBM and AT&T just so you can make your postings? many of the | people in this group have access to source code as well, but most | of us don't run off and read it then report what we find to the | net. I certainly didn't "run off and read it then report what [I found] to the net." It was more like: "Hmm. I think John is wrong. I've used assert() before, and it never returns. Perhaps it's only that way on BSD and SVRx systems. Before I post, I'd better confirm with other implementations." Possibly the only "trade secret" I revealed was that IBM's abort() can be trusted to not return. That's positive press. But go ahead, forward my posting(s) to my management and IBM security (as if they haven't already screened them) and let's see who gets their hand slapped. | just so you get to see how this =really= works in the =real= | world, try this - | [ paraphrase of the demo program I wrote to show John's folly ] Grrrr! This really pisses me off, John. I _know_ what that program does. If you really want to brow-beat me, modify it to make the assert() _always_, _portably_ exit, without repeating the test in the assertion itself (which you were already flamed for once). -- Dave Burton inet: daveb@bach.austin.ibm.com uucp: cs.utexas.edu!ibmchs!auschs!nostromo!daveb
jfh@rpp386.cactus.org (John F. Haugh II) (11/12/90)
In article <4157@awdprime.UUCP> daveb@bach.austin.ibm.com (Dave Burton) writes: >I ignored this the first time around: >The System V Programmer's Reference Manual also does not include >namei() or major(), does this mean they're not there, or can't be >relied upon in kernel code? go check the kernel on AIX V3.1, you will find that it does not include namei() as a kernel service. clearly this proves that you can't rely on non-standard or undocumented features. don't believe me - go check the source code. no namei(). now will you give up? you can't seem to accept that on some system assert() and abort() return to their invoker, and now you go claiming namei() is a common kernel service. please, quit while you are just slightly behind. -- 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
mikep@dirty.csc.ti.com (Michael A. Petonic) (11/13/90)
In article <18717@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >In article <4157@awdprime.UUCP> daveb@bach.austin.ibm.com (Dave Burton) writes: >>I ignored this the first time around: >>The System V Programmer's Reference Manual also does not include >>namei() or major(), does this mean they're not there, or can't be >>relied upon in kernel code? > >go check the kernel on AIX V3.1, you will find that it does not >include namei() as a kernel service. clearly this proves that >you can't rely on non-standard or undocumented features. don't >believe me - go check the source code. no namei(). This is rapidly degenerating into a flame war (uh, too late). But, since it's already here, let me add... Come on, John! If you've got enough UNIX history to know what the hell namei() does, then you'll no doubt be smart enough to realize that it's not going to be a straightforward implementation on AIX with the filesystem *sufficiently* different than System V. If you're in this far, you'd better know what the f*ck you're doing. Your off-the-cuff/hard-and-fast rules are boring us, John. You wouldn't want to be known as a bore, would you (uh, too late). -MikeP
jim@segue.segue.com (Jim Balter) (11/14/90)
In article <18717@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >[...] you can't seem to accept that on some >system assert() and abort() return to their invoker, [...] No one has claimed that assert cannot be made to return on some systems, yet this is at least the third time that you have responded to some *other* point as though that claim were being made. Can you say *strawman*? Since I previously explicitly pointed this out and yet you ignored it (you did respond to other parts of my posting, so you did receive it), the only explanation I can see is bad faith. While there is plenty of room in the information groups for disagreement, there is none for bad faith. >will you give up? you can't seem to accept that on some >system assert() and abort() return to their invoker, and now >you go claiming namei() is a common kernel service. please, >quit while you are just slightly behind. This isn't a contest, John.
jfh@rpp386.cactus.org (John F. Haugh II) (11/14/90)
In article <4643@segue.segue.com> jim@segue.segue.com (Jim Balter) writes: >No one has claimed that assert cannot be made to return on some systems, >yet this is at least the third time that you have responded to some *other* >point as though that claim were being made. Can you say *strawman*? The other objector to my claim that assert() may return has claimed that implementations which have an assert() that can be made to return should be ignored, despite the fact that AT&T UNIX 5.2.1 (and all releases that I know of before it) has exactly this behavior. Dave has repeatedly stated that for all "real" UNIX's assert() never returns, without accepting that this criteria is only true for some flavors of AIX and BSD. In any case, Dave is arguing against reality - the exception proves the argument in this case, and the argument was that assert cannot be relied on to always exit. Providing the single counterexample of SCO Xenix 2.2.3 (and of course, AT&T UNIX 5.2.1) disproves his statement that assert() always exits. [ And yes, he has made that claim, before you state that this is a strawman. ] Anyhow, this is getting old, and has long strayed away from the original topic, which was to be careful of unexpected returns. -- 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
boyd@necisa.ho.necisa.oz (Boyd Roberts) (11/16/90)
In article <18733@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >... In any case, Dave is arguing against reality - the exception proves >the argument in this case, and the argument was that assert cannot be >relied on to always exit. And nor can your CPU be relied upon to function after you've stuck an axe through it. Your whole argument is based on the premise that things don't work `normally' after you've broken them. Get serious. Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''