mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-21 11:59:51 +01:00
+ added conversion from exceptions into run time error
(only if syswin32 compiled with -ddebug for now !)
* added HandleError(errno,frame)
where you specify the frame
needed for win32 exception handling
This commit is contained in:
parent
2d524e51a2
commit
67dba7efc3
@ -306,6 +306,26 @@ end;
|
|||||||
Init / Exit / ExitProc
|
Init / Exit / ExitProc
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
|
Procedure HandleError (Errno : longint;frame : longint);
|
||||||
|
{
|
||||||
|
Procedure to handle internal errors, i.e. not user-invoked errors
|
||||||
|
Internal function should ALWAYS call HandleError instead of RunError.
|
||||||
|
Can be used for exception handlers to specify the frame
|
||||||
|
}
|
||||||
|
var
|
||||||
|
addr : longint;
|
||||||
|
begin
|
||||||
|
addr:=get_caller_addr(frame);
|
||||||
|
If ErrorProc<>Nil then
|
||||||
|
TErrorProc (ErrorProc)(Errno,pointer(addr));
|
||||||
|
errorcode:=Errno;
|
||||||
|
exitcode:=Errno;
|
||||||
|
erroraddr:=pointer(addr);
|
||||||
|
errorbase:=get_caller_frame(frame);
|
||||||
|
DoError:=true;
|
||||||
|
halt(errorcode);
|
||||||
|
end;
|
||||||
|
|
||||||
Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
|
Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
|
||||||
{
|
{
|
||||||
Procedure to handle internal errors, i.e. not user-invoked errors
|
Procedure to handle internal errors, i.e. not user-invoked errors
|
||||||
@ -314,18 +334,9 @@ Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
|
|||||||
var
|
var
|
||||||
addr : longint;
|
addr : longint;
|
||||||
begin
|
begin
|
||||||
addr:=get_caller_addr(get_frame);
|
HandleError(Errno,get_frame);
|
||||||
If ErrorProc<>Nil then
|
|
||||||
TErrorProc (ErrorProc)(Errno,pointer(addr));
|
|
||||||
errorcode:=Errno;
|
|
||||||
exitcode:=Errno;
|
|
||||||
erroraddr:=pointer(addr);
|
|
||||||
errorbase:=get_caller_frame(get_frame);
|
|
||||||
DoError:=true;
|
|
||||||
halt(errorcode);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure runerror(w : word);[alias: 'FPC_RUNERROR'];
|
procedure runerror(w : word);[alias: 'FPC_RUNERROR'];
|
||||||
begin
|
begin
|
||||||
errorcode:=w;
|
errorcode:=w;
|
||||||
@ -477,7 +488,14 @@ end;
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.44 1998-11-26 23:16:15 jonas
|
Revision 1.45 1998-12-01 14:00:10 pierre
|
||||||
|
+ added conversion from exceptions into run time error
|
||||||
|
(only if syswin32 compiled with -ddebug for now !)
|
||||||
|
* added HandleError(errno,frame)
|
||||||
|
where you specify the frame
|
||||||
|
needed for win32 exception handling
|
||||||
|
|
||||||
|
Revision 1.44 1998/11/26 23:16:15 jonas
|
||||||
* changed RandSeed and OldRandSeed to Cardinal to avoid negative random numbers
|
* changed RandSeed and OldRandSeed to Cardinal to avoid negative random numbers
|
||||||
|
|
||||||
Revision 1.43 1998/11/17 10:36:07 michael
|
Revision 1.43 1998/11/17 10:36:07 michael
|
||||||
|
|||||||
@ -28,6 +28,11 @@ interface
|
|||||||
{ include heap support headers }
|
{ include heap support headers }
|
||||||
{$I heaph.inc}
|
{$I heaph.inc}
|
||||||
|
|
||||||
|
{$ifdef debug}
|
||||||
|
{$ifdef i386}
|
||||||
|
{$define Set_i386_Exception_handler}
|
||||||
|
{$endif i386}
|
||||||
|
{$endif debug}
|
||||||
|
|
||||||
const
|
const
|
||||||
{ Default filehandles }
|
{ Default filehandles }
|
||||||
@ -732,12 +737,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
procedure install_exception_handlers;forward;
|
||||||
|
|
||||||
{$ASMMODE DIRECT}
|
{$ASMMODE DIRECT}
|
||||||
|
var
|
||||||
|
{ value of the stack segment
|
||||||
|
to check if the call stack can be written on exceptions }
|
||||||
|
_SS : longint;
|
||||||
|
|
||||||
procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
|
procedure Exe_entry;[public, alias : '_FPC_EXE_Entry'];
|
||||||
begin
|
begin
|
||||||
IsLibrary:=false;
|
IsLibrary:=false;
|
||||||
|
{ install the handlers for exe only ?
|
||||||
|
or should we install them for DLL also ? (PM) }
|
||||||
|
install_exception_handlers;
|
||||||
asm
|
asm
|
||||||
|
pushl %ebp
|
||||||
|
xorl %ebp,%ebp
|
||||||
|
movw %ss,%bp
|
||||||
|
movl %ebp,__SS
|
||||||
|
xorl %ebp,%ebp
|
||||||
call PASCALMAIN
|
call PASCALMAIN
|
||||||
|
popl %ebp
|
||||||
end;
|
end;
|
||||||
{ if we pass here there was no error ! }
|
{ if we pass here there was no error ! }
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
@ -748,6 +769,9 @@ procedure Dll_entry;[public, alias : '_FPC_DLL_Entry'];
|
|||||||
IsLibrary:=true;
|
IsLibrary:=true;
|
||||||
case DLLreason of
|
case DLLreason of
|
||||||
1,2 : asm
|
1,2 : asm
|
||||||
|
xorl %edi,%edi
|
||||||
|
movw %ss,%di
|
||||||
|
movl %edi,__SS
|
||||||
call PASCALMAIN
|
call PASCALMAIN
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
@ -757,6 +781,163 @@ procedure Dll_entry;[public, alias : '_FPC_DLL_Entry'];
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifdef Set_i386_Exception_handler}
|
||||||
|
|
||||||
|
const
|
||||||
|
EXCEPTION_MAXIMUM_PARAMETERS = 15;
|
||||||
|
EXCEPTION_ACCESS_VIOLATION = $c0000005;
|
||||||
|
EXCEPTION_BREAKPOINT = $80000003;
|
||||||
|
EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
|
||||||
|
EXCEPTION_SINGLE_STEP = $80000004;
|
||||||
|
EXCEPTION_ARRAY_BOUNDS_EXCEEDED = $c000008c;
|
||||||
|
EXCEPTION_FLT_DENORMAL_OPERAND = $c000008d;
|
||||||
|
EXCEPTION_FLT_DIVIDE_BY_ZERO = $c000008e;
|
||||||
|
EXCEPTION_FLT_INEXACT_RESULT = $c000008f;
|
||||||
|
EXCEPTION_FLT_INVALID_OPERATION = $c0000090;
|
||||||
|
EXCEPTION_FLT_OVERFLOW = $c0000091;
|
||||||
|
EXCEPTION_FLT_STACK_CHECK = $c0000092;
|
||||||
|
EXCEPTION_FLT_UNDERFLOW = $c0000093;
|
||||||
|
EXCEPTION_INT_DIVIDE_BY_ZERO = $c0000094;
|
||||||
|
EXCEPTION_INT_OVERFLOW = $c0000095;
|
||||||
|
EXCEPTION_INVALID_HANDLE = $c0000008;
|
||||||
|
EXCEPTION_PRIV_INSTRUCTION = $c0000096;
|
||||||
|
EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
|
||||||
|
EXCEPTION_NONCONTINUABLE = $1;
|
||||||
|
EXCEPTION_STACK_OVERFLOW = $c00000fd;
|
||||||
|
EXCEPTION_INVALID_DISPOSITION = $c0000026;
|
||||||
|
ExceptionContinueExecution = 0;
|
||||||
|
ExceptionContinueSearch = 1;
|
||||||
|
type
|
||||||
|
|
||||||
|
FLOATING_SAVE_AREA = record
|
||||||
|
ControlWord : DWORD;
|
||||||
|
StatusWord : DWORD;
|
||||||
|
TagWord : DWORD;
|
||||||
|
ErrorOffset : DWORD;
|
||||||
|
ErrorSelector : DWORD;
|
||||||
|
DataOffset : DWORD;
|
||||||
|
DataSelector : DWORD;
|
||||||
|
RegisterArea : array[0..79] of BYTE;
|
||||||
|
Cr0NpxState : DWORD;
|
||||||
|
end;
|
||||||
|
_FLOATING_SAVE_AREA = FLOATING_SAVE_AREA;
|
||||||
|
TFLOATINGSAVEAREA = FLOATING_SAVE_AREA;
|
||||||
|
PFLOATINGSAVEAREA = ^FLOATING_SAVE_AREA;
|
||||||
|
|
||||||
|
CONTEXT = record
|
||||||
|
ContextFlags : DWORD;
|
||||||
|
Dr0 : DWORD;
|
||||||
|
Dr1 : DWORD;
|
||||||
|
Dr2 : DWORD;
|
||||||
|
Dr3 : DWORD;
|
||||||
|
Dr6 : DWORD;
|
||||||
|
Dr7 : DWORD;
|
||||||
|
FloatSave : FLOATING_SAVE_AREA;
|
||||||
|
SegGs : DWORD;
|
||||||
|
SegFs : DWORD;
|
||||||
|
SegEs : DWORD;
|
||||||
|
SegDs : DWORD;
|
||||||
|
Edi : DWORD;
|
||||||
|
Esi : DWORD;
|
||||||
|
Ebx : DWORD;
|
||||||
|
Edx : DWORD;
|
||||||
|
Ecx : DWORD;
|
||||||
|
Eax : DWORD;
|
||||||
|
Ebp : DWORD;
|
||||||
|
Eip : DWORD;
|
||||||
|
SegCs : DWORD;
|
||||||
|
EFlags : DWORD;
|
||||||
|
Esp : DWORD;
|
||||||
|
SegSs : DWORD;
|
||||||
|
end;
|
||||||
|
LPCONTEXT = ^CONTEXT;
|
||||||
|
_CONTEXT = CONTEXT;
|
||||||
|
TCONTEXT = CONTEXT;
|
||||||
|
PCONTEXT = ^CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
|
type pexception_record = ^exception_record;
|
||||||
|
EXCEPTION_RECORD = record
|
||||||
|
ExceptionCode : longint;
|
||||||
|
ExceptionFlags : longint;
|
||||||
|
ExceptionRecord : pexception_record;
|
||||||
|
ExceptionAddress : pointer;
|
||||||
|
NumberParameters : longint;
|
||||||
|
ExceptionInformation : array[0..EXCEPTION_MAXIMUM_PARAMETERS-1] of pointer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
PEXCEPTION_POINTERS = ^EXCEPTION_POINTERS;
|
||||||
|
EXCEPTION_POINTERS = record
|
||||||
|
ExceptionRecord : PEXCEPTION_RECORD ;
|
||||||
|
ContextRecord : PCONTEXT ;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ type of functions that should be used for exception handling }
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER = function(excep :PEXCEPTION_POINTERS) : longint;
|
||||||
|
|
||||||
|
function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : LPTOP_LEVEL_EXCEPTION_FILTER)
|
||||||
|
: LPTOP_LEVEL_EXCEPTION_FILTER;
|
||||||
|
external 'kernel32' name 'SetUnhandledExceptionFilter';
|
||||||
|
|
||||||
|
function syswin32_i386_exception_handler(excep :PEXCEPTION_POINTERS) : longint;
|
||||||
|
var frame : longint;
|
||||||
|
begin
|
||||||
|
{ default : unhandled !}
|
||||||
|
if excep^.ContextRecord^.SegSs=_SS then
|
||||||
|
frame:=excep^.ContextRecord^.Ebp
|
||||||
|
else
|
||||||
|
frame:=0;
|
||||||
|
syswin32_i386_exception_handler:=ExceptionContinueSearch;
|
||||||
|
case excep^.ExceptionRecord^.ExceptionCode of
|
||||||
|
EXCEPTION_ACCESS_VIOLATION :
|
||||||
|
Handleerror(216,frame);
|
||||||
|
{ EXCEPTION_BREAKPOINT = $80000003;
|
||||||
|
EXCEPTION_DATATYPE_MISALIGNMENT = $80000002;
|
||||||
|
EXCEPTION_SINGLE_STEP = $80000004; }
|
||||||
|
EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
|
||||||
|
Handleerror(201,frame);
|
||||||
|
{ EXCEPTION_FLT_DENORMAL_OPERAND = $c000008d; }
|
||||||
|
EXCEPTION_FLT_DIVIDE_BY_ZERO :
|
||||||
|
Handleerror(200,frame);
|
||||||
|
{EXCEPTION_FLT_INEXACT_RESULT = $c000008f;
|
||||||
|
EXCEPTION_FLT_INVALID_OPERATION = $c0000090;}
|
||||||
|
EXCEPTION_FLT_OVERFLOW :
|
||||||
|
Handleerror(205,frame);
|
||||||
|
EXCEPTION_FLT_STACK_CHECK :
|
||||||
|
Handleerror(207,frame);
|
||||||
|
{ EXCEPTION_FLT_UNDERFLOW :
|
||||||
|
Handleerror(206,frame); should be accepted as zero !! }
|
||||||
|
EXCEPTION_INT_DIVIDE_BY_ZERO :
|
||||||
|
Handleerror(200,frame);
|
||||||
|
EXCEPTION_INT_OVERFLOW :
|
||||||
|
Handleerror(215,frame);
|
||||||
|
{EXCEPTION_INVALID_HANDLE = $c0000008;
|
||||||
|
EXCEPTION_PRIV_INSTRUCTION = $c0000096;
|
||||||
|
EXCEPTION_NONCONTINUABLE_EXCEPTION = $c0000025;
|
||||||
|
EXCEPTION_NONCONTINUABLE = $1;}
|
||||||
|
EXCEPTION_STACK_OVERFLOW :
|
||||||
|
Handleerror(202,frame);
|
||||||
|
{EXCEPTION_INVALID_DISPOSITION = $c0000026;}
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
old_exception : LPTOP_LEVEL_EXCEPTION_FILTER;
|
||||||
|
|
||||||
|
procedure install_exception_handlers;
|
||||||
|
begin
|
||||||
|
old_exception:=SetUnhandledExceptionFilter(@syswin32_i386_exception_handler);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{$else not i386 (Processor specific !!)}
|
||||||
|
procedure install_exception_handlers;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{$endif Set_i386_Exception_handler}
|
||||||
|
|
||||||
const
|
const
|
||||||
Exe_entry_code : pointer = @Exe_entry;
|
Exe_entry_code : pointer = @Exe_entry;
|
||||||
Dll_entry_code : pointer = @Dll_entry;
|
Dll_entry_code : pointer = @Dll_entry;
|
||||||
@ -799,7 +980,14 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.26 1998-11-30 13:13:41 pierre
|
Revision 1.27 1998-12-01 14:00:08 pierre
|
||||||
|
+ added conversion from exceptions into run time error
|
||||||
|
(only if syswin32 compiled with -ddebug for now !)
|
||||||
|
* added HandleError(errno,frame)
|
||||||
|
where you specify the frame
|
||||||
|
needed for win32 exception handling
|
||||||
|
|
||||||
|
Revision 1.26 1998/11/30 13:13:41 pierre
|
||||||
* needs asw to link correctly wprt0 or wdllprt0 file
|
* needs asw to link correctly wprt0 or wdllprt0 file
|
||||||
|
|
||||||
Revision 1.25 1998/11/30 09:16:58 pierre
|
Revision 1.25 1998/11/30 09:16:58 pierre
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user