
Hardware crashes
****************

This chapter describes how Risc-OS Forthmacs copes with hardware 
exceptions such as Prefetch Errors, Address Errors, and Divide by 
Zero, and offers suggestions about debugging software which causes 
such problems.  

After a hardware exception (or a hardware-like trap) such as an 
Address Error, Prefetch Error, Divide-by-Zero, etc, Risc-OS Forthmacs 
will attempt to recover.  The state of the registers and the stacks 
just before the crash is stored in a safe place, where it may be 
examined with SHOWCRASH. 

All registers are saved to the REGISTERS buffer.  The BUG vocabulary 
holds tools for handling the registers saved to this area.  There are 
objects called RR0 RR1 RTOP RSP RPC RSR ... that can be inspected and 
changed by the user.  An example: 

         h# fffffff @
                  ------ an exception occurs
         showcrash
         rtop .    h# 8000 to rtop
         showcrash  rtop .
         (restart

This is used by several debugger tools and can be freely extended by 
user applications.  


Error handling
==============

The error-handling is rather complex in this implementation, all 
hardware- or hardware related errors are managed within 
Risc-OS Forthmacs runtime system, processor-mode problems are hidden 
before you, and you will have to remember one single level of 
ERROR-MANAGING .  

All error conditions at last use ERROR-HANDLE later branching to the 
appropriate specialized error-handler.  You may redefine the handler 
according to your needs.  The error handlers: 

    : serve-error       \ ( -- ) standard error handler
        up@ main-task =
        if ??cr beep error-output why restore-output then
        abort ;
    
    defer handle-error      ' serve-error is handle-error
    defer handle-breakpoint ' serve-error is handle-breakpoint
    defer handle-escape     ' serve-error is handle-escape
    defer handle-data       ' serve-error is handle-data
    defer handle-address    ' serve-error is handle-address
    defer handle-prefetch   ' serve-error is handle-prefetch
    defer handle-div0       ' serve-error is handle-div0


HANDLE-ERROR, all RiscOS error calls go via this handler, use this to 
generate your own error conditions.  WHY will work perfectly with 
this.  

HANDLE-BREAKPOINT, a breakpoint instruction OS_BreakPt will go via 
this handler.  

HANDLE-ESCAPE, escape conditions use this handler, currently this 
works like a Risc-OS Forthmacs "reset" key outside the EXPECT loop.  

HANDLE-ADDRESS, tried to access memory above $3ffffff.  

HANDLE-DATA/PREFETCH, access to data/instructions was aborted from the 
MMU, there wasn't any memory.  

HANDLE-DIV0, tried to divide by zero 


Debugging Tools Glossary
========================


________________________________________________________________________
(RESTART            ( -- )                   bug            
Restart Risc-OS Forthmacs after a hardware crash, the registers must 
have been saved before (this is done by the error-handler), (RESTART 
takes care about the cpu status.  

This can be used for developing debuggers, virtual memory managers 
etc.  

Implementation Note: For security reasons, (RESTART can't set 
supervisor mode.  This restricts debuggers using this word to user 
mode debugging.  You could easily change this by adding the 
"set-supervisor-mode" swi in the (RESTART code.  


________________________________________________________________________
.REGISTERS          ( -- )                                  
dot-registers
Displays the CPU registers values that were saved the last time that a 
breakpoint or exception occurred.  

The contents of the PC have been split to the program-counter RPC and 
the status/flag register RSR 


________________________________________________________________________
.SR                 ( --  )                                 
Decodes and displays the contents of the ARM Status Register part of 
the PC register that was saved at the last breakpoint or exception.  
The Status Register contains the Condition Codes, the Priority level 
and the interrupt level.  The display looks something like this: 
         nZcvif    user mode
"nZcvif" is the condition codes.  An upper case letter indicates that 
the corresponding bit is on.  In the case the "Z" (zero) bit is on and 
the other bits (Negative, Carry, oVerflow and the mode registers) are 
off.  


________________________________________________________________________
.STACK              ( --  )                                 dot-stack
Displays the Data Stack saved at the last breakpoint or exception.  If 
the breakpoint occurred as a result of a RiscOS signal, the system may 
have been executing a system call at the time of the signal.  If so, 
there may be extra stuff on the stack such as C procedure activation 
frames.  


________________________________________________________________________
FTRACE              ( -- )                                  
Display the return stack after a crash, if the return stack pointer 
was outside the Risc-OS Forthmacs stack, there will only rudimentary 
information be given.  Tries to give not the cfa's but the words real 
names.  


________________________________________________________________________
HANDLE-ADDRESS      ( --  )                  Deferred, System  
This handler is used whenever an address exception has happened, 
mostly cause by a wrong address using @ ! etc.  

Risc-OS Forthmacs has a common error handler for all kinds of errors.  
This handler takes care of cpu state, operating system level etc.  All 
register data can be found in REGISTERS , r0 at the lowest address.  
The stacks are saved at RSSAVE and PSSAVE .  

See: SHOWCRASH At it's end it jumps into the error-specific handler, 
by default this is SERVE-ERROR in all cases, but you can install your 
own error handling code instead.  The cpu level debugger uses 
HANDLE-BREAKPOINT, virtual memory could be implemented easily using 
HANDLE-DATA and HANDLE-ADDRESS. 

See: SHOWCRASH 


________________________________________________________________________
HANDLE-BREAKPOINT   ( --  )                  Deferred, System  
This handler is executed whenever a OS_Breakpt instruction was 
trapped.  Use this for more advanced debugging tools.  

See: HANDLE-ADDRESS 


________________________________________________________________________
HANDLE-DATA         ( --  )                  Deferred, System  
This handler is used whenever a data abort has happened, mostly cause 
by a wrong address using @ ! etc.  

See: HANDLE-ADDRESS 


________________________________________________________________________
HANDLE-DIV0         ( --  )                  Deferred, System  
This (emulated) exception is executed when a divide by zero error has 
happened.  

See: HANDLE-ADDRESS 


________________________________________________________________________
HANDLE-ERROR        ( --  )                  Deferred, System  
This handler is used when errors requested by you take place.  Use 
this for your application specific error handling.  

See: HANDLE-ADDRESS 


________________________________________________________________________
HANDLE-ESCAPE       ( --  )                  Deferred, System  
This handler is used when an escape condition has happened.  Escape 
conditions can be generated by pressing the Ctrl-Sh-F12 key.  


See: HANDLE-ADDRESS 


________________________________________________________________________
HANDLE-PREFETCH     ( --  )                  Deferred, System  
This handler is used whenever a prefetch abort has happened, usually 
caused by executing code in nirvana.  

See: HANDLE-ADDRESS 


________________________________________________________________________
REGISTERS           ( -- addr  )             bug            
The address of a buffer holding all register contents after the last 
exception.  


________________________________________________________________________
RR0                 ( -- n )                 bug            
n is the value contained in the saved copy of register r0.  RR0 may be 
modified with the TO command.  Other data register names are RR0, RSP 
etc.  

See: TO .REGISTERS 


________________________________________________________________________
RPC                 ( -- n )                 bug            
n is the value contained in the saved copy of the Program Counter.  
This value is used as the address where the program is restarted for 
the STEP , STEPS , and CONTINUE commands.  RPC may be modified with 
the TO command.  Pipeline effects have been cleared.  


________________________________________________________________________
RSP                 ( -- n )                 bug            
n is the value contained in the saved copy of the Stack Pointer.  


________________________________________________________________________
RSR                 ( -- n )                 bug            
n is the value contained in the saved copy of the Status Register.  
The Status Register contains the Condition Codes, the Priority level 
and the Interrupt level.  RSR may be modified with the TO command.  

See: .SR 


________________________________________________________________________
RUP                 ( -- n )                 bug            
n is the value contained in the saved copy of the User-area Pointer.  

See: RR0 


________________________________________________________________________
SHOWCRASH           ( --  )                                 
Displays all the information saved at the last breakpoint or exception 
including the registers (as in .REGISTERS), the data stack (as in 
.STACK), and the return stack (as in FTRACE). 

