I wrote this simple exception handler for Linux, which can catch segmentation faults and user defined exceptions, without terminating the program:
Code: Select all
#include "trycatch.bi"
try ' // segmentation fault
dim as long ptr bla
*bla = 42
catch(e as Exception)
if e = SEGMENTATION_FAULT then
print "Fix your pointer!"
else
print "Unknown exception: "+str(e)
end if
endtry
try ' // illegal machine code
asm ud2
catch(e as Exception)
if e = ILLEGAL_INSTRUCTION then
print "Fix your code!"
else
print "Unknown exception: "+str(e)
end if
endtry
try ' // user defined exceptions
throw(42)
catch(e as Exception)
print "Unknown exception: "+str(e)
endtry
Code: Select all
#include "crt/setjmp.bi"
#define ILLEGAL_INSTRUCTION 4
#define BUS_ERROR 7
#define SEGMENTATION_FAULT 11
type sigaction
sa_sigaction as sub(signal as long) ' void (*sa_sigaction) (int, siginfo_t *, void *)
as uinteger sa_mask(1024 / (8*8))
as long sa_flags
sa_restorer as sub()
end type
extern "C"
declare sub sigaction(signal as long, __act as sigaction ptr, __oact as sigaction ptr)
end extern
dim shared as jmp_buf __signal_jmp_buf
dim shared as long __sa_signal, __fault
sub __sigsegv(signal as long)
__sa_signal = signal
longjmp(@__signal_jmp_buf, 1)
end sub
dim shared as sigaction __sa
for i as ulong = 0 to 1024/(8*8)
__sa.sa_mask(i) = 0
next
__sa.sa_restorer = 0
__sa.sa_flags = 0
__sa.sa_sigaction = @__sigsegv()
sigaction(ILLEGAL_INSTRUCTION, @__sa, 0)
sigaction(BUS_ERROR, @__sa, 0)
sigaction(SEGMENTATION_FAULT, @__sa, 0)
#macro try
__fault = setjmp(@__signal_jmp_buf)
if __fault = 0 then
#endmacro
#macro catch(signal)
else
dim signal = __sa_signal
#endmacro
sub throw(signal as long)
__sa_signal = signal
longjmp(@__signal_jmp_buf, signal)
end sub
#define endtry end if
type Exception as long
Code: Select all
try
catch(e as Exception)
if e = 1 then ' SIGHUP
endtry