*/
Are you blogging on PH? Get your free blog.
*/

View \HDEBUG10.PAS

Turbo Pascal Heap Debugger With Many Features

Submitted By: WEBMASTER
Rating: (Not rated) (Rate It)


Unit HDebug10;

{$O-}    {  The routines Allocation and Deallocation are called through
            pointers to their addresses.  If you have to overlay, place
            these two procedures in a non-overlaid unit of their own.        }


{----------------------------------------------------------------------------}

interface

  uses
    CRT,       {  color constants   }
    Heap,      {  Heap Interceptor  }
    MapInfo;

  var
    HDMessage : String;       {  WATCH this variable for more information.   }

    {  Heap request interrupt handlers  }

{$F+}
  Procedure Allocating(Size : Word; BlockAddr,CallAddr : Pointer);
  Procedure Deallocating(Size : Word; BlockAddr,CallAddr : Pointer);
{$F-}

{----------------------------------------------------------------------------}

implementation

const
  VideoSegment = $B800;           {  $B000 for monochrome monitors.          }
  HeapGranularity = 8;            {  Turbo Pascal 6.0 heap granularity.      }

var
  HeapSize,                       {  Used to calculate the size of the heap  }
  HeapBottom,                     {  and the position of pointers within it. }
  HeapTop : LongInt;
  NumHeapPointers : Word;

  UserHeapCount,                  {  Counts heap variables created.          }
  Reference : Word;               {  Incremented with each heap interception.}

{----------------------------------------------------------------------------}

    {  Represent an integer as a string.  }

  Function IntStr(A : Integer) : String;
    var
      Temp : String;
    Begin
      Str(A,Temp);
      IntStr := Temp;
    End;

{----------------------------------------------------------------------------}

    {  Represent a pointer as a string.  }

Function PointerStr(P : Pointer) : String;
  Begin
    PointerStr := 'PTR('+HexPtrStr(P)+')';
  End;

{----------------------------------------------------------------------------}

    {  Convert a pointer to a longint.  }

Function Pointer_To_LongInt(P : Pointer) : LongInt;
  type
    PtrRec = record
      Lo,Hi : Word;
    end;
  Begin
    Pointer_To_LongInt := LongInt(PtrRec(P).Hi)*16+PtrRec(P).Lo;
  End;

{----------------------------------------------------------------------------}

    {  Display an urgent message on the screen or in the debugger.
       If a string begins with an '!', it will be displayed on the screen.   }


Procedure Message(S : String);
  const
    MessageAttr = Red*16+Yellow;          {  Attention getting, ugly colors. }
  var
    SaveLine : Array[1..255] of Word;     {  Used to restore the screen.     }
    VideoLine : Array[1..255] of Word absolute VideoSegment:0;
                                          {  First video line.               }
    i,L : Byte;
  Begin
    if (S[1] = '!') then                  {  If urgent, place on the screen. }
      begin
        L := Length(S);
        Move(VideoLine,SaveLine,L*SizeOf(Word));
        for i := 1 to L-1 do
          VideoLine[i] := MessageAttr*256+Byte(S[i+1]);
        ReadLn;
        Move(SaveLine,VideoLine,L*SizeOf(Word)){  Restore the screen.     }
      end
    else
      HDMessage := S;
  End;

{----------------------------------------------------------------------------}

    {  Map a pointer within the heap onto the heap map.  }

Function HeapPointer_Ordinate(P : Pointer) : LongInt;
  var
    HeapPointer : LongInt;
  Begin
    if (P = nil) then
      HeapPointer_Ordinate := 0
    else
      begin
        HeapPointer := Pointer_To_LongInt(P);
        if ((HeapPointer >= HeapBottom) and (HeapPointer <= HeapTop)) then
          HeapPointer_Ordinate := (HeapPointer div HeapGranularity)-
                                  (HeapBottom div HeapGranularity)+1
        else
          Message('!'+PointerStr(P)+' is not within the heap.');
      end;
  End;

{----------------------------------------------------------------------------}

Procedure Allocating(Size : Word; BlockAddr,CallAddr : Pointer);
  var
    OldReference : Word;
    Ordinate : LongInt;
    Allocate : Boolean;
  Begin
    Inc(UserHeapCount);
    Inc(Reference);
    if FatalHeapError and InterceptFatalHeapErrors then
      begin
        Message('!Allocation error detected.');
        Enter_Debugger(CallAddr);
        Message('!Found in unit '+UnitName+', line '+IntStr(CurrentLineNumber)+', address '+PointerStr(CallAddr));
      end;
  End;

{----------------------------------------------------------------------------}

Procedure Deallocating(Size : Word; BlockAddr,CallAddr : Pointer);
  var
    Ordinate : LongInt;
    Original_Size : Word;
    Deallocate : Boolean;

  Begin
    Dec(UserHeapCount);
    Inc(Reference);
    if FatalHeapError and InterceptFatalHeapErrors then
      begin
        Message('!Deallocation error detected.');
        Enter_Debugger(CallAddr);
        Message('!Found in unit '+UnitName+', line '+IntStr(CurrentLineNumber)+', address '+PointerStr(CallAddr));
      end;
  End;

{----------------------------------------------------------------------------}

BEGIN

    {  Assign procedures to each of the interrupt handlers.  }

  Allocation_Handler   := @Allocating;
  Deallocation_Handler := @Deallocating;

    {  Initialize  }

  UserHeapCount := 0;
  Reference     := 0;

    {  Get the dimensions of the heap as soon as possible.  }

  HeapBottom      := Pointer_To_LongInt(HeapOrg);
  HeapTop         := Pointer_To_LongInt(HeapEnd);
  HeapSize        := HeapTop-HeapBottom;
  NumHeapPointers := HeapSize div HeapGranularity;

  HDMessage := '';
END.

{----------------------------------------------------------------------------}

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.