Try/Catch Errorhandler für Windows/Linux 32/64 Bit

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
RocketRider
Beiträge: 109
Registriert: 10.12.2004 19:27
Kontaktdaten:

Try/Catch Errorhandler für Windows/Linux 32/64 Bit

Beitrag von RocketRider »

Hallo

Ich habe einen Try/Catch Errorhandler geschreiben, dieser Funktioniert unter Windows und Linux bei 32 und 64 Bit.

Code: Alles auswählen

;****************************
;***  Try/Catch Commands  ***
;****************************
;*** (c) 2009 RocketRider ***
;***    RocketRider.eu    ***
;****************************
;***    PureBasic 4.31    ***
;****************************
;+ Supports Windows/Linux 32/64 Bit
;+ Does not support multi threated applications at this time

DisableDebugger
Global __TRYCATCH_pOnErrorAddress.i
Global __TRYCATCH_pOldOnErrorAddress.i
Global __TRYCATCH_pTryCatchStackPointer.i
Global __TRYCATCH_pOldTryCatchStackPointer.i

__TRYCATCH_pOnErrorAddress = ?__TRYCATCH_DefaultExceptionHandler
OnErrorGoto(?__TRYCATCH_DefaultExceptionHandler)
Goto __TRYCATCH_EndDefaultExceptionHandler
__TRYCATCH_DefaultExceptionHandler:
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  MessageRequester("Unhandled Exception!", ErrorMessage(), #MB_ICONERROR)
CompilerElse
  MessageRequester("Unhandled Exception!", ErrorMessage())
CompilerEndIf
End
__TRYCATCH_EndDefaultExceptionHandler:

Macro Try(Name)
  __TRYCATCH_pOldOnErrorAddress = __TRYCATCH_pOnErrorAddress
  __TRYCATCH_pOldTryCatchStackPointer = __TRYCATCH_pTryCatchStackPointer
  __TRYCATCH_pOnErrorAddress = ?__TRYCATCH_#Name
  
  CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
    !MOV dword[v___TRYCATCH_pTryCatchStackPointer],ESP
  CompilerElse
    CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
      !MOV qword[v___TRYCATCH_pTryCatchStackPointer],RSP
    CompilerElse
      CompilerError "Processor not supported by try/catch handler"
    CompilerEndIf
  CompilerEndIf
  
  OnErrorGoto(?__TRYCATCH_#Name)
EndMacro
Macro Catch(Name)
  Goto __TRYCATCH_End#Name
  __TRYCATCH_#Name:
  CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
    !MOV ESP,dword[v___TRYCATCH_pTryCatchStackPointer]
  CompilerElse
    CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
      !MOV RSP,qword[v___TRYCATCH_pTryCatchStackPointer]
    CompilerElse
      CompilerError "Processor not supported by try/catch handler"
    CompilerEndIf
  CompilerEndIf
  __TRYCATCH_pTryCatchStackPointer = __TRYCATCH_pOldTryCatchStackPointer
  __TRYCATCH_pOnErrorAddress = __TRYCATCH_pOldOnErrorAddress
  OnErrorGoto(__TRYCATCH_pOnErrorAddress)
EndMacro
Macro EndCatch(Name)
  __TRYCATCH_End#Name:
  __TRYCATCH_pTryCatchStackPointer = __TRYCATCH_pOldTryCatchStackPointer
  If __TRYCATCH_pOnErrorAddress <> __TRYCATCH_pOldOnErrorAddress
    __TRYCATCH_pOnErrorAddress = __TRYCATCH_pOldOnErrorAddress
    OnErrorGoto(__TRYCATCH_pOnErrorAddress)
  EndIf
EndMacro



;Test exception handling
Try(INTERRUPT_TEST)  ; Use Try to begin the exeption handling. INTERRUPT_TEST is the name of the try/catch section. It can be anything, but must be unique. 
  ;Programcode which causes an exception
  !int 21h

Catch(INTERRUPT_TEST)  ; continues execution after Catch(...) if an exception occured, or jumps directly to EndCatch(...) if no exception occured.
  ;This part will be only called if an exception was raised.
  MessageRequester("Exception found!", ErrorMessage())
EndCatch(INTERRUPT_TEST) ; end try/catch section
;The stack will be corrected and the program can be continued.


; Now a second test...
Procedure Test()
  bResult = #True
  Try(POKEL_TEST)
    ;Cause an exception
    PokeL(0,0)
  
  Catch(POKEL_TEST)
    ;This part will be only called if an exception was raised.
    MessageRequester("Exception found in Procedure Test()!", ErrorMessage())
    ;Do not use ProcedureReturn into a Catch...EndCatch section, because exeption handle would not work correct, if nested try-blocks are used (EndCatch would be not called in this case).
    ;Instead st return value
    bResult = #False
  EndCatch(POKEL_TEST)
  ProcedureReturn bResult
EndProcedure

MessageRequester("Result", Str(Test()))


Gruß
RocketRider
GreenForce-Player - Der alternative Media Player!
Wie viele Tage sind es von Halloween bis Weihnachten?
Okt 31 - Dez 25 = 0 Tage!