|
@@ -80,6 +80,8 @@ Const
|
|
|
|
|
|
Procedure HandleError (Errno : Longint); external name 'FPC_HANDLEERROR';
|
|
Procedure HandleError (Errno : Longint); external name 'FPC_HANDLEERROR';
|
|
Procedure HandleErrorFrame (Errno : longint;frame : Pointer); forward;
|
|
Procedure HandleErrorFrame (Errno : longint;frame : Pointer); forward;
|
|
|
|
+Procedure HandleErrorAddrFrame (Errno : longint;addr,frame : Pointer); forward;
|
|
|
|
+Procedure HandleErrorAddrFrameInd (Errno : longint;addr,frame : Pointer); forward;
|
|
|
|
|
|
{$ifdef FPC_HAS_FEATURE_TEXTIO}
|
|
{$ifdef FPC_HAS_FEATURE_TEXTIO}
|
|
type
|
|
type
|
|
@@ -686,29 +688,63 @@ End;
|
|
Miscellaneous
|
|
Miscellaneous
|
|
*****************************************************************************}
|
|
*****************************************************************************}
|
|
|
|
|
|
|
|
+{$ifndef FPC_SYSTEM_HAS_GET_PC_ADDR}
|
|
|
|
+ { This provides a dummy implementation
|
|
|
|
+ of get_pc_addr function, for CPU's that don't need
|
|
|
|
+ the instruction address to walk the stack. }
|
|
|
|
+function get_pc_addr : pointer;
|
|
|
|
+begin
|
|
|
|
+ get_pc_addr:=nil;
|
|
|
|
+end;
|
|
|
|
+{$endif ndef FPC_SYSTEM_HAS_GET_PC_ADDR}
|
|
|
|
+
|
|
|
|
+{$ifndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
|
|
|
|
+ { This provides a simple implementation
|
|
|
|
+ of get_caller_stackinfo procedure,
|
|
|
|
+ using get_caller_addr and get_caller_frame
|
|
|
|
+ functions. }
|
|
|
|
+procedure get_caller_stackinfo(var framebp,addr : pointer);
|
|
|
|
+var
|
|
|
|
+ nextbp,nextaddr : pointer;
|
|
|
|
+begin
|
|
|
|
+ nextbp:=get_caller_frame(framebp,addr);
|
|
|
|
+ nextaddr:=get_caller_addr(framebp,addr);
|
|
|
|
+ framebp:=nextbp;
|
|
|
|
+ addr:=nextaddr;
|
|
|
|
+end;
|
|
|
|
+{$endif ndef FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
|
|
|
|
+
|
|
|
|
+
|
|
procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; compilerproc;
|
|
procedure fpc_rangeerror;[public,alias:'FPC_RANGEERROR']; compilerproc;
|
|
begin
|
|
begin
|
|
- HandleErrorFrame(201,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(201,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure fpc_divbyzero;[public,alias:'FPC_DIVBYZERO']; compilerproc;
|
|
procedure fpc_divbyzero;[public,alias:'FPC_DIVBYZERO']; compilerproc;
|
|
begin
|
|
begin
|
|
- HandleErrorFrame(200,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(200,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; compilerproc;
|
|
procedure fpc_overflow;[public,alias:'FPC_OVERFLOW']; compilerproc;
|
|
begin
|
|
begin
|
|
- HandleErrorFrame(215,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(215,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure fpc_threaderror; [public,alias:'FPC_THREADERROR'];
|
|
procedure fpc_threaderror; [public,alias:'FPC_THREADERROR'];
|
|
begin
|
|
begin
|
|
- HandleErrorFrame(6,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(6,get_pc_addr,get_frame);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+procedure fpc_invalidpointer; [public,alias:'FPC_INVALIDPOINTER'];
|
|
|
|
+begin
|
|
|
|
+ HandleErrorAddrFrameInd(216,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+
|
|
(*
|
|
(*
|
|
procedure fpc_iocheck;[public,alias:'FPC_IOCHECK']; compilerproc;
|
|
procedure fpc_iocheck;[public,alias:'FPC_IOCHECK']; compilerproc;
|
|
var
|
|
var
|
|
@@ -720,7 +756,7 @@ begin
|
|
begin
|
|
begin
|
|
l:=HInOutRes^;
|
|
l:=HInOutRes^;
|
|
HInOutRes^:=0;
|
|
HInOutRes^:=0;
|
|
- HandleErrorFrame(l,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(l,get_pc_addr,get_frame)
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -749,7 +785,7 @@ begin
|
|
begin
|
|
begin
|
|
if assigned(SafeCallErrorProc) then
|
|
if assigned(SafeCallErrorProc) then
|
|
SafeCallErrorProc(res,get_frame);
|
|
SafeCallErrorProc(res,get_frame);
|
|
- HandleErrorFrame(229,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(229,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
result:=res;
|
|
result:=res;
|
|
end;
|
|
end;
|
|
@@ -894,7 +930,7 @@ begin
|
|
Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
|
|
Writeln(pstdout^,'Runtime error ',Errorcode,' at $',hexstr(erroraddr));
|
|
{ to get a nice symify }
|
|
{ to get a nice symify }
|
|
Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
|
|
Writeln(pstdout^,BackTraceStrFunc(Erroraddr));
|
|
- dump_stack(pstdout^,ErrorBase);
|
|
|
|
|
|
+ dump_stack(pstdout^,ErrorBase,ErrorAddr);
|
|
Writeln(pstdout^,'');
|
|
Writeln(pstdout^,'');
|
|
End;
|
|
End;
|
|
|
|
|
|
@@ -1036,6 +1072,15 @@ begin
|
|
*)
|
|
*)
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{ This is used internally by system skip first level,
|
|
|
|
+ and generated the same output as before, when
|
|
|
|
+ HandleErrorFrame function was used internally. }
|
|
|
|
+Procedure HandleErrorAddrFrameInd (Errno : longint;addr,frame : Pointer);
|
|
|
|
+begin
|
|
|
|
+ get_caller_stackinfo (frame, addr);
|
|
|
|
+ HandleErrorAddrFrame (Errno,addr,frame);
|
|
|
|
+end;
|
|
|
|
+
|
|
Procedure HandleErrorFrame (Errno : longint;frame : Pointer);
|
|
Procedure HandleErrorFrame (Errno : longint;frame : Pointer);
|
|
{
|
|
{
|
|
Procedure to handle internal errors, i.e. not user-invoked errors
|
|
Procedure to handle internal errors, i.e. not user-invoked errors
|
|
@@ -1053,7 +1098,7 @@ Procedure fpc_handleerror (Errno : longint); compilerproc; [public,alias : 'FPC_
|
|
Internal function should ALWAYS call HandleError instead of RunError.
|
|
Internal function should ALWAYS call HandleError instead of RunError.
|
|
}
|
|
}
|
|
begin
|
|
begin
|
|
- HandleErrorFrame(Errno,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrame(Errno,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1061,8 +1106,8 @@ procedure RunError(w : word);[alias: 'FPC_RUNERROR'];
|
|
begin
|
|
begin
|
|
errorcode:=w;
|
|
errorcode:=w;
|
|
(*
|
|
(*
|
|
- erroraddr:=get_caller_addr(get_frame);
|
|
|
|
- errorbase:=get_caller_frame(get_frame);
|
|
|
|
|
|
+ erroraddr:=get_caller_addr(get_frame,get_pc_addr,);
|
|
|
|
+ errorbase:=get_caller_frame(get_frame,get_pc_addr);
|
|
*)
|
|
*)
|
|
Halt(errorcode);
|
|
Halt(errorcode);
|
|
end;
|
|
end;
|
|
@@ -1088,10 +1133,11 @@ end;
|
|
|
|
|
|
|
|
|
|
{$ifndef CPUJVM}
|
|
{$ifndef CPUJVM}
|
|
-Procedure dump_stack(var f : text;bp : Pointer);
|
|
|
|
|
|
+Procedure dump_stack(var f : text;bp,addr : Pointer);
|
|
var
|
|
var
|
|
i : Longint;
|
|
i : Longint;
|
|
prevbp : Pointer;
|
|
prevbp : Pointer;
|
|
|
|
+ prevaddr : pointer;
|
|
is_dev : boolean;
|
|
is_dev : boolean;
|
|
caller_frame,
|
|
caller_frame,
|
|
caller_addr : Pointer;
|
|
caller_addr : Pointer;
|
|
@@ -1100,12 +1146,13 @@ Begin
|
|
try
|
|
try
|
|
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
|
|
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
|
|
prevbp:=bp-1;
|
|
prevbp:=bp-1;
|
|
|
|
+ prevaddr:=nil;
|
|
i:=0;
|
|
i:=0;
|
|
is_dev:=do_isdevice(textrec(f).Handle);
|
|
is_dev:=do_isdevice(textrec(f).Handle);
|
|
while bp > prevbp Do
|
|
while bp > prevbp Do
|
|
Begin
|
|
Begin
|
|
- caller_addr := get_caller_addr(bp);
|
|
|
|
- caller_frame := get_caller_frame(bp);
|
|
|
|
|
|
+ caller_addr := get_caller_addr(bp,addr);
|
|
|
|
+ caller_frame := get_caller_frame(bp,addr);
|
|
if (caller_addr=nil) then
|
|
if (caller_addr=nil) then
|
|
break;
|
|
break;
|
|
Writeln(f,BackTraceStrFunc(caller_addr));
|
|
Writeln(f,BackTraceStrFunc(caller_addr));
|
|
@@ -1115,7 +1162,9 @@ Begin
|
|
If ((i>max_frame_dump) and is_dev) or (i>256) Then
|
|
If ((i>max_frame_dump) and is_dev) or (i>256) Then
|
|
break;
|
|
break;
|
|
prevbp:=bp;
|
|
prevbp:=bp;
|
|
|
|
+ prevaddr:=addr;
|
|
bp:=caller_frame;
|
|
bp:=caller_frame;
|
|
|
|
+ addr:=caller_addr;
|
|
End;
|
|
End;
|
|
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
|
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
|
except
|
|
except
|
|
@@ -1305,7 +1354,7 @@ begin
|
|
If pointer(AbstractErrorProc)<>nil then
|
|
If pointer(AbstractErrorProc)<>nil then
|
|
AbstractErrorProc();
|
|
AbstractErrorProc();
|
|
*)
|
|
*)
|
|
- HandleErrorFrame(211,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(211,get_pc_addr,get_frame);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1315,7 +1364,7 @@ begin
|
|
if pointer(AssertErrorProc)<>nil then
|
|
if pointer(AssertErrorProc)<>nil then
|
|
AssertErrorProc(Msg,FName,LineNo,ErrorAddr)
|
|
AssertErrorProc(Msg,FName,LineNo,ErrorAddr)
|
|
else
|
|
else
|
|
- HandleErrorFrame(227,get_frame);
|
|
|
|
|
|
+ HandleErrorAddrFrameInd(227,get_pc_addr,get_frame);
|
|
*)
|
|
*)
|
|
raise JLAssertionError.Create(JLObject(Fname+'('+unicodestring(JLInteger.valueOf(LineNo).toString)+'): '+Msg));
|
|
raise JLAssertionError.Create(JLObject(Fname+'('+unicodestring(JLInteger.valueOf(LineNo).toString)+'): '+Msg));
|
|
end;
|
|
end;
|