Prechádzať zdrojové kódy

* extra info update so it can be always be set on/off

peter 24 rokov pred
rodič
commit
60ba93a688
1 zmenil súbory, kde vykonal 150 pridanie a 138 odobranie
  1. 150 138
      rtl/inc/heaptrc.pp

+ 150 - 138
rtl/inc/heaptrc.pp

@@ -14,13 +14,6 @@
 
  **********************************************************************}
 unit heaptrc;
-
-{ 0.99.12 had a bug that initialization/finalization only worked for
-  objfpc,delphi mode }
-{$ifdef VER0_99_12}
-  {$mode objfpc}
-{$endif}
-
 interface
 
 Procedure DumpHeap;
@@ -33,14 +26,15 @@ Procedure MarkHeap;
    WARNING this needs extremely much memory (PM) }
 
 type
-    FillExtraInfoType = procedure(p : pointer);
+   tFillExtraInfoProc = procedure(p : pointer);
+   tdisplayextrainfoProc = procedure (var ptext : text;p : pointer);
 
-    { allows to add several longint value that can help
-      to debug :
-      see for instance ppheap.pas unit of the compiler source PM }
+{ Allows to add info pre memory block, see ppheap.pas of the compiler
+  for example source }
+procedure SetHeapExtraInfo( size : longint;fillproc : tfillextrainfoproc;displayproc : tdisplayextrainfoproc);
 
-Procedure SetExtraInfo( size : longint;func : FillExtraInfoType);
-Procedure SetHeapTraceOutput(const name : string);
+{ Redirection of the output to a file }
+procedure SetHeapTraceOutput(const name : string);
 
 const
   { tracing level
@@ -57,11 +51,12 @@ const
     is freed several times }
 {$ifdef EXTRA}
   keepreleased : boolean=true;
-  add_tail : boolean = true;
 {$else EXTRA}
   keepreleased : boolean=false;
-  add_tail : boolean = false;
 {$endif EXTRA}
+  { add a small footprint at the end of memory blocks, this
+    can check for memory overwrites at the end of a block }
+  add_tail : boolean = true;
   { put crc in sig
     this allows to test for writing into that part }
   usecrc : boolean = true;
@@ -73,35 +68,46 @@ type
    plongint = ^longint;
 
 const
-  { allows to add custom info in heap_mem_info }
+  { allows to add custom info in heap_mem_info, this is the size that will
+    be allocated for this information }
   extra_info_size : longint = 0;
   exact_info_size : longint = 0;
   EntryMemUsed    : longint = 0;
   { function to fill this info up }
-  fill_extra_info : FillExtraInfoType = nil;
+  fill_extra_info_proc : TFillExtraInfoProc = nil;
+  display_extra_info_proc : TDisplayExtraInfoProc = nil;
   error_in_heap : boolean = false;
   inside_trace_getmem : boolean = false;
 
 type
-  pheap_mem_info = ^theap_mem_info;
+  pheap_extra_info = ^theap_extra_info;
+  theap_extra_info = record
+    fillproc : tfillextrainfoProc;
+    displayproc : tdisplayextrainfoProc;
+    data : record
+           end;
+  end;
+
   { warning the size of theap_mem_info
     must be a multiple of 8
     because otherwise you will get
     problems when releasing the usual memory part !!
     sizeof(theap_mem_info = 16+tracesize*4 so
     tracesize must be even !! PM }
+  pheap_mem_info = ^theap_mem_info;
   theap_mem_info = record
     previous,
     next     : pheap_mem_info;
     size     : longint;
-    sig      : longint;
+    sig      : longword;
 {$ifdef EXTRA}
-    release_sig : longint;
+    release_sig : longword;
     prev_valid  : pheap_mem_info;
 {$endif EXTRA}
     calls    : array [1..tracesize] of longint;
-    extra_info : record
-                 end;
+    exact_info_size : word;
+    extra_info_size : word;
+    extra_info      : pheap_extra_info;
   end;
 
 var
@@ -126,19 +132,11 @@ var
 *****************************************************************************}
 
 var
-{$ifdef Delphi}
   Crc32Tbl : array[0..255] of longword;
-{$else Delphi}
-  Crc32Tbl : array[0..255] of longint;
-{$endif Delphi}
 
 procedure MakeCRC32Tbl;
 var
