// I nominate this to be the Spring libg++ exception handling code. // // Note that it contains Sparc dependent machine code for the log. // // - Graham typedef int jmp_buf[9]; struct ExceptionHandler { ExceptionHandler *prev; jmp_buf handler; void *name; void *parameters; ExceptionHandler (); ExceptionHandler (int x, int y, int z); ~ExceptionHandler (); }; #include #undef _X_H #pragma implementation "x.h" #include "/tools/cygnus/test-os/interfaces/util/x.h" extern "C" void exit (int); ExceptionHandler EHS (1,2,3); ExceptionHandler::ExceptionHandler (int x, int y, int z) { exceptionHandlerStack = &EHS; if (setjmp (EHS.handler)) { printf ("*** Unhandled exception ***\n"); exit (22); } } extern "C" void __unhandled_exception (const char*, int); extern "C" void __raise_exception (void **, void *); // The history of raises is mainatined as acourtesy to our users. // It is only approximately true - we don't lock on updates. int raises_pcs[32]; void *raises_exceptions[32]; int raises_index; void __unhandled_exception(const char *filename, int lineno) { printf ("unhandled exception caught in file `%s' at line %d\n",filename, lineno); printf ("Recent raises : \n"); int index = raises_index; for (int i = 0 ; i < 6 ; i++) { index = (index-1) & 31; if (raises_pcs[index] == 0) { break; } printf (" raising pc = 0x%X, exception = 0x%X\n", raises_pcs[index], raises_exceptions[index]); } printf (" ......\n"); printf ("*** Unhandled exception ***\n"); exit(22); } void __raise_exception (void **addr, void *id) { // Log the exception register int ____return_pc asm ("%i7"); raises_pcs[raises_index] = ____return_pc; raises_exceptions[raises_index] = id; raises_index = (raises_index + 1) & 31; // Do the real work: *addr = id; }