mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 04:29:29 +02:00
--- Merging r29678 into '.':
U rtl/win64/seh64.inc --- Recording mergeinfo for merge of r29678 into '.': U . --- Merging r29692 into '.': U rtl/inc/system.inc U rtl/win64/system.pp G rtl/win64/seh64.inc --- Recording mergeinfo for merge of r29692 into '.': G . --- Merging r29713 into '.': U rtl/inc/systemh.inc G rtl/inc/system.inc U rtl/inc/heaptrc.pp --- Recording mergeinfo for merge of r29713 into '.': G . --- Merging r29733 into '.': G rtl/inc/system.inc --- Recording mergeinfo for merge of r29733 into '.': G . --- Merging r29739 into '.': G rtl/inc/system.inc --- Recording mergeinfo for merge of r29739 into '.': G . # revisions: 29678,29692,29713,29733,29739 ------------------------------------------------------------------------ r29678 | sergei | 2015-02-13 06:02:20 +0100 (vr, 13 feb 2015) | 2 lines Changed paths: M /trunk/rtl/win64/seh64.inc * Win64 SEH: don't call RunError in exception handler, because it always prints backtrace from caller's context. Instead, print the correct backtrace explicitly. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r29692 | sergei | 2015-02-14 12:41:33 +0100 (za, 14 feb 2015) | 1 line Changed paths: M /trunk/rtl/inc/system.inc M /trunk/rtl/win64/seh64.inc M /trunk/rtl/win64/system.pp * Win64: Use separate implementation of CaptureBacktrace that calls RtlCaptureStackBackTrace. This way it does not require non-optimized code to work correctly. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r29713 | sergei | 2015-02-15 21:00:24 +0100 (zo, 15 feb 2015) | 2 lines Changed paths: M /trunk/rtl/inc/heaptrc.pp M /trunk/rtl/inc/system.inc M /trunk/rtl/inc/systemh.inc + Overloaded procedure dump_stack that calls CaptureBacktrace, thus encapsulating internals of stack traversing. * Use this new procedure in heaptrc unit. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r29733 | sergei | 2015-02-16 23:05:54 +0100 (ma, 16 feb 2015) | 7 lines Changed paths: M /trunk/rtl/inc/system.inc * Finalize units after printing the runtime error message. Rationale: * Unit finalization executes arbitrarily large amount of code. Doing it when error occurred can cause other errors, overwriting the original error information. * Code that prints error message depends on everything and a kitchen sink (most notably, Unicode manager and lineinfo unit). Running it after finalizing units can be successful only by coincidence. * Last but not least, this sequence (ExitProc -> print RTE -> finalize units) is same as one used in Delphi. ------------------------------------------------------------------------ ------------------------------------------------------------------------ r29739 | pierre | 2015-02-17 08:35:31 +0100 (di, 17 feb 2015) | 1 line Changed paths: M /trunk/rtl/inc/system.inc Revert aligntoptr to RTTIAlign rename ------------------------------------------------------------------------ git-svn-id: branches/fixes_3_0@33410 -
This commit is contained in:
parent
8cc21d5591
commit
158da745d0
@ -334,23 +334,14 @@ end;
|
||||
|
||||
|
||||
procedure dump_already_free(p : pheap_mem_info;var ptext : text);
|
||||
var
|
||||
bp : pointer;
|
||||
pcaddr : codepointer;
|
||||
begin
|
||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' released');
|
||||
call_free_stack(p,ptext);
|
||||
Writeln(ptext,'freed again at');
|
||||
bp:=get_frame;
|
||||
pcaddr:=get_pc_addr;
|
||||
get_caller_stackinfo(bp,pcaddr);
|
||||
dump_stack(ptext,bp,pcaddr);
|
||||
dump_stack(ptext,1);
|
||||
end;
|
||||
|
||||
procedure dump_error(p : pheap_mem_info;var ptext : text);
|
||||
var
|
||||
bp : pointer;
|
||||
pcaddr : codepointer;
|
||||
begin
|
||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
||||
Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8));
|
||||
@ -359,10 +350,7 @@ begin
|
||||
write(ptext, 'Block content: ');
|
||||
printhex(pointer(p) + sizeof(theap_mem_info), p^.size, ptext);
|
||||
end;
|
||||
bp:=get_frame;
|
||||
pcaddr:=get_pc_addr;
|
||||
get_caller_stackinfo(bp,pcaddr);
|
||||
dump_stack(ptext,bp,pcaddr);
|
||||
dump_stack(ptext,1);
|
||||
end;
|
||||
|
||||
{$ifdef EXTRA}
|
||||
@ -382,16 +370,10 @@ end;
|
||||
{$endif EXTRA}
|
||||
|
||||
procedure dump_wrong_size(p : pheap_mem_info;size : ptruint;var ptext : text);
|
||||
var
|
||||
bp : pointer;
|
||||
pcaddr : codepointer;
|
||||
begin
|
||||
Writeln(ptext,'Marked memory at $',HexStr(pointer(p)+sizeof(theap_mem_info)),' invalid');
|
||||
Writeln(ptext,'Wrong size : ',p^.size,' allocated ',size,' freed');
|
||||
bp:=get_frame;
|
||||
pcaddr:=get_pc_addr;
|
||||
get_caller_stackinfo(bp,pcaddr);
|
||||
dump_stack(ptext,bp,pcaddr);
|
||||
dump_stack(ptext,1);
|
||||
{ the check is done to be sure that the procvar is not overwritten }
|
||||
if assigned(p^.extra_info) and
|
||||
(p^.extra_info^.check=$12345678) and
|
||||
@ -961,8 +943,6 @@ var
|
||||
{$ifdef windows}
|
||||
datap : pointer;
|
||||
{$endif windows}
|
||||
bp : pointer;
|
||||
pcaddr : codepointer;
|
||||
ptext : ^text;
|
||||
begin
|
||||
if p=nil then
|
||||
@ -1117,10 +1097,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
writeln(ptext^,'pointer $',hexstr(p),' does not point to valid memory block');
|
||||
bp:=get_frame;
|
||||
pcaddr:=get_pc_addr;
|
||||
get_caller_stackinfo(bp,pcaddr);
|
||||
dump_stack(ptext^,bp,pcaddr);
|
||||
dump_stack(ptext^,1);
|
||||
runerror(204);
|
||||
end;
|
||||
|
||||
|
@ -557,8 +557,6 @@ const
|
||||
|
||||
VAR
|
||||
mt : tMT19937StateArray;
|
||||
|
||||
const
|
||||
mti: longint=MT19937N+1; // mti=MT19937N+1 means mt[] is not initialized
|
||||
|
||||
{ Initializing the array with a seed }
|
||||
@ -973,8 +971,6 @@ Begin
|
||||
exitProc:=nil;
|
||||
current_exit();
|
||||
End;
|
||||
{ Finalize units }
|
||||
FinalizeUnits;
|
||||
|
||||
{$ifdef FPC_HAS_FEATURE_CONSOLEIO}
|
||||
{ the embedded system unit itself contains no routines for console i/o
|
||||
@ -998,6 +994,9 @@ Begin
|
||||
{$endif EMBEDDED}
|
||||
{$endif FPC_HAS_FEATURE_CONSOLEIO}
|
||||
|
||||
{ Finalize units }
|
||||
FinalizeUnits;
|
||||
|
||||
{$if defined(MSWINDOWS) or defined(OS2)}
|
||||
{ finally release the heap if possible, especially
|
||||
important for DLLs.
|
||||
@ -1070,6 +1069,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_CAPTUREBACKTRACE}
|
||||
function CaptureBacktrace(skipframes,count:sizeint;frames:PCodePointer):sizeint;
|
||||
var
|
||||
curr_frame,prev_frame: pointer;
|
||||
@ -1098,6 +1098,7 @@ begin
|
||||
else
|
||||
result:=i;
|
||||
end;
|
||||
{$endif FPC_SYSTEM_HAS_CAPTUREBACKTRACE}
|
||||
|
||||
|
||||
Procedure HandleErrorAddrFrame (Errno : longint;addr : CodePointer; frame : Pointer);[public,alias:'FPC_BREAK_ERROR']; {$ifdef CPUI386} register; {$endif}
|
||||
@ -1213,6 +1214,28 @@ Begin
|
||||
End;
|
||||
|
||||
|
||||
procedure dump_stack(var f: text; skipframes: longint);
|
||||
var
|
||||
i,count: longint;
|
||||
frames: array [0..255] of codepointer;
|
||||
begin
|
||||
if do_isdevice(textrec(f).handle) then
|
||||
count:=max_frame_dump
|
||||
else
|
||||
count:=255;
|
||||
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
try
|
||||
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
count:=CaptureBacktrace(skipframes+1,count,@frames[0]);
|
||||
for i:=0 to count-1 do
|
||||
writeln(f,BackTraceStrFunc(frames[i]));
|
||||
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
except
|
||||
end;
|
||||
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
procedure DumpExceptionBackTrace(var f:text);
|
||||
var
|
||||
|
@ -1398,6 +1398,7 @@ Function ParamStr(l:Longint):string;
|
||||
{$endif FPC_HAS_FEATURE_COMMANDARGS}
|
||||
|
||||
Procedure Dump_Stack(var f : text;fp:pointer;addr : codepointer = nil);
|
||||
procedure Dump_Stack(var f : text;skipframes : longint);
|
||||
{$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
procedure DumpExceptionBackTrace(var f:text);
|
||||
{$endif FPC_HAS_FEATURE_EXCEPTIONS}
|
||||
|
@ -213,6 +213,12 @@ type
|
||||
end;
|
||||
|
||||
|
||||
function CaptureBacktrace(skipframes,count:sizeint;frames:PCodePointer):sizeint;
|
||||
begin
|
||||
{ skipframes is increased because this function adds a call level }
|
||||
Result:=RtlCaptureStackBackTrace(skipframes+1,count,frames^,nil);
|
||||
end;
|
||||
|
||||
{ note: context must be passed by value, so modifications are made to a local copy }
|
||||
function GetBacktrace(Context: TContext; StartingFrame: Pointer; out Frames: PPointer): Longint;
|
||||
var
|
||||
@ -375,6 +381,8 @@ label L1;
|
||||
var
|
||||
exc: PExceptObject;
|
||||
obj: TObject;
|
||||
hstdout: ^text;
|
||||
i,code: Longint;
|
||||
begin
|
||||
if (rec.ExceptionFlags and EXCEPTION_UNWIND)=0 then
|
||||
begin
|
||||
@ -391,7 +399,19 @@ begin
|
||||
begin
|
||||
Exc:=ExceptObjectStack;
|
||||
if Exc^.FObject=nil then
|
||||
RunError(abs(RunErrorCodex64(rec,context))) // !!prints wrong backtrace
|
||||
begin
|
||||
hstdout:=@stdout;
|
||||
code:=abs(RunErrorCodex64(rec,context));
|
||||
Writeln(hstdout^,'Runtime error ',code,' at $',hexstr(Exc^.addr));
|
||||
Writeln(hstdout^,BackTraceStrFunc(Exc^.Addr));
|
||||
if (Exc^.FrameCount>0) then
|
||||
begin
|
||||
for i:=0 to Exc^.FrameCount-1 do
|
||||
Writeln(hstdout^,BackTraceStrFunc(Exc^.Frames[i]));
|
||||
end;
|
||||
Writeln(hstdout^,'');
|
||||
Halt(code);
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ if ExceptObjProc=nil, ExceptProc is typically also nil,
|
||||
@ -404,8 +424,10 @@ begin
|
||||
L1:
|
||||
{ RtlUnwindEx above resets execution context to the point where the handler
|
||||
was installed, i.e. main_wrapper. It makes exiting this procedure no longer
|
||||
possible, halting is the only possible action here. }
|
||||
RunError(217);
|
||||
possible. Halting is the only possible action here.
|
||||
Furthermore, this is not expected to execute at all, because the above block
|
||||
definitely halts. }
|
||||
Halt(217);
|
||||
end;
|
||||
end;
|
||||
result:=ExceptionContinueSearch;
|
||||
|
@ -29,6 +29,7 @@ interface
|
||||
{$ifdef FPC_USE_WIN64_SEH}
|
||||
{$define FPC_SYSTEM_HAS_RAISEEXCEPTION}
|
||||
{$define FPC_SYSTEM_HAS_RERAISE}
|
||||
{$define FPC_SYSTEM_HAS_CAPTUREBACKTRACE}
|
||||
{$endif FPC_USE_WIN64_SEH}
|
||||
|
||||
{ include system-independent routine headers }
|
||||
|
Loading…
Reference in New Issue
Block a user