-{$ifdef Delphi}
   crc : longword;
-{$else Delphi}
-  crc : longint;
-{$endif Delphi}
   i,n : byte;
 begin
   for i:=0 to 255 do
@@ -146,11 +144,7 @@ begin
      crc:=i;
      for n:=1 to 8 do
       if odd(crc) then
-{$ifdef Delphi}
        crc:=(crc shr 1) xor $edb88320
-{$else Delphi}
-       crc:=longint(cardinal(crc shr 1) xor $edb88320)
-{$endif Delphi}
       else
        crc:=crc shr 1;
      Crc32Tbl[i]:=crc;
@@ -158,13 +152,7 @@ begin
 end;
 
 
-{$ifopt R+}
-{$define Range_check_on}
-{$endif opt R+}
-
-{$R- needed here }
-
-Function UpdateCrc32(InitCrc:longint;var InBuf;InLen:Longint):longint;
+Function UpdateCrc32(InitCrc:longword;var InBuf;InLen:Longint):longword;
 var
   i : longint;
   p : pchar;
@@ -173,25 +161,25 @@ begin
   for i:=1 to InLen do
    begin
      InitCrc:=Crc32Tbl[byte(InitCrc) xor byte(p^)] xor (InitCrc shr 8);
-     inc(longint(p));
+     inc(p);
    end;
   UpdateCrc32:=InitCrc;
 end;
 
-Function calculate_sig(p : pheap_mem_info) : longint;
+Function calculate_sig(p : pheap_mem_info) : longword;
 var
-   crc : longint;
+   crc : longword;
    pl : plongint;
 begin
-   crc:=longint($ffffffff);
+   crc:=longword($ffffffff);
    crc:=UpdateCrc32(crc,p^.size,sizeof(longint));
    crc:=UpdateCrc32(crc,p^.calls,tracesize*sizeof(longint));
-   if extra_info_size>0 then
-     crc:=UpdateCrc32(crc,p^.extra_info,exact_info_size);
+   if p^.extra_info_size>0 then
+     crc:=UpdateCrc32(crc,p^.extra_info^,p^.exact_info_size);
    if add_tail then
      begin
         { Check also 4 bytes just after allocation !! }
-        pl:=pointer(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(longint));
      end;
    calculate_sig:=crc;
@@ -200,32 +188,28 @@ end;
 {$ifdef EXTRA}
 Function calculate_release_sig(p : pheap_mem_info) : longint;
 var
-   crc : longint;
+   crc : longword;
    pl : plongint;
 begin
-   crc:=longint($ffffffff);
+   crc:=$ffffffff;
    crc:=UpdateCrc32(crc,p^.size,sizeof(longint));
    crc:=UpdateCrc32(crc,p^.calls,tracesize*sizeof(longint));
-   if extra_info_size>0 then
-     crc:=UpdateCrc32(crc,p^.extra_info,exact_info_size);
+   if p^.extra_info_size>0 then
+     crc:=UpdateCrc32(crc,p^.extra_info^,p^.exact_info_size);
    { Check the whole of the whole allocation }
-   pl:=pointer(p)+extra_info_size+sizeof(theap_mem_info);
+   pl:=pointer(p)+p^.extra_info_size+sizeof(theap_mem_info);
    crc:=UpdateCrc32(crc,pl^,p^.size);
    { Check also 4 bytes just after allocation !! }
    if add_tail then
      begin
         { Check also 4 bytes just after allocation !! }
-        pl:=pointer(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(longint));
      end;
    calculate_release_sig:=crc;
 end;
 {$endif EXTRA}
 
