Need help on Try-Catch-Throw Linux version

Linux specific questions.
Post Reply
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Need help on Try-Catch-Throw Linux version

Post by marpon »

I've done some experiments with windows here viewtopic.php?f=6&t=26189&p=241236#p241236

now i'm simulating the linux version, the try-catch-throw are using the same type of code using setjmp/longjmp functions but the trapping of the system errors, signals in fact are differents on the linux versus windows

i made here an exercice , is it working on linux ? i don't know
is it compiling on 32 and 64 ?
is it trapping the signals ctrol-c (SIGINT) , segmentation fault (SIGSEGV ) etc...

i've put different possibilities of code , inside or outside Try-catch blocks , to test the trapping

Please play with, and better please report what you found.

has to be compiled with console ...

Thanks in advance for your support. :-)

note : as i wanted to simulate how it is working in windows , you will find plenty of #ifdef __FB_WIN32__ on the code
please don't care, a final version (if any) will be cleaned

Code: Select all

#ifdef __FB_WIN32__ 
# Include once "windows.bi" 
#endif
# Include once "crt/setjmp.bi"                   'setjmp/longjmp usage
# Include once "crt/string.bi"                   'memmove usage

#define SIG_IGN cptr(any ptr, 1)

Const SIGHUP        = 1 'Hangup (POSIX)
Const SIGINT        = 2 'Terminal interrupt (ANSI)
Const SIGQUIT       = 3 'Terminal quit (POSIX)
Const SIGILL        = 4 'Illegal instruction (ANSI)
Const SIGTRAP       = 5 'Trace trap (POSIX)
Const SIGIOT        = 6 'IOT Trap (4.2 BSD)
Const SIGBUS        = 7 'BUS error (4.2 BSD)
Const SIGFPE        = 8 'Floating point exception (ANSI)
Const SIGKILL       = 9 'Kill (can't be caught or ignored) (POSIX)
Const SIGUSR1       = 10 'User defined signal 1 (POSIX)
Const SIGSEGV       = 11 'Invalid memory segment access (ANSI)
Const SIGUSR2       = 12 'User defined signal 2 (POSIX)
Const SIGPIPE       = 13 'Write on a pipe with no reader, Broken pipe (POSIX)
Const SIGALRM       = 14 'Alarm clock (POSIX)
Const SIGTERM       = 15 'Termination (ANSI)
Const SIGSTKFLT     = 16 'Stack fault
Const SIGCHLD       = 17 'Child process has stopped or exited, changed (POSIX)
Const SIGCONT       = 18 'Continue executing, if stopped (POSIX)
Const SIGSTOP       = 19 'Stop executing (can't be caught or ignored) (POSIX)
Const SIGTSTP       = 20 'Terminal stop signal (POSIX)
Const SIGTTIN       = 21 'Background process trying to read, from TTY (POSIX)
Const SIGTTOU       = 22 'Background process trying to write, to TTY (POSIX)
Const SIGURG        = 23 'Urgent condition on socket (4.2 BSD)
Const SIGXCPU       = 24 'CPU limit exceeded (4.2 BSD)
Const SIGXFSZ       = 25 'File size limit exceeded (4.2 BSD)
Const SIGVTALRM     = 26 'Virtual alarm clock (4.2 BSD)
Const SIGPROF       = 27 'Profiling alarm clock (4.2 BSD)
Const SIGWINCH      = 28 'Window size change (4.3 BSD, Sun)
Const SIGIO         = 29 'I/O now possible (4.2 BSD)
Const SIGPWR        = 30 'Power failure restart (System V)
Const NSIG			  = 32 

# define VERBOSE 			0
   	' 0 not verbose , else  verbose mode

#Define TRY do : my_except_class.e_ptr = get_set_excep(1) : _
	my_except_class.e_data[my_except_class.e_pos].icod = setjmp2(my_except_class.e_data[my_except_class.e_pos].jump) : _
	If my_except_class.e_data[my_except_class.e_pos].icod = 0 Then : _
	if VERBOSE THEN print space(my_except_class.e_pos) & "in Try block , e_pos = " & my_except_class.e_pos

