mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 02:49:21 +02:00
* size is now also checked
+ added halt_on_error variable (default true) to stop at first error in getmem/freemem
This commit is contained in:
parent
d84489d9b7
commit
47f406fc04
@ -33,6 +33,8 @@ const
|
|||||||
splitted in two if memory is released !! }
|
splitted in two if memory is released !! }
|
||||||
tracesize = 8;
|
tracesize = 8;
|
||||||
quicktrace : boolean=true;
|
quicktrace : boolean=true;
|
||||||
|
{ calls halt() on error by default !! }
|
||||||
|
halt_on_error : boolean = true;
|
||||||
{ set this to true if you suspect that memory
|
{ set this to true if you suspect that memory
|
||||||
is freed several times }
|
is freed several times }
|
||||||
keepreleased : boolean=false;
|
keepreleased : boolean=false;
|
||||||
@ -125,6 +127,13 @@ begin
|
|||||||
dump_stack(get_caller_frame(get_frame));
|
dump_stack(get_caller_frame(get_frame));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure dump_wrong_size(p : pheap_mem_info;size : longint);
|
||||||
|
begin
|
||||||
|
Writeln(stderr,'Marked memory at ',HexStr(longint(p+sizeof(theap_mem_info)),8),' invalid');
|
||||||
|
Writeln(stderr,'Wrong size : ',p^.size,' allocated ',size,' freed');
|
||||||
|
dump_stack(get_caller_frame(get_frame));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function is_in_getmem_list (p : pointer) : boolean;
|
function is_in_getmem_list (p : pointer) : boolean;
|
||||||
var
|
var
|
||||||
@ -192,22 +201,33 @@ end;
|
|||||||
|
|
||||||
procedure TraceFreeMem(var p:pointer;size:longint);
|
procedure TraceFreeMem(var p:pointer;size:longint);
|
||||||
|
|
||||||
var i,bp : longint;
|
var i,bp, ppsize : longint;
|
||||||
pp : pheap_mem_info;
|
pp : pheap_mem_info;
|
||||||
begin
|
begin
|
||||||
inc(freemem_size,size);
|
inc(freemem_size,size);
|
||||||
inc(freemem8_size,((size+7) div 8)*8);
|
inc(freemem8_size,((size+7) div 8)*8);
|
||||||
inc(size,sizeof(theap_mem_info)+extra_info_size);
|
ppsize:= size + sizeof(theap_mem_info)+extra_info_size;
|
||||||
dec(p,sizeof(theap_mem_info)+extra_info_size);
|
dec(p,sizeof(theap_mem_info)+extra_info_size);
|
||||||
pp:=pheap_mem_info(p);
|
pp:=pheap_mem_info(p);
|
||||||
if not quicktrace and not(is_in_getmem_list(p)) then
|
if not quicktrace and not(is_in_getmem_list(p)) then
|
||||||
RunError(204);
|
RunError(204);
|
||||||
if pp^.sig=$AAAAAAAA then
|
if pp^.sig=$AAAAAAAA then
|
||||||
dump_already_free(pp)
|
begin
|
||||||
|
dump_already_free(pp);
|
||||||
|
if halt_on_error then halt(1);
|
||||||
|
end
|
||||||
else if pp^.sig<>$DEADBEEF then
|
else if pp^.sig<>$DEADBEEF then
|
||||||
begin
|
begin
|
||||||
dump_error(pp);
|
dump_error(pp);
|
||||||
{ don't release anything in this case !! }
|
{ don't release anything in this case !! }
|
||||||
|
if halt_on_error then halt(1);
|
||||||
|
exit;
|
||||||
|
end
|
||||||
|
else if pp^.size<>size then
|
||||||
|
begin
|
||||||
|
dump_wrong_size(pp,size);
|
||||||
|
if halt_on_error then halt(1);
|
||||||
|
{ don't release anything in this case !! }
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
{ now it is released !! }
|
{ now it is released !! }
|
||||||
@ -220,22 +240,22 @@ begin
|
|||||||
pp^.previous^.next:=pp^.next;
|
pp^.previous^.next:=pp^.next;
|
||||||
if pp=heap_mem_root then
|
if pp=heap_mem_root then
|
||||||
heap_mem_root:=heap_mem_root^.previous;
|
heap_mem_root:=heap_mem_root^.previous;
|
||||||
|
bp:=get_caller_frame(get_frame);
|
||||||
|
for i:=(tracesize div 2)+1 to tracesize do
|
||||||
|
begin
|
||||||
|
pp^.calls[i]:=get_caller_addr(bp);
|
||||||
|
bp:=get_caller_frame(bp);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
bp:=get_caller_frame(get_frame);
|
|
||||||
for i:=(tracesize div 2)+1 to tracesize do
|
|
||||||
begin
|
|
||||||
pp^.calls[i]:=get_caller_addr(bp);
|
|
||||||
bp:=get_caller_frame(bp);
|
|
||||||
end;
|
|
||||||
inc(freemem_cnt);
|
inc(freemem_cnt);
|
||||||
{ release the normal memory at least !! }
|
{ release the normal memory at least !! }
|
||||||
{ this way we keep all info about all released memory !! }
|
{ this way we keep all info about all released memory !! }
|
||||||
if keepreleased then
|
if keepreleased then
|
||||||
begin
|
begin
|
||||||
dec(size,sizeof(theap_mem_info)+extra_info_size);
|
dec(ppsize,sizeof(theap_mem_info)+extra_info_size);
|
||||||
inc(p,sizeof(theap_mem_info)+extra_info_size);
|
inc(p,sizeof(theap_mem_info)+extra_info_size);
|
||||||
end;
|
end;
|
||||||
SysFreeMem(p,size);
|
SysFreeMem(p,ppsize);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -336,7 +356,12 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.5 1998-10-09 11:59:31 pierre
|
Revision 1.6 1998-11-06 08:46:01 pierre
|
||||||
|
* size is now also checked
|
||||||
|
+ added halt_on_error variable (default true)
|
||||||
|
to stop at first error in getmem/freemem
|
||||||
|
|
||||||
|
Revision 1.5 1998/10/09 11:59:31 pierre
|
||||||
* changed default to keepreleased=false
|
* changed default to keepreleased=false
|
||||||
(allows to compile pp in one call without reaching the
|
(allows to compile pp in one call without reaching the
|
||||||
64Mb limit of Windows 95 dos box)
|
64Mb limit of Windows 95 dos box)
|
||||||
|
Loading…
Reference in New Issue
Block a user