-{$ifdef Range_check_on}
-{$R+}
-{$undef Range_check_on}
-{$endif Range_check_on}
 
 {*****************************************************************************
                                 Helpers
@@ -239,14 +223,14 @@ begin
   for i:=1 to tracesize do
    if pp^.calls[i]<>0 then
      writeln(ptext,BackTraceStrFunc(pp^.calls[i]));
-  for i:=0 to (exact_info_size div 4)-1 do
-    writeln(ptext,'info ',i,'=',plongint(pointer(@pp^.extra_info)+4*i)^);
+  if assigned(pp^.extra_info^.displayproc) then
+   pp^.extra_info^.displayproc(ptext,@pp^.extra_info^.data);
 end;
 
+
 procedure call_free_stack(pp : pheap_mem_info;var ptext : text);
 var
   i  : longint;
-
 begin
   writeln(ptext,'Call trace for block at 0x',hexstr(longint(pointer(pp)+sizeof(theap_mem_info)),8),' size ',pp^.size);
   for i:=1 to tracesize div 2 do
@@ -256,8 +240,8 @@ 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 (exact_info_size div 4)-1 do
-    writeln(ptext,'info ',i,'=',plongint(pointer(@pp^.extra_info)+4*i)^);
+  for i:=0 to (pp^.exact_info_size div 4)-1 do
+    writeln(ptext,'info ',i,'=',plongint(pointer(pp^.extra_info)+4*i)^);
 end;
 
 
@@ -272,8 +256,7 @@ end;
 procedure dump_error(p : pheap_mem_info;var ptext : text);
 begin
   Writeln(ptext,'Marked memory at 0x',HexStr(longint(pointer(p)+sizeof(theap_mem_info)),8),' invalid');
-  Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8)
-    ,' instead of ',hexstr(calculate_sig(p),8));
+  Writeln(ptext,'Wrong signature $',hexstr(p^.sig,8),' instead of ',hexstr(calculate_sig(p),8));
   dump_stack(ptext,get_caller_frame(get_frame));
 end;
 
@@ -283,11 +266,10 @@ procedure dump_change_after(p : pheap_mem_info;var ptext : text);
      i : longint;
 begin
   Writeln(ptext,'Marked memory at 0x',HexStr(longint(pointer(p)+sizeof(theap_mem_info)),8),' invalid');
-  Writeln(ptext,'Wrong release CRC $',hexstr(p^.release_sig,8)
-    ,' instead of ',hexstr(calculate_release_sig(p),8));
+  Writeln(ptext,'Wrong release CRC $',hexstr(p^.release_sig,8),' instead of ',hexstr(calculate_release_sig(p),8));
   Writeln(ptext,'This memory was changed after call to freemem !');
   call_free_stack(p,ptext);
-  pp:=pointer(p)+sizeof(theap_mem_info)+extra_info_size;
+  pp:=pointer(p)+sizeof(theap_mem_info);
   for i:=0 to p^.size-1 do
     if byte(pp[i])<>$F0 then
       Writeln(ptext,'offset',i,':$',hexstr(i,8),'"',pp[i],'"');
@@ -301,8 +283,8 @@ 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 (exact_info_size div 4)-1 do
-    writeln(ptext,'info ',i,'=',plongint(@p^.extra_info+4*i)^);
+  for i:=0 to (p^.exact_info_size div 4)-1 do
+    writeln(ptext,'info ',i,'=',plongint(p^.extra_info+4*i)^);
   call_stack(p,ptext);
 end;
 
@@ -317,9 +299,9 @@ begin
   i:=0;
   while pp<>nil do
    begin
-     if ((pp^.sig<>longint($DEADBEEF)) or usecrc) and
+     if ((pp^.sig<>$DEADBEEF) or usecrc) and
         ((pp^.sig<>calculate_sig(pp)) or not usecrc) and
-        (pp^.sig <> longint($AAAAAAAA)) then
+        (pp^.sig <>$AAAAAAAA) then
       begin
         writeln(ptext^,'error in linked list of heap_mem_info');
         RunError(204);
@@ -352,13 +334,31 @@ begin
     inc(bp,sizeof(longint));
   p:=SysGetMem(bp);
 { Create the info block }
-  pheap_mem_info(p)^.sig:=longint($DEADBEEF);
+  pheap_mem_info(p)^.sig:=$DEADBEEF;
   pheap_mem_info(p)^.size:=size;
+  pheap_mem_info(p)^.extra_info_size:=extra_info_size;
+  pheap_mem_info(p)^.exact_info_size:=exact_info_size;
+  {
+    the end of the block contains:
+    <tail>   4 bytes
+    <extra_info>   X bytes
+  }
+  pheap_mem_info(p)^.extra_info:=pointer(p)+bp-extra_info_size;
+  fillchar(pheap_mem_info(p)^.extra_info^,extra_info_size,0);
+  pheap_mem_info(p)^.extra_info^.fillproc:=fill_extra_info_proc;
+  pheap_mem_info(p)^.extra_info^.displayproc:=display_extra_info_proc;
+  if assigned(fill_extra_info_proc) then
+    begin
+      inside_trace_getmem:=true;
+      fill_extra_info_proc(@pheap_mem_info(p)^.extra_info^.data);
+      inside_trace_getmem:=false;
+    end;
   if add_tail then
     begin
