mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 13:09:18 +02:00
* fixed handling of FPU exceptions, extended output with -dSYSTEMEXCEPTIONDEBUG, added possibility of debug tracking of OS/2 API error codes in RTL
git-svn-id: trunk@30019 -
This commit is contained in:
parent
37c2d0e60d
commit
b64c4d9acd
@ -2,7 +2,7 @@
|
|||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
|
||||||
This file is part of the Free Pascal run time library.
|
This file is part of the Free Pascal run time library.
|
||||||
Copyright (c) 1999-2005 by Free Pascal development team
|
Copyright (c) 1999-2015 by Free Pascal development team
|
||||||
|
|
||||||
Free Pascal - OS/2 runtime library
|
Free Pascal - OS/2 runtime library
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ interface
|
|||||||
{.$define IODEBUG}
|
{.$define IODEBUG}
|
||||||
{.$define DEBUGENVIRONMENT}
|
{.$define DEBUGENVIRONMENT}
|
||||||
{.$define DEBUGARGUMENTS}
|
{.$define DEBUGARGUMENTS}
|
||||||
|
{.$define DEBUGOSERRORS}
|
||||||
{$endif SYSTEMDEBUG}
|
{$endif SYSTEMDEBUG}
|
||||||
|
|
||||||
{$DEFINE OS2EXCEPTIONS}
|
{$DEFINE OS2EXCEPTIONS}
|
||||||
@ -139,6 +140,8 @@ function RtlCPtoOS2CP (RtlCP: TSystemCodepage; ReqFlags: byte): cardinal;
|
|||||||
const
|
const
|
||||||
(* Are file sizes > 2 GB (64-bit) supported on the current system? *)
|
(* Are file sizes > 2 GB (64-bit) supported on the current system? *)
|
||||||
FSApi64: boolean = false;
|
FSApi64: boolean = false;
|
||||||
|
(* Is full Unicode support provided by the underlying OS/2 version available *)
|
||||||
|
(* and successfully initialized (otherwise dummy routines need to be used). *)
|
||||||
UniAPI: boolean = false;
|
UniAPI: boolean = false;
|
||||||
|
|
||||||
(* Support for tracking I/O errors returned by OS/2 API calls - emulation *)
|
(* Support for tracking I/O errors returned by OS/2 API calls - emulation *)
|
||||||
@ -233,6 +236,12 @@ var
|
|||||||
|
|
||||||
{$ENDIF OS2UNICODE}
|
{$ENDIF OS2UNICODE}
|
||||||
|
|
||||||
|
{$IFDEF SYSTEMDEBUG}
|
||||||
|
var
|
||||||
|
SysLastOSError: cardinal;
|
||||||
|
{$ENDIF SYSTEMDEBUG}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -329,19 +338,37 @@ end;
|
|||||||
procedure JumpToHandleErrorFrame;
|
procedure JumpToHandleErrorFrame;
|
||||||
var
|
var
|
||||||
EIP, EBP, Error: longint;
|
EIP, EBP, Error: longint;
|
||||||
|
{$IFDEF SYSTEMEXCEPTIONDEBUG}
|
||||||
|
ESP, EBP1: longint;
|
||||||
|
{$ENDIF SYSTEMEXCEPTIONDEBUG}
|
||||||
begin
|
begin
|
||||||
(* save ebp *)
|
(* save ebp *)
|
||||||
asm
|
asm
|
||||||
movl (%ebp),%eax
|
movl (%ebp),%eax
|
||||||
movl %eax,ebp
|
movl %eax,ebp
|
||||||
|
{$IFDEF SYSTEMEXCEPTIONDEBUG}
|
||||||
|
movl %ebp,%eax
|
||||||
|
movl %eax,EBP1
|
||||||
|
movl %esp,%eax
|
||||||
|
movl %eax,ESP
|
||||||
|
{$ENDIF SYSTEMEXCEPTIONDEBUG}
|
||||||
end;
|
end;
|
||||||
|
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
||||||
|
if IsConsole then
|
||||||
|
WriteLn (StdErr, 'Exception level at start of JumpToHandleErrorFrame = ', ExceptLevel);
|
||||||
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
if (ExceptLevel > 0) then
|
if (ExceptLevel > 0) then
|
||||||
Dec (ExceptLevel);
|
Dec (ExceptLevel);
|
||||||
EIP := ExceptEIP [ExceptLevel];
|
EIP := ExceptEIP [ExceptLevel];
|
||||||
Error := ExceptError [ExceptLevel];
|
Error := ExceptError [ExceptLevel];
|
||||||
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
||||||
if IsConsole then
|
if IsConsole then
|
||||||
|
begin
|
||||||
WriteLn (StdErr, 'In JumpToHandleErrorFrame error = ', Error);
|
WriteLn (StdErr, 'In JumpToHandleErrorFrame error = ', Error);
|
||||||
|
WriteLn (StdErr, 'EBP on entry: ', HexStr (EBP1, 8));
|
||||||
|
WriteLn (StdErr, 'Previous EBP: ', HexStr (EBP, 8));
|
||||||
|
WriteLn (StdErr, 'ESP on entry: ', HexStr (ESP, 8));
|
||||||
|
end;
|
||||||
{$endif SYSTEMEXCEPTIONDEBUG}
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
if ResetFPU [ExceptLevel] then
|
if ResetFPU [ExceptLevel] then
|
||||||
SysResetFPU;
|
SysResetFPU;
|
||||||
@ -384,7 +411,7 @@ var
|
|||||||
Must_Reset_FPU: boolean;
|
Must_Reset_FPU: boolean;
|
||||||
RC: cardinal;
|
RC: cardinal;
|
||||||
{$IFDEF SYSTEMEXCEPTIONDEBUG}
|
{$IFDEF SYSTEMEXCEPTIONDEBUG}
|
||||||
CurSS: cardinal;
|
CurSS, CurESP, CurEBP: cardinal;
|
||||||
B: byte;
|
B: byte;
|
||||||
{$ENDIF SYSTEMEXCEPTIONDEBUG}
|
{$ENDIF SYSTEMEXCEPTIONDEBUG}
|
||||||
begin
|
begin
|
||||||
@ -392,14 +419,61 @@ begin
|
|||||||
if IsConsole then
|
if IsConsole then
|
||||||
begin
|
begin
|
||||||
asm
|
asm
|
||||||
|
pushl %eax
|
||||||
xorl %eax,%eax
|
xorl %eax,%eax
|
||||||
movw %ss,%ax
|
movw %ss,%ax
|
||||||
movl %eax,CurSS
|
movl %eax,CurSS
|
||||||
|
movl %esp,%eax
|
||||||
|
movl %eax,CurESP
|
||||||
|
movl %ebp,%eax
|
||||||
|
movl %eax,CurEBP
|
||||||
|
popl %eax
|
||||||
end;
|
end;
|
||||||
|
WriteLn (StdErr, '------------------------------------------------------');
|
||||||
WriteLn (StdErr, 'In System_Exception_Handler, error = ',
|
WriteLn (StdErr, 'In System_Exception_Handler, error = ',
|
||||||
HexStr (Report^.Exception_Num, 8));
|
HexStr (Report^.Exception_Num, 8));
|
||||||
|
WriteLn (StdErr, 'Handler flags = ', HexStr (Report^.HandlerFlags, 8));
|
||||||
|
WriteLn (StdErr, 'Nested_RepRec = ', HexStr (PtrUInt (Report^.Nested_RepRec), 8));
|
||||||
|
WriteLn (StdErr, 'Amount of passed parameters = ', Report^.ParamCount);
|
||||||
WriteLn (StdErr, 'Context SS = ', HexStr (Context^.Reg_SS, 8),
|
WriteLn (StdErr, 'Context SS = ', HexStr (Context^.Reg_SS, 8),
|
||||||
', current SS = ', HexStr (CurSS, 8));
|
', current SS = ', HexStr (CurSS, 8));
|
||||||
|
WriteLn (StdErr, 'Current ESP = ', HexStr (CurESP, 8),
|
||||||
|
', current EBP = ', HexStr (CurEBP, 8));
|
||||||
|
WriteLn (StdErr, 'Context flags = ', HexStr (Context^.ContextFlags, 8));
|
||||||
|
WriteLn (StdErr, 'Thread ID = ', ThreadID);
|
||||||
|
if Context^.ContextFlags and Context_Control <> 0 then
|
||||||
|
begin
|
||||||
|
WriteLn (StdErr, 'EBP = ', HexStr (Context^.Reg_EBP, 8),
|
||||||
|
', SS = ', HexStr (Context^.Reg_SS, 8),
|
||||||
|
', ESP = ', HexStr (Context^.Reg_ESP, 8));
|
||||||
|
WriteLn (StdErr, 'CS = ', HexStr (Context^.Reg_CS, 8),
|
||||||
|
', EIP = ', HexStr (Context^.Reg_EIP, 8),
|
||||||
|
', EFlags = ', HexStr (Context^.Flags, 8));
|
||||||
|
end;
|
||||||
|
if Context^.ContextFlags and Context_Floating_Point <> 0 then
|
||||||
|
begin
|
||||||
|
for B := 1 to 6 do
|
||||||
|
Write (StdErr, 'Ctx Env [', B, '] = ', HexStr (Context^.Env [B], 8),
|
||||||
|
', ');
|
||||||
|
WriteLn (StdErr, 'Ctx Env [7] = ', HexStr (Context^.Env [7], 8));
|
||||||
|
for B := 0 to 6 do
|
||||||
|
Write (StdErr, 'FPU stack [', B, '] = ', Context^.FPUStack [B], ', ');
|
||||||
|
WriteLn (StdErr, 'FPU stack [7] = ', Context^.FPUStack [7]);
|
||||||
|
end;
|
||||||
|
if Context^.ContextFlags and Context_Segments <> 0 then
|
||||||
|
WriteLn (StdErr, 'GS = ', HexStr (Context^.Reg_GS, 8),
|
||||||
|
', FS = ', HexStr (Context^.Reg_FS, 8),
|
||||||
|
', ES = ', HexStr (Context^.Reg_ES, 8),
|
||||||
|
', DS = ', HexStr (Context^.Reg_DS, 8));
|
||||||
|
if Context^.ContextFlags and Context_Integer <> 0 then
|
||||||
|
begin
|
||||||
|
WriteLn (StdErr, 'EDI = ', HexStr (Context^.Reg_EDI, 8),
|
||||||
|
', ESI = ', HexStr (Context^.Reg_ESI, 8));
|
||||||
|
WriteLn (StdErr, 'EAX = ', HexStr (Context^.Reg_EAX, 8),
|
||||||
|
', EBX = ', HexStr (Context^.Reg_EBX, 8),
|
||||||
|
', ECX = ', HexStr (Context^.Reg_ECX, 8),
|
||||||
|
', EDX = ', HexStr (Context^.Reg_EDX, 8));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{$endif SYSTEMEXCEPTIONDEBUG}
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
Res := Xcpt_Continue_Search;
|
Res := Xcpt_Continue_Search;
|
||||||
@ -461,7 +535,16 @@ begin
|
|||||||
Res := Xcpt_Continue_Execution;
|
Res := Xcpt_Continue_Execution;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
Err := 216;
|
Err := 216;
|
||||||
|
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
||||||
|
if IsConsole and (Report^.ParamCount >= 2) then
|
||||||
|
begin
|
||||||
|
Writeln (StdErr, 'Access violation flags: ', Report^.Parameters [0]);
|
||||||
|
WriteLn (StdErr, 'Fault address: ', HexStr (Report^.Parameters [1], 8));
|
||||||
|
end;
|
||||||
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
|
end;
|
||||||
Xcpt_Signal:
|
Xcpt_Signal:
|
||||||
case Report^.Parameters [0] of
|
case Report^.Parameters [0] of
|
||||||
Xcpt_Signal_KillProc:
|
Xcpt_Signal_KillProc:
|
||||||
@ -511,14 +594,33 @@ begin
|
|||||||
Context^.Reg_EIP := cardinal (@JumpToHandleErrorFrame);
|
Context^.Reg_EIP := cardinal (@JumpToHandleErrorFrame);
|
||||||
Report^.Exception_Num := 0;
|
Report^.Exception_Num := 0;
|
||||||
|
|
||||||
|
if Must_Reset_FPU and
|
||||||
|
(Context^.ContextFlags and Context_Floating_Point <> 0) then
|
||||||
|
begin
|
||||||
|
{ Control word is index 1 }
|
||||||
|
Context^.Env [1] := Default8087CW;
|
||||||
|
{ Status word is index 2 }
|
||||||
|
Context^.Env [2] := Context^.Env [2] and not FPU_ExceptionMask;
|
||||||
|
{ Tag word is index 3 }
|
||||||
|
Context^.Env [3] := $FFFF;
|
||||||
|
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
||||||
|
WriteLn (StdErr, 'After FPU status reset in context record:');
|
||||||
|
for B := 1 to 2 do
|
||||||
|
Write (StdErr, 'Ctx Env [', B, '] = ', HexStr (Context^.Env [B], 8),
|
||||||
|
', ');
|
||||||
|
WriteLn (StdErr, 'Ctx Env [3] = ', HexStr (Context^.Env [3], 8));
|
||||||
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
|
end;
|
||||||
Res := Xcpt_Continue_Execution;
|
Res := Xcpt_Continue_Execution;
|
||||||
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
{$ifdef SYSTEMEXCEPTIONDEBUG}
|
||||||
if IsConsole then
|
if IsConsole then
|
||||||
begin
|
begin
|
||||||
WriteLn (StdErr, 'Exception Continue Exception set at ',
|
WriteLn (StdErr, 'Exception Continue Exception set at ',
|
||||||
HexStr (ExceptEIP [ExceptLevel], 8));
|
HexStr (ExceptEIP [Pred (ExceptLevel)], 8));
|
||||||
WriteLn (StdErr, 'EIP changed to ',
|
WriteLn (StdErr, 'EIP changed to ',
|
||||||
HexStr (longint (@JumpToHandleErrorFrame), 8), ', error = ', Err);
|
HexStr (Context^.Reg_EIP, 8), ', error = ', Err);
|
||||||
|
WriteLn (StdErr, 'Exception level = ', ExceptLevel);
|
||||||
|
WriteLn (StdErr, 'ResetFPU = ', ResetFPU [Pred (ExceptLevel)]);
|
||||||
end;
|
end;
|
||||||
{$endif SYSTEMEXCEPTIONDEBUG}
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
end;
|
end;
|
||||||
@ -642,11 +744,27 @@ begin
|
|||||||
{$endif SYSTEMEXCEPTIONDEBUG}
|
{$endif SYSTEMEXCEPTIONDEBUG}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IFDEF SYSTEMDEBUG}
|
||||||
|
const
|
||||||
|
OrigOSErrorWatch: TOSErrorWatch = nil;
|
||||||
|
|
||||||
|
procedure TrackLastOSError (Error: cardinal);
|
||||||
|
begin
|
||||||
|
SysLastOSError := Error;
|
||||||
|
{$IFDEF DEBUGOSERRORS}
|
||||||
|
if IsConsole then
|
||||||
|
WriteLn (StdErr, 'Some OS/2 API returned error ', Error);
|
||||||
|
{$ENDIF DEBUGOSERRORS}
|
||||||
|
OrigOSErrorWatch (Error);
|
||||||
|
end;
|
||||||
|
{$ENDIF SYSTEMDEBUG}
|
||||||
|
|
||||||
procedure Remove_Exception_Handlers;
|
procedure Remove_Exception_Handlers;
|
||||||
var
|
var
|
||||||
RC: cardinal;
|
RC: cardinal;
|
||||||
begin
|
begin
|
||||||
RC := DosUnsetExceptionHandler (ExcptReg^);
|
RC := DosUnsetExceptionHandler (ExcptReg^);
|
||||||
|
if RC <> 0 then
|
||||||
OSErrorWatch (RC);
|
OSErrorWatch (RC);
|
||||||
end;
|
end;
|
||||||
{$ENDIF OS2EXCEPTIONS}
|
{$ENDIF OS2EXCEPTIONS}
|
||||||
@ -1265,9 +1383,17 @@ begin
|
|||||||
ThreadID := TIB^.TIB2^.TID;
|
ThreadID := TIB^.TIB2^.TID;
|
||||||
IsConsole := ApplicationType <> 3;
|
IsConsole := ApplicationType <> 3;
|
||||||
|
|
||||||
|
{$IFDEF SYSTEMDEBUG}
|
||||||
|
SysLastOSError := 0;
|
||||||
|
OrigOSErrorWatch := TOSErrorWatch (SetOSErrorTracking (@TrackLastOSError));
|
||||||
|
{$ENDIF SYSTEMDEBUG}
|
||||||
|
|
||||||
{Query maximum path length (QSV_MAX_PATH_LEN = 1)}
|
{Query maximum path length (QSV_MAX_PATH_LEN = 1)}
|
||||||
if DosQuerySysInfo (1, 1, DW, SizeOf (DW)) = 0 then
|
RC := DosQuerySysInfo (1, 1, DW, SizeOf (DW));
|
||||||
RealMaxPathLen := DW;
|
if RC = 0 then
|
||||||
|
RealMaxPathLen := DW
|
||||||
|
else
|
||||||
|
OSErrorWatch (RC);
|
||||||
|
|
||||||
ExitProc := nil;
|
ExitProc := nil;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user