Path: utzoo!attcan!uunet!ora!minya!jc From: jc@minya.UUCP (John Chambers) Newsgroups: comp.unix.wizards Subject: Re: Implementing NULL trapping (was: What machines core dump on deref of NULL?) Message-ID: <423@minya.UUCP> Date: 8 Jul 90 16:02:21 GMT References: <31079@cup.portal.com> <13226@smoke.BRL.MIL> <412@minya.UUCP> <1990Jul5.174608.17336@eci386.uucp> Lines: 83 [Reader Warning: portability horror story follows which may be more than weak hearts can handle; you may wish to hit the 'n' key now. ;-} In article <1990Jul5.174608.17336@eci386.uucp>, clewis@eci386.uucp (Chris Lewis) writes: > To reiterate a remark I made before: > All programmers should be forced to develop their UNIX software > on systems that have a thermonuclear device triggered by the > access bits on page 0.... > I'm just trying to get there myself ;-) > [Yes, I know that NULL isn't necessarily 0 from a C language theoretical > point - I'm just trying to implement a testing mechanism for my specific > implementation...] Part of the reason I find this chain interesting is some fun I had a few years back porting an application to a long list of Unix systems. It was fairly well-written, with lots of builtin error detection, a run-time debug-level flag, and all that. On one system it compiled fine and seemed to run, but it totally ignored all its command-line parameters. This naturally aroused my curiosity. It seems that the program had a set of N routines for chewing up assorted command-line args, essentially a routine for each module. Each routine stripped out the args it found interesting, and left the uninteresting ones in argv[] for the next routine. They were called by code that looked like: args1(&argc,argv); args2(&argc,argv); ... argsN(&argc,argv); and anything left over was treated as a file name, as I recall. Seems quite reasonable. These routines, of course, did some error checking on their params, including making sure they were nonnull and that argv[0] thru argv[*argc-1] were also nonnull. On one particular machine (whose name will be omitted to protect the guilty turkeys who should all be strung up by their toes, but I digress; note that it could be your next system ;-), the folks who put the Unix system together decided, in their wisdom, that page 0 of the D-space shouldn't be used by applications. But they didn't put it out of bounds; they used it for "system" stuff. In particular, since the execve() call needs to stuff its args into the process's data area, they decided to put all the main() args at the start of page 0, starting with argc, then the strings for argv[], then the strings for argv[], then the pointers for these vectors, and then some other junk that isn't relevant here. Do I detect looks of horror forming on the faces of some readers? Yep, you got it right. Page 0 (at virtual address 0) started with argc, so the above calls looked like: args1(0,argv); args2(0,argv); ... argsN(0,argv); And since the routines were written by a Good Programmer, they all tested both args for being NULL, and returned immediately. I "corrected" the code by #ifdefing out the null test on the first argument. I won't repeat the verbal comments that went along with it. I've also used this on occasion to illustrate the Old Engineer's maxim that you can't guarantee the correct functioning of a system by guaranteeing correctness of all its parts. If you examine the design of any one of the parts, each in itself seems like a very reasonable way to do that job. But when you put these particular parts together, the result is a disaster, and you can't point a finger at any one culprit as the "cause". For instance, if the C compiler had used some value other than zero for null, the code would have worked, but the C compiler writers are innocent because in fact zero is a valid representation of null pointers, and they aren't responsible for the OS's memory layout. The memory-management module is innocent, because zero is a valid hardware address, and there's no inherent reason to make any address illegal; that's the job of the memory-allocation module. Completing the argument for each part of the system is left as an exercise for the reader... Just though I'd share this with y'all. (Say "Thank you, jc.") -- Typos and silly ideas Copyright (C) 1990 by: Uucp: ...!{harvard.edu,ima.com,eddie.mit.edu,ora.com}!minya!jc (John Chambers) Home: 1-617-484-6393 Work: 1-508-952-3274