-      pl:=pointer(p)+bp-sizeof(longint);
-      pl^:=longint($DEADBEEF);
+      pl:=pointer(p)+bp-extra_info_size-sizeof(longint);
+      pl^:=$DEADBEEF;
     end;
+  { retrieve backtrace info }
   bp:=get_caller_frame(get_frame);
   for i:=1 to tracesize do
    begin
@@ -381,16 +381,10 @@ begin
     because checkpointer can be called from within
     fill_extra_info PM }
   inc(getmem_cnt);
-  if assigned(fill_extra_info) then
-    begin
-      inside_trace_getmem:=true;
-      fill_extra_info(@pheap_mem_info(p)^.extra_info);
-      inside_trace_getmem:=false;
-    end;
 { update the pointer }
   if usecrc then
     pheap_mem_info(p)^.sig:=calculate_sig(pheap_mem_info(p));
-  inc(p,sizeof(theap_mem_info)+extra_info_size);
+  inc(p,sizeof(theap_mem_info));
   TraceGetmem:=p;
 end;
 
@@ -406,23 +400,25 @@ var
 {$ifdef EXTRA}
   pp2 : pheap_mem_info;
 {$endif}
+  extra_size : longint;
 begin
   inc(freemem_size,size);
   inc(freemem8_size,((size+7) div 8)*8);
-  ppsize:= size + sizeof(theap_mem_info)+extra_info_size;
-  if add_tail then
-    ppsize:=ppsize+sizeof(longint);
-  dec(p,sizeof(theap_mem_info)+extra_info_size);
+  dec(p,sizeof(theap_mem_info));
   pp:=pheap_mem_info(p);
+  extra_size:=pp^.extra_info_size;
+  ppsize:= size + sizeof(theap_mem_info)+pp^.extra_info_size;
+  if add_tail then
+    inc(ppsize,sizeof(longint));
   if not quicktrace and not(is_in_getmem_list(pp)) then
     RunError(204);
-  if (pp^.sig=longint($AAAAAAAA)) and not usecrc then
+  if (pp^.sig=$AAAAAAAA) and not usecrc then
     begin
        error_in_heap:=true;
        dump_already_free(pp,ptext^);
        if haltonerror then halt(1);
     end
-  else if ((pp^.sig<>longint($DEADBEEF)) or usecrc) and
+  else if ((pp^.sig<>$DEADBEEF) or usecrc) and
         ((pp^.sig<>calculate_sig(pp)) or not usecrc) then
     begin
        error_in_heap:=true;
@@ -446,7 +442,7 @@ begin
        exit;
     end;
   { now it is released !! }
-  pp^.sig:=longint($AAAAAAAA);
+  pp^.sig:=$AAAAAAAA;
   if not keepreleased then
     begin
        if pp^.next<>nil then
@@ -470,13 +466,11 @@ begin
   { this way we keep all info about all released memory !! }
   if keepreleased then
     begin
