@need 3200

@node Handling Bugs
@chapter Handling Bugs

@geindex Burroughs, William S.


@example
@group
     Captain Mission did not fear Panic, the sudden
     intolerable knowing that everything is alive.  
     He was himself an emissary of Panic, of the 
     knowledge that man fears above all else: the
     truth of his origin.  It's so close.  Just wipe 
     away the words and look.
@end group
@group
@end group
@end example
@example
@group
                             William S. Burroughs
                             Ghost of a Chance
@end group
@group
@end group
@end example

The Hackerlab C library defines a @geindex bug
@dfn{bug} as a condition within a
running program which is not expected to arise, and which can not
be recovered from if it does arise, but which can not be ruled out
with certainty.


When a bug occurs, the only sane alternative is for the process
to exit with a non-0 status.  By convention, a process which 
exits due to a bug should print an error message on its standard
output stream giving some indication of what bug occurred.


When a fatal condition arises, call @code{panic}.  In tricky code, 
play it safe and test for conditions which should always be 
true by using the macro @code{invariant}. See @ref{Panic}.


If your program needs to quit in some way besides @code{_exit(1)}, you
might want to replace the function @code{panic_exit}.  See @ref{Exiting Due to Panic}.

@menu
* Panic::
* Exiting Due to Panic::
@end menu

@need 3200

@node Panic
@section Panic
@noindent
@strong{#include <hackerlab/bugs/panic.h>}@*
@sp 1

@geindex panic

@geindex invariant


@sp 1
@need 1750
@noindent
@b{* Function} @code{panic}@fuindex panic
@*
@example
@group
int panic (char * str);
@end group
@group
@end group
@end example

Print an error message containing @code{str} on descriptor @code{2} and exit
the process by calling @code{panic_exit}.


This function uses @code{write} to print @code{str}.


This function does not return.

@sp 1
@need 1750
@noindent
@b{* Function} @code{panic_msg}@fuindex panic_msg
@*
@example
@group
int panic_msg (char * str);
@end group
@group
@end group
@end example

Print an error message containing @code{str} on descriptor @code{2}.


This function uses @code{write} to print @code{str}.


This function @emph{does} return.

@sp 1
@need 1750
@noindent
@b{* Macro} @code{invariant}@maindex invariant
@*
@example
@group
void invariant(CONDITION);
@end group
@group
@end group
@end example

Defined as:

@example
@group
  #define invariant(X) invariant_test(X, #X, __FILE__, __LINE__)
@end group
@group
@end group
@end example

If @code{CONDITION} evaluates to @code{0}, write a message to the standard
error output (descriptor @code{2}) and exit by calling @code{panic_exit}.
See @strong{panic}.

@sp 1
@need 1750
@noindent
@b{* Function} @code{invariant_test}@fuindex invariant_test
@*
@example
@group
void invariant_test (int condition, char * str, char * file, int line);
@end group
@group
@end group
@end example

If @code{condition} is @code{0}, write a message to stderr (fd @code{2}) and exit.
See @strong{invariant}.




@need 3200

@node Exiting Due to Panic
@section Exiting Due to Panic
@noindent
@strong{#include <hackerlab/bugs/panic-exit.h>}@*
@sp 1

@geindex exitting on panic


@sp 1
@need 1750
@noindent
@b{* Function} @code{panic_exit}@fuindex panic_exit
@*
@example
@group
void panic_exit (void);
@end group
@group
@end group
@end example

This function is called by @code{panic} to terminate the process with
status @code{1}.  (It does not return.  It calls @code{_exit}.)


For your convenience, this function is defined in its own object
file.  You can define your own version and still link against
this library.  If you do define your own version, @emph{it must not
return}.