#Macro CATCH(e , _type)
	ElseIf my_except_class.e_data[my_except_class.e_pos].got = 1 and my_except_class.e_data[my_except_class.e_pos].icod < 0 then 
		show_catch(my_except_class.e_data[my_except_class.e_pos])
	elseif  my_except_class.e_data[my_except_class.e_pos].got = 1 and  my_except_class.e_data[my_except_class.e_pos].icod = _type Then  		
		Dim As exdata_type e =  my_except_class.e_data[my_except_class.e_pos]
		if VERBOSE THEN print space(my_except_class.e_pos) & " in Catch block , e_pos = " & my_except_class.e_pos
#EndMacro

#Macro CATCH_ANY(e)
	ElseIf my_except_class.e_data[my_except_class.e_pos].got = 1 and my_except_class.e_data[my_except_class.e_pos].icod < 0 then 
		show_catch(my_except_class.e_data[my_except_class.e_pos])
	ElseIf my_except_class.e_data[my_except_class.e_pos].got = 1 then     													
		Dim As exdata_type e = my_except_class.e_data[my_except_class.e_pos]
		if VERBOSE THEN print space(my_except_class.e_pos) & " in Catch_any block , e_pos = " & my_except_class.e_pos
#EndMacro

#Define FINALLY End If:  If my_except_class.e_pos Then

#Define END_TRY  if my_except_class.e_pos then :  my_except_class.e_ptr = get_set_excep(-1) : end if : End If  : exit do : loop

#Define THROW(_type)  set_throw ( __FILE__, __FUNCTION__, __LINE__, "", _type)

#Define THROW_MSG(_type , mess)  set_throw ( __FILE__, __FUNCTION__, __LINE__, mess, _type)

#Define RETHROW   set_rethrow()

Type exdata_type
	jump   As jmp_buf Ptr
	icod   As long
	file   As String
	proc   As String
	msg    As String
	line   As long
	got    As byte
End Type

Type my_except_class
	public:
		declare constructor()
		declare destructor()
		declare sub back_except()
		declare sub decrease_except()
		declare sub increase_except()

		Static e_pos   As long
		Static e_data  As exdata_type Ptr
		Static e_ptr	As my_except_class Ptr
		Static countID As long
	private:
		e_size As long
End Type

declare function raise cdecl alias "raise"(byval signal as long) as long
Declare Function Signal cdecl  alias "signal" (ByVal V_Signal As long, byval V_Function As Any Ptr) as Any Ptr

declare function get_set_excep(byval iflag as long = 0) as my_except_class ptr
declare sub show_catch(byref e as exdata_type, byval flag as integer = 1)
declare sub set_throw( byref sfile as string, byref sproc as string, byval iline as long, byref smess as string, byval lcode as long)
declare sub set_rethrow()

#ifdef __FB_WIN32__ 
	declare function setjmp2 cdecl alias "_setjmp"(byval as jmp_buf ptr , byval as any ptr = 0) as long
#else
	declare function setjmp2 cdecl alias "setjmp" (byval as jmp_buf ptr) as long
#endif

