Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!columbia!rutgers!husc6!cfa!willner
From: willner@cfa.harvard.EDU (Steve Willner)
Newsgroups: comp.lang.forth
Subject: Preventing Crashes
Message-ID: <629@cfa.cfa.harvard.EDU>
Date: Wed, 22-Jul-87 12:06:37 EDT
Article-I.D.: cfa.629
Posted: Wed Jul 22 12:06:37 1987
Date-Received: Fri, 24-Jul-87 04:58:28 EDT
References: 
Organization: Harvard-Smithsonian Ctr. for Astrophysics
Lines: 64
Keywords: crash user application
Summary: dictionary can be protected

In article , 
lord+@andrew.cmu.edu (Tom Lord) writes:
> 2) What work has been done on `crash proof' forth systems?  At what cost to
> execution speed?

Magic/L is a forth-like language with memory management that should
make it nearly crash-proof.  But I've never used it myself, so don't
know how it actually works out in practice.  The vendor is Loki
Engineering, 55 Wheeler St., Cambridge, MA 02138, phone 617-576-0666.
I believe they have a Unix-compatible version of some sort, but you
should contact them for more information.

A forth _application_ (as distinct from a _system_) can be
essentially crash-proof if the programmer does a good job.  I'd
suggest four areas for attention.  None of these compromises
execution speed within the program.

1) The main thing is to prevent storing garbage in unfortunate
locations (like the dictionary).  At a minimum, write extra words so
that users never have to use "!" directly.  If you want to be even
more careful, you can end your program by redefining "!" and related
words so certain parts of memory cannot be changed.  In practice, I
have not found this extreme to be necessary.

2) The second most important thing is to make unavailable any words
that are dangerous (e.g. words that should only be called after
something else has happened.)  A variety of techniques can be used,
depending on the system.  At a minimum, give dangerous words names
that are not likely to be typed by accident.  Most systems have a
smudge bit or some way of (reversibly) making words unrecognizable;
use it to prevent a user from accessing dangerous words.  An easy
alternative is to redefine dangerous words after your program has
used them for the last time so the new word just gives an error
message.  My own technique is to name dangerous words in lower case
and to set the system bit that converts terminal input to upper case.
(Telling users to always set the "caps lock" on the terminal would be
just as effective but would prevent users from typing readable text.)
Or if you're really paranoid, write a parser that only recognizes and
executes selected, safe words and does so only after checking that
all arguments (on stack or elsewhere) are appropriate.

3) Limit the damage.  If "@", "!", or any other words don't check the
stack before or after every execution, redefine them at the end of
the application code so they do.  That way a user-written routine
that makes a stack error will abort immediately rather than calling
more words with wrong values on the stack.

4) For a multitasking system, make sure users can't do something that
hogs the CPU.  Our system, for example, can only switch processes
when it encounters a ";", and all long loops must therefore contain
at least one colon-word so the process can be suspended.  The
solution is to make sure that all loops defined within the
application contain a colon-word, and at the end redefine "DO",
"BEGIN", etc. so they always compile "DUM" (a no-op colon word)
within any loop a user might execute.

These suggestions are not perfect protection, but as a practical
matter they have worked very well in preventing crashes caused by
careless users.  Now if only I could figure out how to prevent
crashes from broken hardware and from bad programs :-) 
-- 
Steve Willner              Phone 617-495-7123        Bitnet: willner@cfa1
60 Garden St.              FTS:      830-7123         UUCP:   willner@cfa
Cambridge, MA 02138 USA  Telex:  921428 satellite cam