-{$ifndef EXTRA}
-       dec(ppsize,sizeof(theap_mem_info)+extra_info_size);
-       inc(p,sizeof(theap_mem_info)+extra_info_size);
-{$else EXTRA}
-      inc(p,sizeof(theap_mem_info)+extra_info_size);
-      fillchar(p^,size,#240); { $F0 will lead to GFP if used as pointer ! }
-      { We want to check if the memory was changed after release !! }
+       i:=ppsize;
+       inc(p,sizeof(theap_mem_info));
+       fillchar(p^,size,#240); { $F0 will lead to GFP if used as pointer ! }
+{$ifdef EXTRA}
+       { We want to check if the memory was changed after release !! }
        pp^.release_sig:=calculate_release_sig(pp);
        if pp=heap_valid_last then
          begin
@@ -498,11 +492,12 @@ begin
             else
               pp2:=pp2^.prev_valid;
          end;
-       exit;
 {$endif EXTRA}
-    end;
-  i:=SysFreeMemSize(p,ppsize);
-  dec(i,sizeof(theap_mem_info)+extra_info_size);
+       exit;
+    end
+  else
+    i:=SysFreeMemSize(p,ppsize);
+  dec(i,sizeof(theap_mem_info)+extra_size);
   if add_tail then
    dec(i,sizeof(longint));
   TraceFreeMemSize:=i;
@@ -512,9 +507,12 @@ end;
 function TraceMemSize(p:pointer):Longint;
 var
   l : longint;
+  pp : pheap_mem_info;
 begin
-  l:=SysMemSize(p-(sizeof(theap_mem_info)+extra_info_size));
-  dec(l,sizeof(theap_mem_info)+extra_info_size);
+  dec(p,sizeof(theap_mem_info));
+  pp:=pheap_mem_info(p);
+  l:=SysMemSize(pp);
+  dec(l,sizeof(theap_mem_info)+pp^.extra_info_size);
   if add_tail then
    dec(l,sizeof(longint));
   TraceMemSize:=l;
@@ -526,7 +524,7 @@ var
   size : longint;
   pp : pheap_mem_info;
 begin
-  pp:=pheap_mem_info(pointer(p)-(sizeof(theap_mem_info)+extra_info_size));
+  pp:=pheap_mem_info(p-sizeof(theap_mem_info));
   size:=TraceMemSize(p);
   { this can never happend normaly }
   if pp^.size>size then
@@ -551,6 +549,10 @@ var
   i,bp : longint;
   pl : plongint;
   pp : pheap_mem_info;
+  oldextrasize,
+  oldexactsize : longint;
+  old_fill_extra_info_proc : tfillextrainfoproc;
+  old_display_extra_info_proc : tdisplayextrainfoproc;
 begin
 { Free block? }
   if size=0 then
@@ -568,10 +570,10 @@ begin
      exit;
    end;
 { Resize block }
-  dec(p,sizeof(theap_mem_info)+extra_info_size);
+  dec(p,sizeof(theap_mem_info));
   pp:=pheap_mem_info(p);
   { test block }
-  if ((pp^.sig<>longint($DEADBEEF)) or usecrc) and
+  if ((pp^.sig<>$DEADBEEF) or usecrc) and
      ((pp^.sig<>calculate_sig(pp)) or not usecrc) then
    begin
      error_in_heap:=true;
@@ -583,15 +585,21 @@ begin
      if haltonerror then halt(1);
      exit;
    end;
+  { save info }
+  oldextrasize:=pp^.extra_info_size;
+  oldexactsize:=pp^.exact_info_size;
+  old_fill_extra_info_proc:=pp^.extra_info^.fillproc;
+  old_display_extra_info_proc:=pp^.extra_info^.displayproc;
   { Do the real ReAllocMem, but alloc also for the info block }
-  bp:=size+sizeof(theap_mem_info)+extra_info_size;
+  bp:=size+sizeof(theap_mem_info)+pp^.extra_info_size;
   if add_tail then
    inc(bp,sizeof(longint));
-  { the internal ReAllocMem is not allowed to move any data }
+  { Try to resize the block, if not possible we need to do a
+    getmem, move data, freemem }
   if not SysTryResizeMem(p,bp) then
    begin
      { restore p }
-     inc(p,sizeof(theap_mem_info)+extra_info_size);
+     inc(p,sizeof(theap_mem_info));
      { get a new block }
      oldsize:=TraceMemSize(p);
      newP := TraceGetMem(size);
@@ -612,21 +620,28 @@ begin
   inc(getmem_size,size);
   inc(getmem8_size,((size+7) div 8)*8);
 { Create the info block }
-  pp^.sig:=longint($DEADBEEF);
+  pp^.sig:=$DEADBEEF;
   pp^.size:=size;
-  if add_tail then
-    begin
-      pl:=pointer(p)+bp-sizeof(longint);
-      pl^:=longint($DEADBEEF);
-    end;
+  pp^.extra_info_size:=oldextrasize;
+  pp^.exact_info_size:=oldexactsize;
   bp:=get_caller_frame(get_frame);
   for i:=1 to tracesize do
    begin
      pp^.calls[i]:=get_caller_addr(bp);
      bp:=get_caller_frame(bp);
    end;
-  if assigned(fill_extra_info) then
-    fill_extra_info(@pp^.extra_info);
+  { add the new extra_info and tail }
+  pp^.extra_info:=p+bp-pp^.extra_info_size;
+  fillchar(pp^.extra_info^,extra_info_size,0);
+  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);
+  if add_tail then
+    begin
+      pl:=pointer(p)+bp-pp^.extra_info_size-sizeof(longint);
+      pl^:=$DEADBEEF;
+    end;
 { update the pointer }
   if usecrc then
     pp^.sig:=calculate_sig(pp);
@@ -727,10 +742,10 @@ begin
         (cardinal(p)<=cardinal(pp)+sizeof(theap_mem_info)+extra_info_size+pp^.size) then
        begin
           { check allocated block }
-          if ((pp^.sig=longint($DEADBEEF)) and not usecrc) or
+          if ((pp^.sig=$DEADBEEF) and not usecrc) or
              ((pp^.sig=calculate_sig(pp)) and usecrc) or
           { special case of the fill_extra_info call }
-             ((pp=heap_valid_last) and usecrc and (pp^.sig=longint($DEADBEEF))
+             ((pp=heap_valid_last) and usecrc and (pp^.sig=$DEADBEEF)
               and inside_trace_getmem) then
             goto _exit
           else
@@ -758,7 +773,7 @@ begin
      if (cardinal(p)>=cardinal(pp)+sizeof(theap_mem_info)+cardinal(extra_info_size)) and
         (cardinal(p)<=cardinal(pp)+sizeof(theap_mem_info)+cardinal(extra_info_size)+cardinal(pp^.size)) then
         { allocated block }
-       if ((pp^.sig=longint($DEADBEEF)) and not usecrc) or
+       if ((pp^.sig=$DEADBEEF) and not usecrc) or
           ((pp^.sig=calculate_sig(pp)) and usecrc) then
           goto _exit
        else
@@ -817,7 +832,7 @@ begin
           Writeln(ptext^,'More memory blocks than expected');
           exit;
        end;
-     if ((pp^.sig=longint($DEADBEEF)) and not usecrc) or
+     if ((pp^.sig=$DEADBEEF) and not usecrc) or
         ((pp^.sig=calculate_sig(pp)) and usecrc) then
        begin
           { this one was not released !! }
@@ -825,7 +840,7 @@ begin
             call_stack(pp,ptext^);
           dec(i);
        end
-     else if pp^.sig<>longint($AAAAAAAA) then
+     else if pp^.sig<>$AAAAAAAA then
        begin
           dump_error(pp,ptext^);
 {$ifdef EXTRA}
@@ -854,7 +869,7 @@ begin
   pp:=heap_mem_root;
   while pp<>nil do
    begin
-     pp^.sig:=longint($AAAAAAAA);
+     pp^.sig:=$AAAAAAAA;
      pp:=pp^.previous;
    end;
 end;
@@ -958,22 +973,16 @@ begin
    writeln(ptext^);
 end;
 
-procedure SetExtraInfo( size : longint;func : fillextrainfotype);
+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(pointer)*2;
+  extra_info_size:=((exact_info_size+7) div 8)*8;
+  fill_extra_info_proc:=fillproc;
+  display_extra_info_proc:=displayproc;
+end;
 
-  begin
-     if getmem_cnt>0 then
-       begin
-         writeln(ptext^,'Setting extra info is only possible at start !! ');
-         dumpheap;
-       end
-     else
-       begin
-          { the total size must stay multiple of 8 !! }
-          exact_info_size:=size;
-          extra_info_size:=((size+7) div 8)*8;
-          fill_extra_info:=func;
-       end;
-  end;
 
 Initialization
   EntryMemUsed:=System.HeapSize-MemAvail;
@@ -996,7 +1005,10 @@ finalization
 end.
 {
   $Log$
-  Revision 1.6  2000-12-16 15:57:17  jonas
+  Revision 1.7  2001-04-11 12:34:50  peter
+    * extra info update so it can be always be set on/off
+
+  Revision 1.6  2000/12/16 15:57:17  jonas
     * removed 64bit evaluations when range checking is on
 
   Revision 1.5  2000/12/07 17:19:47  jonas