'# ifdef _EXCEPTIONS_INIT_CODE_

	declare sub trap_signals()

	Dim As long 					my_except_class.countID = 0
	Dim As long 					my_except_class.e_pos = 0
	Dim As exdata_type Ptr 		my_except_class.e_data = 0
	Dim As my_except_class Ptr my_except_class.e_ptr = 0

	Private Constructor my_except_class()
		if my_except_class.countID = 0 then
			e_size = 4     'initial level setting normally not needed more , but reallocation is installed
			my_except_class.e_data = callocate (sizeof(exdata_type) * e_size)
			my_except_class.e_data[0].jump = 0
			my_except_class.e_data[0].file = ""
			my_except_class.e_data[0].proc = ""
			my_except_class.e_data[0].msg = ""
			my_except_class.e_data[0].line = 0
			my_except_class.e_data[0].icod = 0
			my_except_class.e_data[0].got = 0
			my_except_class.countID = 1
			my_except_class.e_pos = 0
		end if
	End Constructor

	Private Destructor my_except_class()
		if my_except_class.e_data <> 0 and my_except_class.countID = 1 then
			while my_except_class.e_pos >= 0
				if my_except_class.e_data[my_except_class.e_pos].jump THEN delete my_except_class.e_data[my_except_class.e_pos].jump
				my_except_class.e_pos -= 1
			wend
			e_size = 0
			deallocate(my_except_class.e_data)
		end if
		my_except_class.countID = 0
		my_except_class.e_data = 0
		my_except_class.e_pos = 0
	End Destructor

	Private sub my_except_class.back_except()
		if my_except_class.e_pos < 2 then exit sub
		if my_except_class.e_data[my_except_class.e_pos].jump THEN delete my_except_class.e_data[my_except_class.e_pos].jump
		my_except_class.e_data[my_except_class.e_pos].jump = 0
		my_except_class.e_data[my_except_class.e_pos - 1].icod = my_except_class.e_data[my_except_class.e_pos].icod
		my_except_class.e_data[my_except_class.e_pos].icod = 0
		my_except_class.e_data[my_except_class.e_pos - 1].got = my_except_class.e_data[my_except_class.e_pos].got
		my_except_class.e_data[my_except_class.e_pos].got = 0
		my_except_class.e_data[my_except_class.e_pos - 1].file = my_except_class.e_data[my_except_class.e_pos].file
		my_except_class.e_data[my_except_class.e_pos].file = ""
		my_except_class.e_data[my_except_class.e_pos - 1].proc = my_except_class.e_data[my_except_class.e_pos].proc
		my_except_class.e_data[my_except_class.e_pos].proc = ""
		my_except_class.e_data[my_except_class.e_pos - 1].msg = my_except_class.e_data[my_except_class.e_pos].msg
		my_except_class.e_data[my_except_class.e_pos].msg = ""
		my_except_class.e_data[my_except_class.e_pos - 1].line = my_except_class.e_data[my_except_class.e_pos].line
		my_except_class.e_data[my_except_class.e_pos].line = 0
		my_except_class.e_pos -= 1
	end sub

	Private sub my_except_class.decrease_except()
		if my_except_class.e_pos < 1 then exit sub
		if my_except_class.e_data[my_except_class.e_pos].jump THEN delete my_except_class.e_data[my_except_class.e_pos].jump
		my_except_class.e_data[my_except_class.e_pos].jump = 0
		my_except_class.e_data[my_except_class.e_pos].icod = 0
		my_except_class.e_data[my_except_class.e_pos].got = 0
		my_except_class.e_data[my_except_class.e_pos].file = ""
		my_except_class.e_data[my_except_class.e_pos].proc = ""
		my_except_class.e_data[my_except_class.e_pos].msg = ""
		my_except_class.e_data[my_except_class.e_pos].line = 0
		my_except_class.e_pos-= 1
	end sub

	Private sub my_except_class.increase_except()
		if my_except_class.e_pos + 1 = e_size  THEN
			dim as exdata_type Ptr ptemp2 = callocate(sizeof(exdata_type) * e_size * 2)
			if ptemp2 = 0 THEN
				#ifdef _INC_WINDOWS
					messagebox 0, "Close to abort !", "error .... reallocating", MB_ICONERROR
				#else
					print "error .... reallocating,  terminate now!": print
					sleep 5000
				#endif	
				raise(4)
			else
				memmove(ptemp2, my_except_class.e_data, sizeof(exdata_type) * e_size)
				deallocate(my_except_class.e_data)
         END IF
			my_except_class.e_data = ptemp2
			e_size *= 2
			if VERBOSE then print "reallocating... done"
		END IF
		my_except_class.e_pos += 1
		my_except_class.e_data[my_except_class.e_pos].jump = new jmp_buf
		my_except_class.e_data[my_except_class.e_pos].icod = 0
		my_except_class.e_data[my_except_class.e_pos].got = 0
		my_except_class.e_data[my_except_class.e_pos].file = ""
		my_except_class.e_data[my_except_class.e_pos].proc = ""
		my_except_class.e_data[my_except_class.e_pos].msg = ""
		my_except_class.e_data[my_except_class.e_pos].line = 0
	end sub

	Private function get_set_excep(byval iflag as long = 0) as my_except_class ptr
		if iflag = 0  and my_except_class.e_ptr = 0 THEN
			'print "init0 here "
			my_except_class.e_ptr = new my_except_class
		elseif iflag < 0 and my_except_class.e_ptr <> 0 then
			'print "decrease here "
			my_except_class.e_ptr->decrease_except()
		elseif iflag > 0 and my_except_class.e_ptr <> 0 then
			'print "increase here "
			my_except_class.e_ptr->increase_except()
		elseif iflag > 0 and my_except_class.e_ptr = 0 then
			'print "init1 here "
			my_except_class.e_ptr = new my_except_class
			my_except_class.e_ptr->increase_except()
		END IF
		return my_except_class.e_ptr
	end function

	Private sub set_throw( byref sfile as string, byref sproc as string, byval iline as long, byref smess as string, byval lcode as long)
		dim as long _e_pos_ = my_except_class.e_pos
		dim as exdata_type Ptr _exdata_type_ptr_ = my_except_class.e_data

		_exdata_type_ptr_[_e_pos_].file = sfile
		_exdata_type_ptr_[_e_pos_].proc = sproc
		_exdata_type_ptr_[_e_pos_].line = iline
		_exdata_type_ptr_[_e_pos_].msg = smess
		_exdata_type_ptr_[_e_pos_].icod = lcode
		_exdata_type_ptr_[_e_pos_].got = 1
		if _e_pos_ > 0 THEN
			longjmp(_exdata_type_ptr_[_e_pos_].jump, lcode)
		else
			show_catch(_exdata_type_ptr_[0], 0)
		end if
	end sub

	Private sub set_rethrow()
		dim as my_except_class ptr  _except_ptr_ = my_except_class.e_ptr
		dim as long _e_pos_ = my_except_class.e_pos
		dim as exdata_type Ptr _exdata_type_ptr_ = my_except_class.e_data

		if _e_pos_ > 1 and _exdata_type_ptr_[_e_pos_].got = 1 THEN
			_except_ptr_->back_except()
			_e_pos_ -= 1
			longjmp(_exdata_type_ptr_[_e_pos_].jump, _exdata_type_ptr_[_e_pos_].icod)
		end if
	end sub

	Private sub show_catch(byref e as exdata_type, byval flag as integer = 1)
		dim as string status
		dim as long e_pos = my_except_class.e_pos
		if flag THEN
			if VERBOSE THEN Print space(e_pos) & "  e_exceptions message : " ; e.msg
			status = "e_exceptions message : " & e.msg
		else
			if VERBOSE THEN Print space(e_pos) & "  error exceptions : Throw outside Try-Catch bloc   "  & e.msg
			status =  "error exceptions : Throw outside Try-Catch bloc"  & chr(10,10) & "e_exceptions message : " & e.msg
		END IF
		if VERBOSE THEN Print space(e_pos) & "   e_exception code = " ; Str(e.icod)
		status &= chr(10,10) & "   e_exception code = " & Str(e.icod)
		if VERBOSE THEN Print space(e_pos) & "   file = " ; e.file
		status &= chr(10) & "   file = " & e.file
		if VERBOSE THEN Print space(e_pos) & "   proc = " ; e.proc
		status &= chr(10) & "   proc = " & e.proc
		if VERBOSE THEN Print space(e_pos) & "   line = " ; Str(e.line)
		status &= chr(10) & "   line = " & Str(e.line)
		if flag  and e.icod > 0 then
			#ifdef _INC_WINDOWS
				messagebox 0, status, "Catched Exception ", MB_ICONWARNING
			#else
				print "Catched Exception " : print "    " ; status : print
			#endif
		elseif flag  and e.icod < -99  THEN
			trap_signals
			#ifdef _INC_WINDOWS
				messagebox 0, status, "Catched Exception ", MB_ICONWARNING
			#else
				print "Catched Exception " : print "    " ; status : print
			#endif
		elseif e.icod < 0  and e.icod > -100 THEN
			#ifdef _INC_WINDOWS
				messagebox 0, status & chr(10, 10) & "Abort now!", "Catched Exception : Error", MB_ICONERROR
			#else
				print "Catched Exception " : print "    " ; status : print : print "Abort now!"
				sleep 5000
			#endif
			end(e.icod)
		elseif flag = 0 and e_pos = 0 THEN
			trap_signals
			#ifdef _INC_WINDOWS
				messagebox 0, status & chr(10, 10) & "Abort now!", "Thrown Exception  wihout Try_Catch", MB_ICONERROR
			#else
				print "Thrown Exception  wihout Try_Catch " : print "    " ; status : print : print "Abort now!"
				sleep 5000
			#endif
			end(e.icod)	
		end if
	end sub

	sub sig_SIGFPE cdecl()
		Signal(SIGFPE,  SIG_IGN )
		THROW_MSG(- SIGFPE , "got SIGFPE!")
	end sub

	sub sig_SIGSEGV cdecl()
		Signal(SIGSEGV,  SIG_IGN )
		THROW_MSG(- SIGSEGV , "got SIGSEGV!")
	end sub

	sub sig_SIGINT cdecl()
		print "in SIGINT"
		Signal(SIGINT,  SIG_IGN )
		THROW_MSG(- (SIGINT +100) , "got SIGINT!")
	end sub

	sub sig_SIGILL cdecl()
		Signal(SIGILL,  SIG_IGN )
		THROW_MSG(- SIGILL , "got SIGILL!")
	end sub

  	 /' sub sig_SIGABRT cdecl()
		Signal(SIGABRT,  SIG_IGN )
		THROW_MSG(- SIGABRT , "got SIGABRT!")
	end sub  '/  

	sub sig_SIGTERM cdecl()
		Signal(SIGTERM,  SIG_IGN )
		THROW_MSG(- SIGTERM , "got SIGTERM!")
	end sub

  	 /' sub sig_SIGBREAK cdecl()
		Signal(SIGBREAK,  SIG_IGN )
		THROW_MSG(- SIGBREAK , "got SIGBREAK!")
	end sub   '/ 

	sub sig_SIGSTKFLT cdecl()
		Signal(SIGSTKFLT,  SIG_IGN )
		THROW_MSG(- SIGSTKFLT , "got SIGSTKFLT!")
	end sub

	sub sig_SIGBUS cdecl()
		Signal(SIGBUS,  SIG_IGN )
		THROW_MSG(- SIGBUS , "got SIGBUS!")
	end sub
	
	sub sig_SIGTRAP cdecl()
		Signal(SIGTRAP,  SIG_IGN )
		THROW_MSG(- (SIGTRAP + 100) , "got SIGTRAP!")
	end sub
	
	sub sig_SIGTSTP cdecl()
		Signal(SIGTSTP,  SIG_IGN )
		THROW_MSG(- (SIGTSTP + 100) , "got SIGTSTP!")
	end sub
	
	sub sig_SIGSTOP cdecl()
		Signal(SIGSTOP,  SIG_IGN )
		THROW_MSG(- (SIGSTOP  + 100), "got SIGSTOP!")
	end sub

	sub sig_SIGUSR1 cdecl()
		Signal(SIGUSR1, SIG_IGN )
		THROW_MSG(- (SIGUSR1  + 100), "got SIGUSR1!")
	end sub
	
	sub sig_SIGUSR2 cdecl()
		Signal(SIGUSR2, SIG_IGN )
		THROW_MSG(- (SIGUSR2 + 100) , "got SIGUSR2!")
	end sub
		
	sub sig_NSIG cdecl()
		Signal(NSIG, SIG_IGN )
		THROW_MSG(- (NSIG  + 100), "got NSIG!")
	end sub
	
	sub sig_SIGHUP cdecl()
		Signal(SIGHUP, SIG_IGN )
		THROW_MSG(- (SIGHUP  + 100), "got SIGHUP!")
	end sub
	
	sub trap_signals()
		signal(SIGSEGV , SIG_IGN)
		signal(SIGSEGV , @sig_SIGSEGV)
		signal(SIGFPE , SIG_IGN)
		signal(SIGFPE , @sig_SIGFPE)
		signal(SIGINT , SIG_IGN)
		signal(SIGINT ,  @sig_SIGINT)
		signal(SIGILL , SIG_IGN)
		signal(SIGILL , @sig_SIGILL)
		 /' signal(SIGABRT , SIG_IGN)
		signal(SIGABRT ,  @sig_SIGABRT) '/   
		signal(SIGTERM , SIG_IGN)
		signal(SIGTERM , @sig_SIGTERM)
		 /' signal(SIGBREAK , SIG_IGN)
		signal(SIGBREAK ,  @sig_SIGBREAK) '/   
		signal(SIGSTKFLT , SIG_IGN)
		signal(SIGSTKFLT , @sig_SIGSTKFLT)
		'#ifdef __FB_LINUX__
			signal(SIGBUS , SIG_IGN)
			signal(SIGBUS , @sig_SIGBUS)	
		'#endif
		signal(SIGTRAP , SIG_IGN)
		signal(SIGTRAP , @sig_SIGTRAP)
		signal(SIGSTOP , SIG_IGN)
		signal(SIGSTOP , @sig_SIGSTOP)
		signal(SIGTSTP , SIG_IGN)
		signal(SIGTSTP , @sig_SIGTSTP)
		signal(SIGUSR1 , SIG_IGN)
		signal(SIGUSR1 , @sig_SIGUSR1)
		signal(SIGUSR2 , SIG_IGN)
		signal(SIGUSR2 , @sig_SIGUSR2)
		signal(NSIG , SIG_IGN)
		signal(NSIG , @sig_NSIG)
		signal(SIGHUP , SIG_IGN)
		signal(SIGHUP , @sig_SIGHUP)
	end sub

	'#	undef _EXCEPTIONS_INIT_CODE_
	if my_except_class.countID = 0 THEN
		if VERBOSE then print "initialisation "
		my_except_class.e_ptr = get_set_excep()
		my_except_class.countID = 1
		trap_signals()
	end if
