* allow runtime setting using the environment HEAPTRC

This commit is contained in:
peter 2001-04-12 18:00:14 +00:00
parent 273db58aed
commit 03d4bdcd40

View File

@ -16,6 +16,11 @@
unit heaptrc;
interface
{ 1.0.x doesn't have good rangechecking for cardinals }
{$ifdef VER1_0}
{$R-}
{$endif}
Procedure DumpHeap;
Procedure MarkHeap;
@ -44,6 +49,9 @@ const
{$else EXTRA}
tracesize = 8;
{$endif EXTRA}
{ install heaptrc memorymanager }
useheaptrace : boolean=true;
{ less checking }
quicktrace : boolean=true;
{ calls halt() on error by default !! }
HaltOnError : boolean = true;
@ -82,7 +90,8 @@ const
type
pheap_extra_info = ^theap_extra_info;
theap_extra_info = record
fillproc : tfillextrainfoProc;
check : cardinal; { used to check if the procvar is still valid }
fillproc : tfillextrainfoProc;
displayproc : tdisplayextrainfoProc;
data : record
end;
@ -223,7 +232,10 @@ begin
for i:=1 to tracesize do
if pp^.calls[i]<>0 then
writeln(ptext,BackTraceStrFunc(pp^.calls[i]));
if assigned(pp^.extra_info^.displayproc) then
{ the check is done to be sure that the procvar is not overwritten }
if assigned(pp^.extra_info) and
(pp^.extra_info^.check=$12345678) and
assigned(pp^.extra_info^.displayproc) then
pp^.extra_info^.displayproc(ptext,@pp^.extra_info^.data);
end;
@ -240,8 +252,11 @@ begin
for i:=(tracesize div 2)+1 to tracesize do
if pp^.calls[i]<>0 then
writeln(ptext,BackTraceStrFunc(pp^.calls[i]));
for i:=0 to (pp^.exact_info_size div 4)-1 do
writeln(ptext,'info ',i,'=',plongint(pointer(pp^.extra_info)+4*i)^);
{ the check is done to be sure that the procvar is not overwritten }
if assigned(pp^.extra_info) and
(pp^.extra_info^.check=$12345678) and
assigned(pp^.extra_info^.displayproc) then
pp^.extra_info^.displayproc(ptext,@pp^.extra_info^.data);
end;
@ -277,14 +292,15 @@ end;
{$endif EXTRA}
procedure dump_wrong_size(p : pheap_mem_info;size : longint;var ptext : text);
var
i : longint;
begin
Writeln(ptext,'Marked memory at 0x',HexStr(longint(pointer(p)+sizeof(theap_mem_info)),8),' invalid');
Writeln(ptext,'Wrong size : ',p^.size,' allocated ',size,' freed');
dump_stack(ptext,get_caller_frame(get_frame));
for i:=0 to (p^.exact_info_size div 4)-1 do
writeln(ptext,'info ',i,'=',plongint(p^.extra_info+4*i)^);
{ 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
assigned(p^.extra_info^.displayproc) then
p^.extra_info^.displayproc(ptext,@p^.extra_info^.data);
call_stack(p,ptext);
end;
@ -323,7 +339,7 @@ end;
Function TraceGetMem(size:longint):pointer;
var
i,bp : longint;
pl : plongint;
pl : pdword;
p : pointer;
pp : pheap_mem_info;
begin
@ -349,6 +365,7 @@ begin
begin
pp^.extra_info:=pointer(p)+bp-extra_info_size;
fillchar(pp^.extra_info^,extra_info_size,0);
pp^.extra_info^.check:=$12345678;
pp^.extra_info^.fillproc:=fill_extra_info_proc;
pp^.extra_info^.displayproc:=display_extra_info_proc;
if assigned(fill_extra_info_proc) then
@ -359,7 +376,7 @@ begin
end;
end
else
pp^.extra_info:=nil;
pp^.extra_info:=nil;
if add_tail then
begin
pl:=pointer(p)+bp-extra_info_size-sizeof(longint);
@ -556,7 +573,7 @@ var
oldsize,
allocsize,
i,bp : longint;
pl : plongint;
pl : pdword;
pp : pheap_mem_info;
oldextrasize,
oldexactsize : longint;
@ -601,7 +618,7 @@ begin
begin
old_fill_extra_info_proc:=pp^.extra_info^.fillproc;
old_display_extra_info_proc:=pp^.extra_info^.displayproc;
end;
end;
{ Do the real ReAllocMem, but alloc also for the info block }
allocsize:=size+sizeof(theap_mem_info)+pp^.extra_info_size;
if add_tail then
@ -641,13 +658,14 @@ begin
begin
pp^.extra_info:=p+allocsize-pp^.extra_info_size;
fillchar(pp^.extra_info^,extra_info_size,0);
pp^.extra_info^.check:=$12345678;
pp^.extra_info^.fillproc:=old_fill_extra_info_proc;
pp^.extra_info^.displayproc:=old_display_extra_info_proc;
if assigned(pp^.extra_info^.fillproc) then
pp^.extra_info^.fillproc(@pp^.extra_info^.data);
end
else
pp^.extra_info:=nil;
pp^.extra_info:=nil;
if add_tail then
begin
pl:=pointer(p)+allocsize-pp^.extra_info_size-sizeof(longint);
@ -924,6 +942,41 @@ begin
end;
{*****************************************************************************
Program Hooks
*****************************************************************************}
Procedure SetHeapTraceOutput(const name : string);
var i : longint;
begin
if ptext<>@stderr then
begin
ptext:=@stderr;
close(ownfile);
end;
assign(ownfile,name);
{$I-}
append(ownfile);
if IOResult<>0 then
Rewrite(ownfile);
{$I+}
ptext:=@ownfile;
for i:=0 to Paramcount do
write(ptext^,paramstr(i),' ');
writeln(ptext^);
end;
procedure SetHeapExtraInfo( size : longint;fillproc : tfillextrainfoproc;displayproc : tdisplayextrainfoproc);
begin
{ the total size must stay multiple of 8, also allocate 2 pointers for
the fill and display procvars }
exact_info_size:=size + sizeof(theap_extra_info);
extra_info_size:=((exact_info_size+7) div 8)*8;
fill_extra_info_proc:=fillproc;
display_extra_info_proc:=displayproc;
end;
{*****************************************************************************
Install MemoryManager
*****************************************************************************}
@ -941,6 +994,27 @@ const
HeapSize : TraceHeapsize;
);
procedure TraceInit;
begin
EntryMemUsed:=System.HeapSize-MemAvail;
MakeCRC32Tbl;
SetMemoryManager(TraceManager);
ptext:=@stderr;
{$ifdef EXTRA}
Assign(error_file,'heap.err');
Rewrite(error_file);
{$endif EXTRA}
{ checkpointer init }
{$ifdef go32v2}
Heap_at_init:=HeapPtr;
{$endif}
{$ifdef win32}
StartupHeapEnd:=HeapEnd;
{$endif}
end;
procedure TraceExit;
begin
{ no dump if error
@ -972,59 +1046,82 @@ begin
end;
end;
Procedure SetHeapTraceOutput(const name : string);
var i : longint;
begin
if ptext<>@stderr then
begin
ptext:=@stderr;
close(ownfile);
end;
assign(ownfile,name);
{$I-}
append(ownfile);
if IOResult<>0 then
Rewrite(ownfile);
{$I+}
ptext:=@ownfile;
for i:=0 to Paramcount do
write(ptext^,paramstr(i),' ');
writeln(ptext^);
Function GetEnv(P:string):Pchar;
{
Searches the environment for a string with name p and
returns a pchar to it's value.
A pchar is used to accomodate for strings of length > 255
}
var
ep : ppchar;
i : longint;
found : boolean;
Begin
p:=p+'='; {Else HOST will also find HOSTNAME, etc}
ep:=envp;
found:=false;
if ep<>nil then
begin
while (not found) and (ep^<>nil) do
begin
found:=true;
for i:=1 to length(p) do
if p[i]<>ep^[i-1] then
begin
found:=false;
break;
end;
if not found then
inc(ep);
end;
end;
if found then
getenv:=ep^+length(p)
else
getenv:=nil;
end;
procedure SetHeapExtraInfo( size : longint;fillproc : tfillextrainfoproc;displayproc : tdisplayextrainfoproc);
procedure LoadEnvironment;
var
i,j : longint;
s,hs : string;
begin
{ the total size must stay multiple of 8, also allocate 2 pointers for
the fill and display procvars }
exact_info_size:=size + sizeof(pointer)*2;
extra_info_size:=((exact_info_size+7) div 8)*8;
fill_extra_info_proc:=fillproc;
display_extra_info_proc:=displayproc;
s:=Getenv('HEAPTRC');
if pos('keepreleased',s)>0 then
keepreleased:=true;
if pos('disabled',s)>0 then
useheaptrace:=false;
if pos('nohalt',s)>0 then
haltonerror:=false;
i:=pos('log=',s);
if i>0 then
begin
hs:=copy(s,i+4,255);
j:=pos(' ',hs);
if j=0 then
j:=length(hs)+1;
delete(hs,j,255);
SetHeapTraceOutput(hs);
end;
end;
Initialization
EntryMemUsed:=System.HeapSize-MemAvail;
MakeCRC32Tbl;
SetMemoryManager(TraceManager);
ptext:=@stderr;
{$ifdef EXTRA}
Assign(error_file,'heap.err');
Rewrite(error_file);
{$endif EXTRA}
{ checkpointer init }
{$ifdef go32v2}
Heap_at_init:=HeapPtr;
{$endif}
{$ifdef win32}
StartupHeapEnd:=HeapEnd;
{$endif}
LoadEnvironment;
{ heaptrc can be disabled from the environment }
if useheaptrace then
TraceInit;
finalization
TraceExit;
if useheaptrace then
TraceExit;
end.
{
$Log$
Revision 1.8 2001-04-11 14:08:31 peter
Revision 1.9 2001-04-12 18:00:14 peter
* allow runtime setting using the environment HEAPTRC
Revision 1.8 2001/04/11 14:08:31 peter
* some small fixes to my previous commit
Revision 1.7 2001/04/11 12:34:50 peter