comp.sys.acorn (1647/1650) Path: cix!slxsys!uknet!acorn!enevill From: enevill@acorn.co.uk (Edward Nevill) Newsgroups: comp.sys.acorn Subject: Re: Trap handling in C Message-ID: <12372@acorn.co.uk> Date: 24 Jan 92 12:26:00 GMT References: <1992Jan20.090419.17124@rdg.dec.com> Sender: enevill@acorn.co.uk Distribution: comp Organization: Acorn Computers Ltd, Cambridge, England Lines: 77 In article <1992Jan20.090419.17124@rdg.dec.com> goodwin@system.enet.dec.com (Pete Goodwin) writes: >I wanted to use this to catch faults in my 3d front end to PVray (!Model) and >exit gracefully without wiping the current picture I've spent ages building up. >Trouble is, it didn't seem to work. I got the usual "Application !Model has a >fatal error (type=2) and must exit immediately". I lost a fiddly picture this >way (sob!). > >Why won't: > >signal(SIGFPE, trap_routine); >signal(SIGSEGV, trap_routine); >signal(SIGILL, trap_routine); > >call my trap_routine? All I want to do is dump the edited picture and exit. The message "Application ... and must exit immediately" is generated by a signal handler which is installed by 'wimpt_init'. If you wish to replace this signal handler with one of your own you must install your signal handler AFTER the call to wimpt_init. The complete list of signals which you will probably need to catch is Name Type SIGFPE 2 Aritmetic exception (eg divide by 0) SIGILL 3 Illegal instruction executed SIGSEGV 5 Data abort or address exception SIGSTAK 6 Stack overflow SIGOSERROR 10 Error generated by non X form SWI call Note, if you trap SIGSTAK your signal handler must be compiled with stack checking disabled, otherwise a second SIGSTACK will be generated immediately on entry to your signal handler and the error "Trap while in trap handler" will be generated. To disable stack checking put #pragma -s1 before your signal handler and #pragma -s0 after your signal handler to re-enable stack checking. The is a limited amount of stack available to your SIGSTAK handler so you should not do anything which may require stack space. The best way around this is to 'longjmp' out of your signal handler back to 'main'. This will unwind the stack and free up enough stack space for you to save your picture. So, the code looks something like. static jmp_buf env; #pragma -s1 static void my_handler(sig : integer) { longjmp(env, sig); } #pragma -s0 int main(void) { ... wimpt_init(...); signal(SIGFPE, my_handler); signal(SIGILL, my_handler); signal(SIGSEGV, my_handler); signal(SIGSTAK, my_handler); signal(SIGOSERROR, my_handler); if (setjmp(env)) { signal(SIGFPE, SIG_DFL); /* disable signal handlers in case */ signal(SIGILL, SIG_DFL); /* something nasty happens while */ signal(SIGSEGV, SIG_DFL); /* trying to save picture */ signal(SIGSTAK, SIG_DFL); signal(SIGOSERROR, SIG_DFL); ... /* save picture */ exit(1); } }