'#endif  /' _EXCEPTIONS_INIT_CODE_ '/
'**********************************************************************************************
'End of the commun part to put into an include header
'********************************************************************************************** 

'**********************************************************************************************
'utility functions / defines for test 
'********************************************************************************************** 

' define e_exception types
#Define DIVISION_BY_ZERO	221                     ' can be any number
#Define FORCED_TO_ZERO 		222                     ' can be any number
#Define NOTHING_EX 			250                     ' can be any number

' function that can throw an e_exceptions
Function div1(byval a As Integer , byval b As Integer) As double
	if b = 0 and a = 0 THEN
		raise(SIGINT)                                  '' Breakpoint (INT 3)
   END IF
   If b = 0 Then THROW_MSG(DIVISION_BY_ZERO, "Division by zero")
	If b > a Then THROW_MSG(FORCED_TO_ZERO, "Forced to zero")	
	TRY
		if  b < a Then THROW_MSG(NOTHING_EX, "nothing noticed")
	CATCH_ANY(e)
		show_catch(e)
	FINALLY
		Print  " div result printed"
	END_TRY
   Return a / b
End Function

' test function (calls div):
Function add_div(byval a As Integer , byval b As Integer , byval c As Single) As Integer
   Return div1(a + b , c)
End Function

' test func:
Sub test()
	TRY
		TRY
			print "test again ctrl-c in try-catch block or any key to continue" : sleep
			Print add_div(10 , 5 , 1)
		CATCH_ANY(e)
			show_catch(e)	
		FINALLY
			Print  " div 1 done"
		END_TRY
		TRY
			Print add_div(10 , 5 , 0)
		CATCH_ANY(e)
			show_catch(e)
		FINALLY
			Print  " div 2 done"
		END_TRY
		TRY
			Print add_div(10 , 5 , 30)
		CATCH_ANY(e)
			show_catch(e)
		FINALLY
			Print  " div 3 done"
		END_TRY
		TRY
			Print add_div(0 , 0 , 0)
		CATCH_ANY(e)
			show_catch(e)
		FINALLY
			Print  " div 4 done"
		END_TRY 
		print "put a breakpoint here"	
		raise(SIGINT)                                   '' Breakpoint (INT 3)
	CATCH_ANY(e)
		print "catched something global in test()"
		show_catch(e)
		RETHROW
	FINALLY
		print "finally test()"		
	END_TRY
