Bizzare Bourne Shell

Jeff Hardy hardy at sdccsu3.UUCP
Sat May 12 08:53:44 AEST 1984


The Bizzare Bourne Shell

The Bourne Shell relies on some very obscure quirks of the VAX/PDP-11 and
Unix.  As many of us know, the Bourne Shell does its own memory allocation
scheme.  This scheme does not necessarily do an sbrk when memory is
allocated, but merely marks the memory as allocated.  When an illegal
reference is made to this memory, the memory fault signal is caught,
the sbrk is done and the program continues on its merry way.  This works
like a charm on the VAX and PDP-11.  It cannot work at all on the MC68000
or very easily on the MC68010.

The reasons this cannot work on the MC68000 are well known, basically the
68000 cannot recover from an illegal memory reference.  It cannot work
easily on the MC68010 because the 68010 can only CONTINUE a faulted
instruction, not RESTART it.  Why this causes the Bourne Shell difficulty
can be explained by:  A memory fault occurs, we enter the USER signal
processing which performs an sbrk, then we want to continue in the
instruction which generated the memory fault.  Unfortunately, we are now
in USER state and we can only continue the instruction by doing an RTE,
which must be done from SYSTEM state!  There are, of course, solutions.
Software continuation of the instruction or a special hook to allow a USER
generated RTE might be possiblities.  But I doubt you could convince me
that they are either easy or not kludges.

What most people who have ported the Bourne Shell have done is to catch
all the places where the "non-allocated" memory might be referenced and
check for the sbrk being done.  This is not terribly pleasant either,
since these references are sprinkled throughout the Bourne Shell.
Fortunately, most are done through macros.  But this only mildly
soothes my angst and ire.

Unix Guru Question:  what is the value of *p after the second sbrk?

	p = sbrk(0); *p = 1; sbrk(2);

The Unix Programmer's Manual says that all newly allocated memory is
initialized to zero.  However, on Unix Version 6, 7, System III and
System V, *p is one!  Indeed, Unix only zeros memory when a new MMU
segment of memory is allocated.  Also, this code will generate a memory
fault if p happens to point to a new MMU segment.  I contend that this
really is a Unix bug, not a "feature".  Either sbrk should not initialize
any memory, or it should always initialize memory.  The half-assed attempt
it does now can only lead to bizzare usages of this "feature".

You guessed it, the Bizzare Bourne Shell depends upon this.  The
Bourne Shell places a pointer into its available space pool at the
location returned from an sbrk(0).  If sbrk were to act as the
documentation indicates, the next time you did an sbrk, it would
corrupt your free list.  Also note that on the VAX and PDP-11 this trick
is guaranteed to work 100% of the time, since if p points to an invalid
address, the Bourne Shell will field the memory fault and do the sbrk,
which initializes the new segment to zero, before the assignment of the
location.  Only careful coding will prevent this on the 68000/68010.

I really question whether a program as critical as the Bourne Shell
should depend upon not merely an undocumented "feature", but one seemingly
CONTRADICTED by the documentation.

These are just a couple of the many interesting quirks in the Bourne Shell.
I will not even comment on those brain-damaged individuals who insist
upon "improving" the C language with macros like IF, THEN, ELSE, or who
fail to use standard include files like <signal.h>.

Michael Christensen
Unix System V Project Manager
Alcyon Corporation



More information about the Comp.unix.wizards mailing list