mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 21:29:42 +02:00
+ Add tail_size varaible to be able to adjust size of tail memory area.
* Correct computation of CRC for if add_tail is true: tail is before extra_info, not after. Use tail_size variable to cacluate CRC use the whole tail memory area. + New function released_modified. Checks if released memory was modified after it release (used if keep_released is true). * TraceGetMem,TraceFreeMem TraceReallocMem: adapt to new tail_size variable. * TraceInit: Store previous memory manager in local variable, to be able to restore it in TracExit call. * LoadEnvironment: Add parsing of tail_size=XXX, where XXX is a decimal value, rounded up to next multiple of sizeof(ptruint). git-svn-id: trunk@34385 -
This commit is contained in:
parent
1612138071
commit
b6b27f2fb7
@ -82,6 +82,8 @@ const
|
|||||||
{ add a small footprint at the end of memory blocks, this
|
{ add a small footprint at the end of memory blocks, this
|
||||||
can check for memory overwrites at the end of a block }
|
can check for memory overwrites at the end of a block }
|
||||||
add_tail : boolean = true;
|
add_tail : boolean = true;
|
||||||
|
tail_size : longint = sizeof(ptruint);
|
||||||
|
|
||||||
{ put crc in sig
|
{ put crc in sig
|
||||||
this allows to test for writing into that part }
|
this allows to test for writing into that part }
|
||||||
usecrc : boolean = true;
|
usecrc : boolean = true;
|
||||||
@ -233,8 +235,8 @@ begin
|
|||||||
if add_tail then
|
if add_tail then
|
||||||
begin
|
begin
|
||||||
{ Check also 4 bytes just after allocation !! }
|
{ Check also 4 bytes just after allocation !! }
|
||||||
pl:=pointer(p)+p^.extra_info_size+sizeof(theap_mem_info)+p^.size;
|
pl:=pointer(p)+sizeof(theap_mem_info)+p^.size;
|
||||||
crc:=UpdateCrc32(crc,pl^,sizeof(ptruint));
|
crc:=UpdateCrc32(crc,pl^,tail_size);
|
||||||
end;
|
end;
|
||||||
calculate_sig:=crc;
|
calculate_sig:=crc;
|
||||||
end;
|
end;
|
||||||
@ -258,7 +260,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
{ Check also 4 bytes just after allocation !! }
|
{ Check also 4 bytes just after allocation !! }
|
||||||
pl:=pointer(p)+p^.extra_info_size+sizeof(theap_mem_info)+p^.size;
|
pl:=pointer(p)+p^.extra_info_size+sizeof(theap_mem_info)+p^.size;
|
||||||
crc:=UpdateCrc32(crc,pl^,sizeof(ptruint));
|
crc:=UpdateCrc32(crc,pl^,tail_size);
|
||||||
end;
|
end;
|
||||||
calculate_release_sig:=crc;
|
calculate_release_sig:=crc;
|
||||||
end;
|
end;
|
||||||
@ -364,6 +366,40 @@ begin
|
|||||||
dump_stack(ptext,1);
|
dump_stack(ptext,1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function released_modified(p : pheap_mem_info;var ptext : text) : boolean;
|
||||||
|
var pl : pdword;
|
||||||
|
pb : pbyte;
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
released_modified:=false;
|
||||||
|
{ Check tail_size bytes just after allocation !! }
|
||||||
|
pl:=pointer(p)+sizeof(theap_mem_info)+p^.size;
|
||||||
|
pb:=pointer(p)+sizeof(theap_mem_info);
|
||||||
|
for i:=0 to p^.size-1 do
|
||||||
|
if pb[i]<>$F0 then
|
||||||
|
begin
|
||||||
|
Writeln(ptext,'offset',i,':$',hexstr(i,2*sizeof(pointer)),'"',hexstr(pb[i],2),'"');
|
||||||
|
released_modified:=true;
|
||||||
|
end;
|
||||||
|
for i:=1 to (tail_size div sizeof(dword)) do
|
||||||
|
begin
|
||||||
|
if unaligned(pl^) <> AllocateSig then
|
||||||
|
begin
|
||||||
|
released_modified:=true;
|
||||||
|
writeln(ptext,'Tail modified after release at pos ',i*sizeof(ptruint));
|
||||||
|
printhex(pointer(p)+p^.extra_info_size+sizeof(theap_mem_info)+p^.size,tail_size,ptext);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
inc(pointer(pl),sizeof(dword));
|
||||||
|
end;
|
||||||
|
if released_modified then
|
||||||
|
begin
|
||||||
|
dump_already_free(p,ptext);
|
||||||
|
if @stderr<>@ptext then
|
||||||
|
dump_already_free(p,stderr);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{$ifdef EXTRA}
|
{$ifdef EXTRA}
|
||||||
procedure dump_change_after(p : pheap_mem_info;var ptext : text);
|
procedure dump_change_after(p : pheap_mem_info;var ptext : text);
|
||||||
var pp : pchar;
|
var pp : pchar;
|
||||||
@ -457,7 +493,7 @@ end;
|
|||||||
|
|
||||||
Function TraceGetMem(size:ptruint):pointer;
|
Function TraceGetMem(size:ptruint):pointer;
|
||||||
var
|
var
|
||||||
allocsize : ptruint;
|
i, allocsize : ptruint;
|
||||||
pl : pdword;
|
pl : pdword;
|
||||||
p : pointer;
|
p : pointer;
|
||||||
pp : pheap_mem_info;
|
pp : pheap_mem_info;
|
||||||
@ -474,7 +510,7 @@ begin
|
|||||||
allocsize:=size+sizeof(theap_mem_info)+extra_info_size;
|
allocsize:=size+sizeof(theap_mem_info)+extra_info_size;
|
||||||
{$endif cpuarm}
|
{$endif cpuarm}
|
||||||
if add_tail then
|
if add_tail then
|
||||||
inc(allocsize,sizeof(ptruint));
|
inc(allocsize,tail_size);
|
||||||
{ if ReturnNilIfGrowHeapFails is true
|
{ if ReturnNilIfGrowHeapFails is true
|
||||||
SysGetMem can return nil }
|
SysGetMem can return nil }
|
||||||
p:=SysGetMem(allocsize);
|
p:=SysGetMem(allocsize);
|
||||||
@ -515,8 +551,12 @@ begin
|
|||||||
pp^.extra_info:=nil;
|
pp^.extra_info:=nil;
|
||||||
if add_tail then
|
if add_tail then
|
||||||
begin
|
begin
|
||||||
pl:=pointer(pp)+allocsize-pp^.extra_info_size-sizeof(ptruint);
|
pl:=pointer(pp)+allocsize-pp^.extra_info_size-tail_size;
|
||||||
unaligned(pl^):=longword(AllocateSig);
|
for i:=1 to tail_size div sizeof(dword) do
|
||||||
|
begin
|
||||||
|
unaligned(pl^):=dword(AllocateSig);
|
||||||
|
inc(pointer(pl),sizeof(dword));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{ clear the memory }
|
{ clear the memory }
|
||||||
fillchar(p^,size,#255);
|
fillchar(p^,size,#255);
|
||||||
@ -658,7 +698,7 @@ begin
|
|||||||
extra_size:=pp^.extra_info_size;
|
extra_size:=pp^.extra_info_size;
|
||||||
ppsize:= size+sizeof(theap_mem_info)+pp^.extra_info_size;
|
ppsize:= size+sizeof(theap_mem_info)+pp^.extra_info_size;
|
||||||
if add_tail then
|
if add_tail then
|
||||||
inc(ppsize,sizeof(ptruint));
|
inc(ppsize,tail_size);
|
||||||
{ do various checking }
|
{ do various checking }
|
||||||
release_mem := CheckFreeMemSize(loc_info, pp, size, ppsize);
|
release_mem := CheckFreeMemSize(loc_info, pp, size, ppsize);
|
||||||
if release_todo_lock then
|
if release_todo_lock then
|
||||||
@ -670,7 +710,7 @@ begin
|
|||||||
{ return the correct size }
|
{ return the correct size }
|
||||||
dec(i,sizeof(theap_mem_info)+extra_size);
|
dec(i,sizeof(theap_mem_info)+extra_size);
|
||||||
if add_tail then
|
if add_tail then
|
||||||
dec(i,sizeof(ptruint));
|
dec(i,tail_size);
|
||||||
InternalFreeMemSize:=i;
|
InternalFreeMemSize:=i;
|
||||||
end else
|
end else
|
||||||
InternalFreeMemSize:=size;
|
InternalFreeMemSize:=size;
|
||||||
@ -737,7 +777,7 @@ begin
|
|||||||
l:=SysMemSize(pp);
|
l:=SysMemSize(pp);
|
||||||
dec(l,sizeof(theap_mem_info)+pp^.extra_info_size);
|
dec(l,sizeof(theap_mem_info)+pp^.extra_info_size);
|
||||||
if add_tail then
|
if add_tail then
|
||||||
dec(l,sizeof(ptruint));
|
dec(l,tail_size);
|
||||||
{ this can never happend normaly }
|
{ this can never happend normaly }
|
||||||
if pp^.size>l then
|
if pp^.size>l then
|
||||||
begin
|
begin
|
||||||
@ -761,7 +801,7 @@ end;
|
|||||||
function TraceReAllocMem(var p:pointer;size:ptruint):Pointer;
|
function TraceReAllocMem(var p:pointer;size:ptruint):Pointer;
|
||||||
var
|
var
|
||||||
newP: pointer;
|
newP: pointer;
|
||||||
allocsize,
|
i, allocsize,
|
||||||
movesize : ptruint;
|
movesize : ptruint;
|
||||||
pl : pdword;
|
pl : pdword;
|
||||||
pp : pheap_mem_info;
|
pp : pheap_mem_info;
|
||||||
@ -823,7 +863,7 @@ begin
|
|||||||
allocsize:=size+sizeof(theap_mem_info)+pp^.extra_info_size;
|
allocsize:=size+sizeof(theap_mem_info)+pp^.extra_info_size;
|
||||||
{$endif cpuarm}
|
{$endif cpuarm}
|
||||||
if add_tail then
|
if add_tail then
|
||||||
inc(allocsize,sizeof(ptruint));
|
inc(allocsize,tail_size);
|
||||||
{ Try to resize the block, if not possible we need to do a
|
{ Try to resize the block, if not possible we need to do a
|
||||||
getmem, move data, freemem }
|
getmem, move data, freemem }
|
||||||
if not SysTryResizeMem(pp,allocsize) then
|
if not SysTryResizeMem(pp,allocsize) then
|
||||||
@ -867,9 +907,13 @@ begin
|
|||||||
pp^.extra_info:=nil;
|
pp^.extra_info:=nil;
|
||||||
if add_tail then
|
if add_tail then
|
||||||
begin
|
begin
|
||||||
pl:=pointer(pp)+allocsize-pp^.extra_info_size-sizeof(ptruint);
|
pl:=pointer(pp)+allocsize-pp^.extra_info_size-tail_size;
|
||||||
unaligned(pl^):=longword(AllocateSig);
|
for i:=1 to tail_size div sizeof(dword) do
|
||||||
end;
|
begin
|
||||||
|
unaligned(pl^):=dword(AllocateSig);
|
||||||
|
inc(pointer(pl),sizeof(dword));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
{ adjust like a freemem and then a getmem, so you get correct
|
{ adjust like a freemem and then a getmem, so you get correct
|
||||||
results in the summary display }
|
results in the summary display }
|
||||||
inc(loc_info^.freemem_size,oldsize);
|
inc(loc_info^.freemem_size,oldsize);
|
||||||
@ -1175,6 +1219,8 @@ begin
|
|||||||
else if pp^.sig<>longword(ReleaseSig) then
|
else if pp^.sig<>longword(ReleaseSig) then
|
||||||
begin
|
begin
|
||||||
dump_error(pp,ptext^);
|
dump_error(pp,ptext^);
|
||||||
|
if @stderr<>ptext then
|
||||||
|
dump_error(pp,stderr);
|
||||||
{$ifdef EXTRA}
|
{$ifdef EXTRA}
|
||||||
dump_error(pp,error_file);
|
dump_error(pp,error_file);
|
||||||
{$endif EXTRA}
|
{$endif EXTRA}
|
||||||
@ -1187,6 +1233,12 @@ begin
|
|||||||
dump_change_after(pp,error_file);
|
dump_change_after(pp,error_file);
|
||||||
loc_info^.error_in_heap:=true;
|
loc_info^.error_in_heap:=true;
|
||||||
end
|
end
|
||||||
|
{$else not EXTRA}
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if released_modified(pp,ptext^) then
|
||||||
|
exitcode:=203;
|
||||||
|
end;
|
||||||
{$endif EXTRA}
|
{$endif EXTRA}
|
||||||
;
|
;
|
||||||
pp:=pp^.previous;
|
pp:=pp^.previous;
|
||||||
@ -1364,6 +1416,9 @@ const
|
|||||||
GetFPCHeapStatus : @TraceGetFPCHeapStatus;
|
GetFPCHeapStatus : @TraceGetFPCHeapStatus;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var
|
||||||
|
PrevMemoryManager : TMemoryManager;
|
||||||
|
|
||||||
procedure TraceInit;
|
procedure TraceInit;
|
||||||
begin
|
begin
|
||||||
textoutput := @stderr;
|
textoutput := @stderr;
|
||||||
@ -1372,6 +1427,7 @@ begin
|
|||||||
main_orig_todolist := @heap_info.heap_free_todo;
|
main_orig_todolist := @heap_info.heap_free_todo;
|
||||||
main_relo_todolist := nil;
|
main_relo_todolist := nil;
|
||||||
TraceInitThread;
|
TraceInitThread;
|
||||||
|
GetMemoryManager(PrevMemoryManager);
|
||||||
SetMemoryManager(TraceManager);
|
SetMemoryManager(TraceManager);
|
||||||
useownfile:=false;
|
useownfile:=false;
|
||||||
if outputstr <> '' then
|
if outputstr <> '' then
|
||||||
@ -1421,6 +1477,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
{ Disable heaptrc memory manager to avoid problems }
|
||||||
|
GetMemoryManager(PrevMemoryManager);
|
||||||
move_heap_info(@orphaned_info, @heap_info);
|
move_heap_info(@orphaned_info, @heap_info);
|
||||||
dumpheap;
|
dumpheap;
|
||||||
if heap_info.error_in_heap and (exitcode=0) then
|
if heap_info.error_in_heap and (exitcode=0) then
|
||||||
@ -1559,7 +1617,8 @@ end;
|
|||||||
procedure LoadEnvironment;
|
procedure LoadEnvironment;
|
||||||
var
|
var
|
||||||
i,j : ptruint;
|
i,j : ptruint;
|
||||||
s : string;
|
s,s2 : string;
|
||||||
|
err : word;
|
||||||
begin
|
begin
|
||||||
s:=Getenv('HEAPTRC');
|
s:=Getenv('HEAPTRC');
|
||||||
if pos('keepreleased',s)>0 then
|
if pos('keepreleased',s)>0 then
|
||||||
@ -1572,6 +1631,22 @@ begin
|
|||||||
HaltOnNotReleased :=true;
|
HaltOnNotReleased :=true;
|
||||||
if pos('skipifnoleaks',s)>0 then
|
if pos('skipifnoleaks',s)>0 then
|
||||||
GlobalSkipIfNoLeaks :=true;
|
GlobalSkipIfNoLeaks :=true;
|
||||||
|
if pos('tail_size=',s)>0 then
|
||||||
|
begin
|
||||||
|
i:=pos('tail_size=',s)+length('tail_size=');
|
||||||
|
s2:='';
|
||||||
|
while (i<=length(s)) and (s[i] in ['0'..'9']) do
|
||||||
|
begin
|
||||||
|
s2:=s2+s[i];
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
val(s2,tail_size,err);
|
||||||
|
if err=0 then
|
||||||
|
tail_size:=((tail_size + sizeof(ptruint)-1) div sizeof(ptruint)) * sizeof(ptruint)
|
||||||
|
else
|
||||||
|
tail_size:=sizeof(ptruint);
|
||||||
|
add_tail:=(tail_size > 0);
|
||||||
|
end;
|
||||||
i:=pos('log=',s);
|
i:=pos('log=',s);
|
||||||
if i>0 then
|
if i>0 then
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user