End Sub


sub stack_overflow()
  dim as long  foo(10000)'allocate something big on the stack
  print "loop"
  stack_overflow()
end sub

' This function can overflow the call stack.
function sum1to(byval n as ulong) as ulong
    if n = 0 then 
        return 0
    else 
        dim as ulong m = sum1to(n - 1)
        return m + n
    end if
end function

sub create_segflt()
	print : print "test a segmentation fault here"    
	dim intPtr as integer ptr = 0
	intPtr[10] = 1  
END SUB
	

'**********************************************************************************************
'main test code begins here 
'********************************************************************************************** 
Print " test ctrl-c to abort ,  any key to continue" : sleep

'test a segmentation fault here	
'create_segflt()    

'print : print "test a stack_overflow here"    		'uncomment these 3 lines
'stack_overflow()  			' not  trapped  in fact, it crashs before been trapped....
'print sum1to(250000)		' not  trapped  in fact, it crashs before been trapped....

print : print "test function here with nested try_catch"
test() 

' the Try..Catch block
TRY	
	test()
CATCH(e , DIVISION_BY_ZERO)
	if e.msg <> "" then show_catch(e)
	TRY
		test()
	CATCH_ANY(e)
		show_catch(e)
		RETHROW
	FINALLY
		Print " finally1"
	END_TRY
CATCH_ANY(e)                               ' this will catch any other e_exceptions (that is not DIVISION_BY_ZERO)
	show_catch(e)
FINALLY
	Print " FINALLY executed allways, no matter if an e_exceptions was thrown or not"
END_TRY


TRY
	test()
	print "extra test"
	dim d0 as double = div1(17, 0)
CATCH(e , DIVISION_BY_ZERO)
   show_catch(e)	
	TRY
		test()
	CATCH_ANY(e)
		show_catch(e)
	FINALLY
		Print " finally2"
	END_TRY
CATCH_ANY(e)                               ' this will catch any other e_exceptions (that is not DIVISION_BY_ZERO)
	show_catch(e)
FINALLY
	Print " last finally"
END_TRY

TRY
	print "new SIGINT"	
	raise(SIGINT)
	Print " try test ctrl-c to abort , any key to continue"    'the ctrl-c aborts as normal , not trapped
	sleep
CATCH_ANY(e)
		show_catch(e)
FINALLY
		Print " finally before leaving"
END_TRY   

Print "press any key to finish" : sleep
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: Need help on Try-Catch-Throw Linux version

Post by lizard »

Compiles here with Geany on Linux Mint 18.2 32bit. Shows a long list of tests, seems to be OK.
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: Need help on Try-Catch-Throw Linux version

Post by srvaldez »

compiles and runs OK on my Mac
test ctrl-c to abort , any key to continue

test function here with nested try_catch
test again ctrl-c in try-catch block or any key to continue
Catched Exception
e_exceptions message : nothing noticed

e_exception code = 250
file = Try-Catch.bas
proc = DIV1
line = 460

div result printed
15
div 1 done
Catched Exception
e_exceptions message : Division by zero

e_exception code = 221
file = Try-Catch.bas
proc = DIV1
line = 457

div 2 done
Catched Exception
e_exceptions message : Forced to zero

e_exception code = 222
file = Try-Catch.bas
proc = DIV1
line = 458

div 3 done
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

div 4 done
put a breakpoint here
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

finally test()
test again ctrl-c in try-catch block or any key to continue
Catched Exception
e_exceptions message : nothing noticed

e_exception code = 250
file = Try-Catch.bas
proc = DIV1
line = 460

div result printed
15
div 1 done
Catched Exception
e_exceptions message : Division by zero

e_exception code = 221
file = Try-Catch.bas
proc = DIV1
line = 457

div 2 done
Catched Exception
e_exceptions message : Forced to zero

e_exception code = 222
file = Try-Catch.bas
proc = DIV1
line = 458

div 3 done
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

div 4 done
put a breakpoint here
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

finally test()
FINALLY executed allways, no matter if an e_exceptions was thrown or not
test again ctrl-c in try-catch block or any key to continue
Catched Exception
e_exceptions message : nothing noticed

e_exception code = 250
file = Try-Catch.bas
proc = DIV1
line = 460

div result printed
15
div 1 done
Catched Exception
e_exceptions message : Division by zero

e_exception code = 221
file = Try-Catch.bas
proc = DIV1
line = 457

div 2 done
Catched Exception
e_exceptions message : Forced to zero

e_exception code = 222
file = Try-Catch.bas
proc = DIV1
line = 458

div 3 done
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

div 4 done
put a breakpoint here
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

finally test()
extra test
Catched Exception
e_exceptions message : Division by zero

e_exception code = 221
file = Try-Catch.bas
proc = DIV1
line = 457

test again ctrl-c in try-catch block or any key to continue
Catched Exception
e_exceptions message : nothing noticed

e_exception code = 250
file = Try-Catch.bas
proc = DIV1
line = 460

div result printed
15
div 1 done
Catched Exception
e_exceptions message : Division by zero

e_exception code = 221
file = Try-Catch.bas
proc = DIV1
line = 457

div 2 done
Catched Exception
e_exceptions message : Forced to zero

e_exception code = 222
file = Try-Catch.bas
proc = DIV1
line = 458

div 3 done
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

div 4 done
put a breakpoint here
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

finally test()
finally2
last finally
new SIGINT
in SIGINT
Catched Exception
e_exceptions message : got SIGINT!

e_exception code = -102
file = Try-Catch.bas
proc = SIG_SIGINT
line = 326

finally before leaving
press any key to finish
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Need help on Try-Catch-Throw Linux version

Post by marpon »

thanks lizard

did you try to force ctrol-c when asked? if yes did you have a normal continuation or crash

did you try to create segfault , uncommenting where is that code : create_segflt()
if yes , what result , clean abort whith message or crash

same for stack_overflow() ...

but again thanks to test it, at least the test you have done are showing the try-catch is working on your system

now trapping the system errors ? i expect yes
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Need help on Try-Catch-Throw Linux version

Post by marpon »

thanks also srvaldez 'sorry for the mistake'

it shows the try-catch is working fine

same questions as my previous post, could you try to stress with ctrol-c or ctrol break or try segfault , stack_overflow()
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: Need help on Try-Catch-Throw Linux version

Post by lizard »

marpon wrote:
did you try to force ctrol-c when asked? if yes did you have a normal continuation or crash

did you try to create segfault , uncommenting where is that code : create_segflt()
if yes , what result , clean abort whith message or crash
Normal Output is same like srvaldez.

Uncommented Segfault and press Ctrl-c gives this output:

Code: Select all

  test ctrl-c to abort ,  any key to continue
in SIGINT
Thrown Exception  wihout Try_Catch 
    error exceptions : Throw outside Try-Catch bloc

e_exceptions message : got SIGINT!

   e_exception code = -102
   file = throw.bas
   proc = SIG_SIGINT
   line = 326

Abort now!!
Uncommented Stackoverflow and press Ctrl-c gives this output:

Code: Select all

 test ctrl-c to abort ,  any key to continue
in SIGINT
Thrown Exception  wihout Try_Catch 
    error exceptions : Throw outside Try-Catch bloc

e_exceptions message : got SIGINT!

   e_exception code = -102
   file = throw.bas
   proc = SIG_SIGINT
   line = 326

Abort now!

No crashes so far.
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Need help on Try-Catch-Throw Linux version

Post by marpon »

thanks again for your support

it seems working as expected, in fact that's easier than the windows version

signal trapping seems to work correctly
freebasic users would easily implement management exception on linux and windows environment under 32 or 64


if some of you notice something wrong if using that feature please make me informed
Post Reply