Written some cool source code? Upload it to Programmer's Heaven.

View \LIESMICH.TXT

The Heap Debugger V2.0 TP/BP 7.0

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


Der

                              HEAP DEBUGGER V2.0

                                     f?r
                             BORLAND PASCAL V7.0
                           (DOS, DOS/DPMI, WINDOWS)


                                Copyright 1995
                                      by

                                   AIT GmbH
                         Alte Gasse 12 - 86152 Augsburg
                                    Germany

                            Tel. +49 (821) 514868
                            Fax: +49 (821) 514831

                  FIDO-Net: Karsten Strobel @ 2:2480/300.7
                  Internet: [[Email Removed]]
 





                                        INHALT


      EINF?HRUNG

      Der Sinn des Heap Debuggers .........................................  3
      Was der Heap Debugger kann ..........................................  3
      Was der Heap Debugger NICHT kann ....................................  3
      Der Umgang mit dynamischem Speicher .................................  3
      Versionen und Zielplattformen .......................................  4
      Liste der Dateien ...................................................  5
      Sharewarekonzept ....................................................  5
      Lizenzbedingungen ...................................................  5
      Nutzungsempfehlungen und Haftungsausschl?sse ........................  6

      ANWENDUNG DES HEAP DEBUGGERS

      Den Heap Debugger einbinden .........................................  6
      Compiler- und Linkereinstellungen ...................................  7
      Wenn die Initialisierung fehlschl?gt ................................  7
      Der Heap Debugger Report ............................................  8
      Besondere Meldungen im Heap Debugger Report .........................  9
      Interpretation des Reports .......................................... 10
      Auffinden von Bugs .................................................. 11
      Arbeiten mit einem externen Debugger ................................ 11
      Compilerschalter in USEHDEB ......................................... 12


      HEAP DEBUGGING IM DETAIL

      Overlays ............................................................ 13
      DLLs ................................................................ 13
      Programminstanzen (Windows) ......................................... 14
      Interrupts .......................................................... 14
      Stabilit?t und Performance .......................................... 14
      Eingriffsm?glichkeiten f?r den Programmierer ........................ 15


      BEKANNTE EINSCHR?NKUNGEN UND PROBLEME

      Mark/Release ........................................................ 16
      MemAllocSeg ......................................................... 17
      BGI ................................................................. 18
      TMemoryStream ....................................................... 18
      Heap?berlauf ........................................................ 18
      Programmabbruch ..................................................... 19
      WINCRT .............................................................. 19
 
      Seite 3


      EINF?HRUNG _____________________________________________________________

      ___ Der Sinn des Heap Debuggers ________________________________________

      Der Heap Debugger ?berwacht (fast) alle vom Programm vorgenommenen Heap-
      Operationen und f?hrt unter anderem eine Liste ?ber alle nicht freigege-
      benen Heapspeicherbereiche. Der Programmierer, der den Heap Debugger
      w?hrend der Entwicklungsphase in sein Programm einbindet, wird nach je-
      dem Programmabschlu? auf ?briggebliebene Speicherbl?cke hingewiesen.

      Der Heap Debugger macht das Auffinden der Fehlerquellen extrem einfach,
      weil er (meistens) einen Hinweis auf die Sourcecodestelle (Dateiname und
      Zeile) liefert, an der die inkorrekte Heap-Operation vorgenommen wurde
      bzw. an der ein sp?ter nicht wieder freigegebener Speicherblock allo-
      ziert wurde.

      Hierzu bedient sich der Heap Debugger der Debug-Informationen f?r den
      externen Debugger, die (optional) an das vom Compiler erzeugte EXE-File
      angeh?ngt werden.


      ___ Was der Heap Debugger kann _________________________________________

      Der Heap Debugger ?berwacht alle Allokationen von Heapspeicher, die mit
      den Befehlen

         - GetMem
         - New
         - FreeMem
         - Dispose

      vorgenommen werden. Auch Aufrufe dieser Routinen aus der Run-Time-
      Library und aus Programmteilen heraus, die nicht im Sourcecode vorliegen
      (z.B. fremde TPUs), werden ber?cksichtigt.

      Alle nicht korrekt deallokierten Heapspeicherbl?cke und sonstige fehler-
      hafte Heap-Operationen werden im Heap Debugger Report ausgegeben.


      ___ Was der Heap Debugger NICHT kann ___________________________________

      Folgende Heap-Operationen k?nnen vom Heap Debugger NICHT mitverfolgt
      werden:

         - Mark und Release (d?rfen gar nicht verwendet werden !)

         - direkte Operationen mit dem globalen Heap (DPMI+Windows),
           also alle "Global..."-Aufrufe

         - direkte Operationen mit dem lokalen Heap (Windows),
           also alle "Local..."-Aufrufe


      ___ Der Umgang mit dynamischem Speicher ________________________________

      In Programme, die intensiv mit Heapspeicher umgehen, schleichen sich
      nicht selten heimt?ckische Programmierfehler ein: Wenn n?mlich dynamisch
      angeforderte Speicherbereiche nicht korrekt wieder freigegeben werden,
      schrumpft der noch verf?gbare Heapspeicher nach und nach so weit zu-
 
      Seite 4


      sammen, da? irgendwann f?r eine neue Anforderung nicht mehr gen?gend
      Platz zur Verf?gung steht und das Programm abbricht oder -st?rzt.

      Zum v?lligen Aufzehren des Heapspeichers kommt es nat?rlich nur, wenn
      Allokationen ohne entsprechende Deallokationen nicht nur einmal, sondern
      wiederholt durchgef?hrt werden. Wenn dieses z.B. mit der Anwahl einer
      bestimmten Programmfunktion durch den Benutzer verbunden ist, dann kann
      dies vielleicht einige hundert Male gut gehen, bis der ?brige Heapspei-
      cher aufgebraucht ist. So intensiv werden aber Programme nur selten vom
      Programmierer getestet. Also kommen so bedingte Abst?rze in der Regel
      erst beim Benutzer vor, der daf?r nat?rlich keine Erkl?rung hat.

      Es gibt auch Allokationen, die nur einmalig, also zum Beispiel in der
      Initialisierungsphase vorgenommen werden, weil das Programm Speicher-
      platz f?r quasi-statische Variablen ben?tigt. Solche Variablen (bzw.
      Strukturen oder Objekte) k?nnte der Pogrammierer auch im Datensegment
      (als globale Variablen) allokierten, aber da die Gr??e des Datensegmen-
      tes auf insgesamt 64KB beschr?nkt ist, wird manchmal der Heap als Aus-
      weg gew?hlt. Wenn solche (nur einmalig allokierten) quasi-statischen
      Variablen nicht wieder freigegeben werden, so ist dies nur ein Sch?n-
      heitsfehler, hat aber sonst keine Konsequenzen. Der Heap Debugger be-
      m?ngelt aber nat?rlich auch solche Delikte.

      Besonders t?ckisch sind Deallokationsfehler, d.h. fehlerhafte Freigaben
      von Heapspeicher. Ein Deallokationsfehler liegt vor, wenn bei der
      Freigabe von Heapspeicher eine falsche Adresse oder eine falsche L?nge
      angegeben wird, also zu der unternommenen Deallokation zuvor keine pas-
      sende Allokation erfolgt ist. Da sich die Runtime-Library weitgehend auf
      die Angaben des Programmierers verl??t, k?nnen Deallokationsfehler ver-
      heerende Folgen haben.

      Besonders die Objektorientierte Programmierung macht intensiv von Heap-
      speicher Gebrauch. Zu jeder neuen Instanz eines Objektes wird ein Heap-
      speicherblock f?r die Felder des Objektes angefordert, der beim L?schen
      der Instanz wieder freigegeben werden mu?. Hierzu bedient man sich der
      Befehle New und Dispose in der speziell f?r OOP-Zwecke erweiterten
      Syntax. Auch "vergessene" Objekte konsumieren Heapspeicher.


      ___ Versionen und Zielplattformen ______________________________________

      Der Heap Debugger wurde entwickelt und getestet mit

                  Borland Pascal V7.0 und V7.01

                  mit den Zielsystemen
                  - Real Mode (hierf?r HDEB7?.TPU)
                  - Protected Mode (hierf?r HDEB7?.TPP)
                  - Windows (hierf?r HDEB7?.TPW)

                  unter
                  - DOS 6.2x
                  - Windows V3.1
                  - Windows for Workgroups V3.11
                  - Windows NT 3.5 Workstation
                  - OS/2 V2.11

      Eine Version f?r Delphi V1.0 f?r Windows ist in Vorbereitung.
 
      Seite 5


      ___ Liste der Dateien __________________________________________________

      USEHDEB.PAS .... Unit zum Einbinden in Pascalprogramme, f?r
                       DOS, DOS/DPMI und WINDOWS
      HDEB7S.TPU ..... Der Kern des Heap Debuggers, nur bei
                       Sharewareversionen, f?r DOS/Real Mode
      HDEB7S.TPP ..... Der Kern des Heap Debuggers, nur bei
                       Sharewareversionen, f?r DOS/Protected Mode
      HDEB7S.TPW ..... Der Kern des Heap Debuggers, nur bei
                       Sharewareversionen, f?r Windows
      HDEB7F.TPU ..... Der Kern des Heap Debuggers, nur bei
                       Vollversionen f?r DOS/Real Mode
      HDEB7F.TPP ..... Der Kern des Heap Debuggers, nur bei
                       Vollversionen f?r DOS/Protected Mode
      HDEB7F.TPW ..... Der Kern des Heap Debuggers, nur bei
                       Vollversionen f?r Windows
      VIEWME.EXE ..... Der Heap Debugger in Bildern (VGA)
      README.TXT ..... Dieser Text (englisch)
      LIESMICH.TXT ... Dieser Text (deutsch)
      DIZFILES.ZIP ... F?r Sysops, nur in Sharewareversionen
      SHARWARE.ZIP ... Diese Datei ist nur in Vollversionen
                       enthalten und enth?lt die Sharewareversion
      BESTELL.TXT .... Bestellformular (deutsch)
      ORDER.TXT ...... Bestellformular (englisch)


      ___ Sharewarekonzept ___________________________________________________

      Der Heap Debugger ist Shareware, also KEINE Public Domain oder Freeware!

      Die ?ber Sharewarevertriebswege verbeitete Version des Heap Debuggers in
      den Dateien HDEB7S.* ("S"=Shareware) und die Begleitdateien und die
      Datei USEHDEB.PAS d?rfen zu Testzwecken genutzt und an andere weiterge-
      geben werden.

      Die Sharewareversion ist gegen?ber der Vollversion im Leistungsumfang
      beschr?nkt: Die Sharewareversion des Heap Debuggers verfolgt nur die
      ersten 50 Allokationen von Heapspeicherbl?cken. Alle folgenden Allo-
      kationen werden ignoriert. Bei ?berschreitung des Sharewarelimits wird
      bei Ausgabe des Reports (bei Programmende) eine entsprechende Meldung
      ausgegeben.

      Registrierte Vollversionen des Heap Debuggers beinhalten die Dateien
      HDEB7F.* ("F"=Full). Diese Dateien d?rfen NICHT an Dritte weitergegeben
      oder ihnen zug?nglich gemacht werden.


      ___ Lizenzbedingungen __________________________________________________

      Wer den Heap Debugger in der unbeschr?nkten Vollversion nutzen m?chte,
      mu? eine Registrierung bei den Autoren vornehmen und erh?lt im Zuge der
      Lieferung der Vollversion eine Lizenz zur Nutzung der Vollversion auf
      einem einzelnen Arbeitsplatz.

      Bei Nutzung des Heap Debuggers auf mehreren Arbeitspl?tzen m?ssen auch
      mehrere Registrierungen bestellt werden. Hierf?r bieten wir Staffel-
      preise an.
 
      Seite 6


      Ein Registrierungsformular ist in der Datei BESTELL.TXT vorbereitet.

      Es ist ausdr?cklich untersagt, die Vollversion des Heap Debuggers
      weiterzugeben. Dies betrifft insbesondere die Dateien HDEB7F.*


      ___ Nutzungsempfehlungen und Haftungsausschl?sse _______________________

      Obwohl wir den Heap Debugger vor der Ver?ffentlichung ausf?hrlich getes-
      tet haben, k?nnen wir keine Garantie f?r einwandfreie Funktion oder Feh-
      lerfreiheit dieser Software ?bernehmen.

      Wir empfehlen die Nutzung des Heap Debuggers w?hrend der Entwicklungs-
      phase. Nach Fertigstellung eines Softwareprodukts sollte unserer Meinung
      nach der Heap Debugger nicht mehr eingebunden werden.

      Der Heap Debugger soll Ihnen bei der Softwareentwicklung helfen, Fehler
      bei der Speicherverwaltung zu vermeiden oder zu beseitigen. Wir weisen
      aber auch auf die zus?tzlichen Gefahren f?r die Stabilit?t einer Soft-
      ware, die den Heap Debugger einbindet, hin. N?heres hierzu siehe Ab-
      schnitt "Stabilit?t und Performance".

      Bei Lieferungen dieser Software erstreckt sich unsere Garantie aus-
      schlie?lich auf die Lesbarkeit des gelieferten Datentr?gers. Wir ?ber-
      nehmen keinerlei Haftung f?r Sch?den, die durch Benutzung des Heap
      Debuggers eventuell entstehen werden.


      ANWENDUNG DES HEAP DEBUGGERS ___________________________________________

      ___ Den Heap Debugger einbinden ________________________________________

      Um den Heap Debugger in ein eigenes Programm einzubinden, m?ssen Sie nur
      die Unit UseHDeb in die Uses-Klausel Ihres Hauptprogramms aufnehmen.
      Beispiel:

            PROGRAM MyProg;

               UseHDeb,
                \  /
                 \/
            USES   Drivers, Objects, Views, Menus, ...

      Es ist sinnvoll, die Unit UseHDeb als erste Unit in der Uses-Klausel
      aufzuf?hren. Die Initialisierung des Heap Debuggers erfolgt ?ber den
      Initialisierungsteil dieser Unit. Erst nach der Initialisierung kann der
      Heap Debugger Heap-Operationen "beobachten". Deshalb sollte die Initia-
      lisierung von UseHDeb m?glichst vor der Initialisierung anderer Units,
      die eventuell schon Heap-Operationen machen, vorgenommen werden.

      Keine der Units, von denen die Units UseHDeb und HDeb7? ihrerseits di-
      rekt oder indirekt Gebrauch machen, nimmt in der Initialisierungsphase
      Heap-Allokationen vor. Der Heap Debugger erh?lt also von allen Heap-
      Operationen Kenntnis, sofern keine der vom Heap Debugger genutzten Units
      modifiziert worden sind.
 
      Seite 7


      ___ Compiler- und Linkereinstellungen __________________________________

      "D+":

      Der Heap Debugger wird nur initialisiert, wenn die Unit UseHDeb mit der
      Compileroption "D+" (Debug-Informationen ein) ?bersetzt wird. Das liegt
      daran, da? fast die gesamte Unit UseHDeb mit Hilfe der Klausel
      {$IFOPT D+}...{$ENDIF} von der Compilierung ausgeschlossen ist, wenn die
      Option D+ nicht eingeschaltet ist. Dieser Schalter kann also zum Ein-
      und Ausschalten des Heap Debuggers verwendet werden. Theoretisch k?nnte
      der Heap Debugger allerdings auch ohne eingeschaltetes D+ laufen.

      F?r alle anderen Units, die in Ihr Programm eingebunden werden, sowie
      f?r das Hauptprogramm gilt: Nur wenn mit der Option D+ ?bersetzt wird,
      kann der Heap Debugger in seinem Report Referenzen auf diese Quellda-
      teien und Zeilennummern angeben.

      "Link-Puffer: Festplatte" und "Externer Debugger":

      Damit der Heap Debugger im Report Referenzen auf Quelldateien und Zei-
      lennummern liefern kann, m?ssen die dazu notwendigen Debug-Informa-
      tionen in das vom Compiler erzeugte EXE-File (bzw. DLL) geschrieben wer-
      den. Neben der Compileroption D+ werden dazu au?erdem die Einstellungen
      "Link-Puffer: Festplatte" und "Externer Debugger" ben?tigt. Unter Win-
      dows hei?t die letzte Option "Debug-Info in EXE".

      "Unit-Verzeichnis: \BP\RTL\WIN" (DOS/DPMI und Windows):

      Die Unit UseHDeb ben?tigt im Protected Mode (DOS+Windows) die Unit
      WINPROCS. Diese befindet sich gew?hnlich im Verzeichnis "\BP\RTL\WIN".
      Da unter DOS dieses Verzeichnis normalerweise nicht als Unit-Verzeichnis
      (siehe Option-->Verzeichnisse) eingestellt ist, m?ssen Sie dieses Ver-
      zeichnis selbst in der Liste der Unit-Verzeichnisse erg?nzen.


      ___ Wenn die Initialisierung fehlschl?gt _______________________________

      Die Initialisierung des Heap Debuggers wird von dem Initialisierungteil
      der Unit UseHDeb vorgenommen. Bei Fehlschlagen der Initialisierung gibt
      UseHDeb die Meldung "Heap Debugger konnte nicht initialisiert werden !"
      aus und stoppt das Programm mit dem Kommando HALT.

      Das Fehlschlagen der Initialisierung kann folgende Ursachen haben:

        - Sie verwenden eine modifizierte Run-Time-Library, die in
          einem f?r den Heap Debugger wichtigen Punkt nicht mit dem
          Original von Borland ?bereinstimmt.
        - Sie verwenden ein von uns nicht getestetes Betriebssystem
          oder spezielle, von uns nicht getestete Tools (z.B. zur
          Speicherverwaltung).
        - Sie verwenden eine von uns nicht getestete Compilerversion.
        - Es wurden keine freien Interruptvektoren gefunden. Der
          Heap Debugger ben?tigt drei freie Interrupts. In diesem
          Falle ist wahrscheinlich unsere Testmethode zum Finden
          freier Interrupts verantwortlich. Es kommt selten vor,
          da? tats?chlich alle Interrupts belegt sind.
        - Der Heap Debugger ist schon initilisiert. Dies sollte bei
          Verwendung der Unit UseHDeb nicht vorkommen.
 
      Seite 8



      Wenn bei Ihrem System die Initialisierung des Heap Debuggers fehlschla-
      gen sollte, dann versuchen Sie bitte zun?chst, Ihr Programm in einer von
      uns getesteten Konfiguration (z.B. MSDOS 6.2, ggf. Windows 3.1) ohne
      vorheriges Laden irgendwelcher spezieller Speichermanager oder Multi-
      tasker zu laden. Beobachten Sie, ob der Heap Debugger in dieser Konfi-
      guration initialisiert werden kann.

      Bitte informieren Sie uns ?ber Konfigurationen, in denen der Heap
      Debugger nicht betrieben werden kann (m?glichst per email).

      ___ Der Heap Debugger Report ___________________________________________

      Der Heap Debugger gibt beim Beenden des untersuchten Programms einen Re-
      port aus. Dies geschieht in der Exit-Prozedur der Unit UseHDeb.

      Der Heap Debugger Report hat in der Regel folgenden Aufbau (Beispiel):

        HEAP DEBUGGER DIAGNOSE:
        2 Pointer wurden registiert (*1)
        1 Debug-Eintraege vorhanden (*2)
        auflisten (J/N) ? j

        (*3)  (*4)      (*5)  (*6)           (*7)       |------(*8)------|
        Nr    Pointer   Size  Flags          Aufrufer         Datei  Zeile
         2  1A41:0000    256          0000[122D]:0044   HEAPBUG.PAS     16


      (*1): Hier wird angegeben, wieviele Heap-Allokationen der Heap Debugger
            insgesamt mitverfolgt hat. Diese Zahl enth?lt also noch keine
            Aussage ?ber eventuelle Fehler.
      (*2): Hier wird angegeben, wieviele Diagnosezeilen der Heap Debugger
            auszugeben hat. Im Idealfall sollte hier immer "0" stehen. Nicht
            alle, aber die meisten Diagnosezeilen deuten auf einen Program-
            mierfehler hin.
      (*3): Hier wird eine laufende Nummer aller vom Programm vorgenommener
            Allokationen ausgegeben. Bei Deallokationen (Flag "F") steht hier
            nichts.
      (*4): Hier wird die Adresse des allokierten bzw. deallokierten
            Heapspeicherblocks ausgegeben. Diese Adresse kann von Programmlauf
            zu Programmlauf variieren.
      (*5): Hier wird die Gr??e des allokierten bzw. deallokieren Blocks
            ausgegeben.
      (*6): Die hier ausgegebenen Flags haben folgende Bedeutung
            (Kombinationen sind m?glich):

            keins: Es handelt sich um eine Allokation, zu der keine passende
                   Deallokation erfolgt ist.
            "O"  : Es handelt sich um die Daten einer Objektinstanz. Das ist
                   der Datenbereich, der vom Constructor eines Objektes
                   f?r die Felder des Objektes (und anderes) bei jeder neuen
                   Instanz angelegt wird. Als Aufrufer wird die Zeile mit
                   dem Word "BEGIN" des Construktors angegeben, bzw. die Zeile
                   mit dem Word "END" des Destructors bei Deallokationen.
            "F"  : Bei dieser Diagnosezeile geht es um eine Deallokation
                   (F=free). Was bei dieser Deallokation schiefgegangen ist,
                   wird mit einem der folgenden Flags angegeben.
 
      Seite 9


            "S"  : Ein Heapspeicherblock wurde nicht mit der gleichen Block-
                   l?nge (S=size) deallokiert, mit der er allokiert wurde. In
                   diesem Falle wird dieses Flag sowohl in der Diagnosezeile
                   der Allokation als auch in der der Deallokation ausgegeben.
            "M"  : Zu einer Deallokation wurde keine passende Allokation
                   gefunden (M=mismatch). Das hei?t, da? versucht wurde, einen
                   Heapspeicherblock zu deallokieren, dessen Adresse nicht bei
                   einer vorangegangenen Allokation registriert worden ist.
                   Dieses Flag tritt nur zusammen mit dem Flag "F" auf.

      (*7): Hier wird die Adresse der aufrufenden Programmstelle ausgegeben.
            An dieser Programmstelle wurde die in der Diagnosezeile angegebene
            Heap-Operation aufgerufen. Die Segmentadresse dieser Stelle ist
            sowohl als virtuelle Segmentadresse (in eckigen Klammern "[]")
            als auch aktuelle Segmentadresse angegeben. Die virtuelle Segment-
            adresse wird vom Linker vergeben und ist die Adresse relativ zur
            Adresse 0000. Die aktuelle Adresse wird beim Laden des Programms
            vergeben und ist abh?ngig von der Stelle, an die das Programm in
            den Speicher geladen wird. Die virtuelle Adresse findet sich im
            MAP-File des Programms wieder. Die aktuelle Adresse kann von Pro-
            grammlauf zu Programmlauf variieren.
      (*8): Hier wird die Sourcecodestelle (Dateiname und Zeilennummer) ange-
            geben, die sich die Aufrufer-Adresse bezieht. Voraussetzung daf?r
            ist, da? ?berhaupt Debug-Informationen im EXE-File existieren.
            Sind keine Debug-Informationen vorhanden, dann wird hier
            "keine Info." angezeigt. Wenn zwar Debug-Informationen vorhanden
            sind, aber die Sourcecodestelle zu der Aufrufer-Adresse trotzdem
            nicht gefunden werden konnte, dann wird hier "?" angezeigt.


      ___ Besondere Meldungen im Heap Debugger Report ________________________

      Folgende Meldungen k?nnen im Heap Debugger Report in Ausnahmef?llen auf-
      treten:

      "Programm durch HALT(nnn) gestoppt"

      Diese Meldung erscheint, wenn das Programm gezielt mit dem Befehl
      HALT(nnn) gestoppt wurde. Der Exitcode wird mit nnn angegeben.

      "Laufzeitfehler nnn bei ssss:oooo, Datei: ________ Zeile: _____"

      Wenn das Programm durch einen Laufzeitfehler abgebrochen wird, erscheint
      diese Meldung. Als zus?tzliche, n?tzliche Information wird die
      Programmstelle des Laufzeitfehlers (Quelldateiname und Zeilennummer)
      ausgegeben, sofern diese Information verf?gbar ist.

      "interner Fehler 203 im Heap Debugger aufgetreten"

      Diese Meldung bedeutet, da? dem Heap Debugger zur Laufzeit nicht gen?-
      gend Heapspeicher zur Verf?gung stand, um alle Heap-Operationen auf-
      zeichnen zu k?nnen.

      "Shareware-Limit ueberschritten!
       Es wurden nur 50 pointer verarbeitet!"

      Diese Meldung wird nur von der Sharewareversion ausgegeben und besagt,
      da? das Sharewarelimit von 50 ?berwachten Allokationen zur Laufzeit
      ?berschritten worden ist.
 
      Seite 10


      ___ Interpretation des Reports _________________________________________

      Nat?rlich sollte man immer anstreben, am Ende eines Programmlaufs vom
      Heap Debugger die Meldung "0 Debug-Eintraege vorhanden" gemacht zu
      bekommen. Wenn der Heap Debugger w?hrend der gesamten Entwicklungszeit
      einer Applikation kontinuierlich eingesetzt wird, dann l??t sich eine
      nach einem Testlauf pl?tzlich auftauchende andere Meldung meist sehr
      leicht mit der zuletzt vorgenommenen Programm?nderung in Zusammenhang
      bringen.

      Wenn die Sache einmal nicht so einfach ist, mu? man die Diagnose des
      Heap Debuggers zun?chst einmal interpretieren, um dem Problem auf die
      Schliche zu kommen.

      Hierzu sollte man sich die folgenden Fragen stellen:

      - Ist die Anzahl der Diagnoseeintr?ge immer gleich oder variiert diese
        Anzahl ?

        Soweit die Anzahl nicht variiert, handelt es sich offenbar um
        einmalig vorkommende Fehler im Programm. Es gibt F?lle, bei denen
        die Bezeichnung Fehler sogar etwas zu scharf gew?hlt ist. Manche
        Programme legen n?mlich quasi-statische Variablen auf dem Heap an,
        und geben diese dann am Ende nicht wieder frei. So ein Verhalten
        ist zwar nicht sonderlich sch?n und sollte deshalb vermieden werden;
        es hat andererseits aber auch keine schlimmen Konsequenzen.

      - L??t sich das Anwachsen der Anzahl der Diagnosezeilen mit einer
        bestimmten Funktion meines Programms in Zusammenhang bringen ?

        Wenn die Anzahl w?chst, dann sollte man versuchen, den sich
        offenbar wiederholenden Fehler auszumachen. Meistens ist das sehr
        einfach, wenn n?mlich der Heap Debugger f?r mehrere Eintr?ge die
        selbe Aufruferadresse ausgibt. Es handelt sich dann wohl um einen
        Fehler, der immer dann zum Tragen kommt, wenn eine bestimmte
        Programmfunktion ausgel?st wird. Solche Fehler sollte man auf jeden
        Fall beseitigen, da sie den gef?rchteten "Ged?chtnisschwund" ausl?sen.

      - Wurde in einzelnen Diagnosezeilen irgendein Flag eingetragen ?

        Soweit nicht, handelt es sich bei den Diagnosen des Heap
        Debuggers um Hinweise auf "klassische" Fehler, n?mlich auf das
        unterlassene Freigeben "normaler" Heapspeicherbl?cke, die
        mittels GetMem oder New angefordert wurden. Die Sourcecodereferenz
        verweist auf die Stelle, an der diese Anforderung geschehen ist.

      - Wurde in einzelnen Diagnosezeilen das Flag "O" eingetragen ?

        Soweit ja, weist der Heap Debugger auf Verfehlungen im Zusammenhang
        mit Objekten hin. Wird z.B. nur ein "O" eingetragen, dann handelt
        es sich um nicht freigegebene Instanzdaten eines Objektes, welche
        (im allgemeinen) mittels New in der OOP-Variante, n?mlich
        New(ptr, constructor), angelegt worden sind. Die Sourcecodereferenz
        deutet aber dann NICHT auf diese New-Anweisung, sondern auf die
        Zeile BEGIN im betreffenden Constructor. Wenn man diesen ausgemacht
        hat, mu? man ?berlegen, wo Instanzen dieses Objekttyps angelegt
        werden und dort auf korrekte Freigaben pr?fen.
 
      Seite 11


      - Wurde in einzelnen Diagnosezeilen das Flag "F" eingetragen ?

        Dieses Flag kommt nie allein. Es bedeutet (meistens), da? ein Deallo-
        kationsfehler passiert ist. Au?er dem "F" ist immer entweder ein
        "S" oder ein "M" gesetzt, was bedeutet, da? entweder eine Deallokation
        mit einer falschen Blockl?nge aufgerufen worden ist, bzw. da? der
        deallokierte Speicherblock an einer Adresse liegt, an der vorher
        keine Allokation vorgenommen worden ist.

        Solche Diagnosen sind entweder sehr schlimm oder sehr harmlos.
        Der harmlose Fall ist im Abschnitt "MemAllocSeg" beschrieben. Wenn
        diese Beschreibung nicht zutrifft, dann liegt wahrscheinlich ein
        echter Fehler vor, der unbedingt gefunden werden mu?, weil er das
        gesamte Programm (auch den Heap Debugger) zum Absturz bringen kann.
        Letzteres kann passieren, wenn die Konsistenz der Heapverwaltung
        nicht mehr gegeben ist. In so einem Fall k?nnen ?brigens auch Daten
        auf dem Heap verst?mmelt werden.


      ___ Auffinden von Bugs _________________________________________________

      Wenn der Heap Debugger zu seinen Diagnosen Sourcecodereferenzen ausgeben
      konnte, dann ist das Auffinden von Bugs verh?ltnism??ig einfach.

      Wenn die Sourcecodereferenz allerdings mit "?" angegeben wird, dann be-
      findet sich die unter "Aufrufer" aufgef?hrte Adresse in einem Modul, das
      nicht mit der Option "D+", also ohne Debuginformationen ?bersetzt worden
      ist. Oft ist der Aufrufer dann in der Run-Time-Library zu finden.

      Man sollte sich aber nicht zu dem Schlu? verleiten lassen, da? man f?r
      den entsprechenden Fehler dann gar nicht verantwortlich ist und da? die
      Run-Time-Library einen Bug hat. Wenn von Ihnen z.B. eine Allokation
      mittels "NewStr" (Funktion der Run-Time-Library) vorgenommen wurde,
      und der so angeforderte Heapspeicherblock wurde anschlie?end nicht
      korrekt mit DisposeStr deallokiert, dann liegt der Fehler in Ihrem
      Programmteil; als Aufrufer wird aber eine Zeile in der Funktion NewStr
      genannt.

      Viele Probleme dieser Art kann man l?sen, indem man die ganze
      Run-Time-Library mit Debug-Option neu ?bersetzt. Das ist nur bei
      BP7.0, nicht bei TP7.0 m?glich. Informationen hierzu bietet Borland
      in der Datei \BP\RTL\README.


      ___ Arbeiten mit einem externen Debugger _______________________________

      In hartn?ckigen F?llen kann man versuchen, einen Fehler mit Hilfe des
      externen Debuggers einzugrenzen. Das ist besonders dann sinnvoll, wenn
      man dem Heap Debugger trotz aller Bem?hungen keine Sourcecodereferenz
      entlocken kann.

      Im externen Debugger sollte man versuchen, auf die fragliche Programm-
      stelle (die Aufruferadresse) einen Breakpoint zu setzen.

      Beachten Sie hierzu den Unterschied zwischen der virtuellen und der
      aktuellen Segmentadresse, die der Heap Debugger ausgibt.
 
      Seite 12


      Achtung: Die aktuelle Segmentadresse eines Aufrufers kann sich von
      Programmlauf zu Programmlauf verschieben. Nach dem Laden des Debuggers
      wird sie sich sogar sehr wahrscheindlich verschieben. Lassen Sie daher
      Ihr Programm mit geladenem Debugger einmal oder mehrmals laufen, ohne
      einen Breakpoint zu setzen. Verwenden sie die zuletzt ausgegebene
      aktuelle Segmentadresse, um den Breakpoint zu setzen. Sie setzen einen
      Breakpoint auf eine von Hand eingegebene Adresse mit der Funktion
      "Breakpoints->At...". Geben Sie einfach die Adresse ein und beginnen Sie
      die Segmentadresse UND die Offsetadresse jeweils mit "$" f?r hexadezi-
      male Notation.

      Wenn Sie Ihr Programm dann starten und einen Breakpoint erreichen,
      versuchen Sie das Programm ab dieser Stelle in Einzelschritten fortzu-
      setzen, bis Sie zu einer Stelle des Programms kommen, die Ihnen bekannt
      ist.


      ___ Compilerschalter in USEHDEB ________________________________________

      In die Unit UseHDeb wurden bereits einige Compilerschalter eingef?hrt,
      die die Anpassung an besondere Anforderungen erleichtern sollen. Wir
      hoffen, da? damit die allermeisten Anpassungsprobleme zu l?sen sind, so
      da? dem Anwender eine weitergehende Ver?nderung des Sourcecodes erspart
      bleibt.

      Der Schalter "USE_SHAREWARE":

      Wenn dieser Schalter aktiv ist, dann wird der Heap Debugger in einer der
      Units "HDEB7S.TP?" benutzt. Wenn er ausgeschaltet ist, dann wird eine
      der Units "HDEB7F.TP?" eingebunden. Letztere stellt die Vollversion des
      Heap Debuggers dar und kann nat?rlich nur verwendet werden, wenn die
      Software registriert worden ist. Dieser Compiler ist bei Lieferung der
      Shareware- bzw. der Vollversion schon richtig eingestellt und mu? also
      in der Regel nicht ver?ndert werden.

      Der Schalter "GERMAN_LANG":

      Wenn dieser Schalter aktiv ist, dann wird der Heap Debugger Report in
      deutscher Sprache ausgegeben, sonst in Englisch.

      Der Schalter "GETDEBUGINFO":

      Wenn dieser Schalter aktiv ist, dann wird bei der Reportausgabe ver-
      sucht, auf die Debug-Informationen im EXE-File zuzugreifen, um Dateina-
      men und Zeilennummer zu jeder Diagnosezeile zu ermitteln. Dieser Schal-
      ter sollte normalerweise aktiv bleiben.

      Der Schalter "REPORT_TO_FILE":

      Wenn dieser Schalter aktiv ist, dann wird die Reportausgabe der Unit
      UseHDeb in eine Datei umgeleitet. Der Name dieser Datei wird mit der
      Konstanten DumpFileName festgelegt und ist auf "HEAPDEB.DMP" voreinge-
      stellt, kann aber ver?ndert werden. Die Datei wird mit jeder Reportaus-
      gabe erweitert. Bitte beachten Sie: Wenn der Heap Debugger aus irgendei-
      nem Grund nicht initialisiert wurde und der Schalter "REPORT_TO_FILE"
      aktiviert ist, dann wird das Programm ohne Ausgabe einer Meldung (auch
      nicht in die Datei) mit dem Kommando "HALT" gestoppt.
 
      Seite 13


      Der Schalter "SWITCH_TO_LASTMODE":

      Wenn dieser Schalter aktiv ist, dann wird vor der Reportausgabe der Unit
      UseHDeb mit dem Kommando "Textmode(LastMode)" in den Videomodus zur?ck-
      geschaltet, der beim Start des Programms aktiv war. Dies kann n?tzlich
      sein, wenn das Hauptprogramm z.B. in einen vom BIOS nicht unterst?tzten
      Grafikmodus umschaltet oder Textfarben so manipuliert, da? die Report-
      ausgabe nicht lesbar ist. Dieser Schalter hat unter Windows keine Aus-
      wirkung.

      Beispiel f?r das Ein- und Ausschalten eines Schalters:
           aktiv:   "{$DEFINE GERMAN_LANG}"
           inaktiv: "{not $DEFINE GERMAN_LANG}"


      HEAP DEBUGGING IM DETAIL _______________________________________________

      ___ Overlays ___________________________________________________________

      Sie k?nnen den Heap Debugger auch innerhalb von Programmen nutzen, die
      von Overlayprogrammierung Gebrauch machen. Die Units USEHDEB und HDEB7?
      d?rfen allerdings nicht als Overlays geladen werden.


      ___ DLLs _______________________________________________________________

      Eine DLL kann man mit dem Heap Debugger behandeln wie ein normales, ei-
      genst?ndiges Programm. Wenn ein Programm, das den Heap Debugger verwen-
      det, zur Laufzeit eine DLL einbindet, dann ist der Heap Debugger f?r
      diese DLL nicht wirksam. Umgekehrt kann eine DLL den Heap Debugger ver-
      wenden, ohne da? dadurch die Heap-Operationen im Hauptprogramm ?berwacht
      werden. Wird sowohl in eine DLL alsauch in das Hauptprogramm der Heap
      Debugger eingebunden, so werden zum Programmende zwei Reporte ausgege-
      ben.

      Das Einbinden des Heap Debuggers in eine DLL erfolgt demgem?? auch wie
      bei einem normalen Programm: In der Hauptquelldatei der DLL (mit der
      ?berschrift "library") wird die Unit UseHDeb als erste in die uses-
      Klausel eingef?gt.

      Der Exit-Code der Unit UseHDeb (mit der Reportausgabe) wird beim Beenden
      der DLL durchgef?hrt. Wann ist das ? Die DLL wird normalerweise beendet,
      wenn auch das Hauptprogramm, das die DLL geladen hat, beendet wird. Es
      gibt allerdings Ausnahmen. Wenn man das Hauptprogramm mit dem externen
      Debugger ausf?hrt, so wird die DLL nicht bei Programmende abgeschlossen,
      sondern beim Verlassen des Debuggers, was dann aus unerfindlichen Gr?n-
      den h?ufig zu einem Absturz des Rechners f?hrt. Es empfiehlt sich daher
      sehr, eine DLL, die den Heap Debugger einbindet, zur Laufzeit des Haupt-
      programms gezielt mit der Anweisung "FreeLibrary" zu beenden, wodurch
      der Exit-Code der Unit UseHDeb f?r die DLL ausgef?hrt und somit der Re-
      port ausgegeben wird.

      Das bisher Gesagte gilt f?r DLLs unter DOS und unter Windows gleicher-
      ma?en.
 
      Seite 14


      Unter Windows ergibt sich aber noch ein zus?tzliches Problem: Die Re-
      portausgabe, die von der Unit UseHDeb unter Windows ja in ein WinCrt-
      Fenster vorgenommen wird, klappt bei einer DLL nicht: Die Folge des Ver-
      suches, eine Reportausgabe aus einer DLL heraus in ein WinCrt-Fenster
      vorzunehmen, ist in aller Regel entweder ein Laufzeitfehler oder das
      v?llige Ausbleiben jeder Ausgabe. Unter DOS gibt es diese Probleme
      nicht.

      Es ist unter Windows bei Einsatz des Heap Debuggers in einer DLL also
      unbedingt notwendig, die Ausgaben der Unit UseHDeb in eine Datei umzu-
      leiten. Hierf?r wurde der Schalter "REPORT_TO_FILE" vorbereitet (siehe
      hierzu "Compilerschalter in USEHDEB").


      ___ Programminstanzen (Windows) ________________________________________

      Wenn unter Windows ein Programm, das den Heap Debugger einbindet, in
      mehreren Instanzen gestartet wird, so wird nur f?r die erste Instanz der
      Heap Debugger installiert. Folgende Instanzen nutzen automatisch den
      schon installierten Heap Debugger mit. Die Ausgabe des Reports erfolgt
      erst nach Beenden der letzten aktiven Instanz des Programms, und der Re-
      port beinhaltet alle Heap-Operationen, die in anderen Instanzen des sel-
      ben Programms vorgenommen wurden, ohne das die verursachenden Instanzen
      in dem Report voneinander unterschieden werden k?nnen. Um die ?bersicht-
      lichkeit zu wahren, sollten also m?glichst nicht mehrere Instanzen aus-
      gef?hrt werden.


      ___ Interrupts ________________________________________________________

      Der Heap Debugger ben?tigt f?r seine Arbeit drei eigene Softwareinter-
      rupts. Das hei?t, da? der Heap Debugger bei der Installation drei freie
      Interruptvektoren belegt und diese bei Programmende wieder restauriert.
      Der Heap Debugger sucht sich die freien Softwareinterrupts selbst aus,
      und zwar im Bereich 78h bis FFh. Aus diesem Bereich k?nnen gezielt ein-
      zelne Interrupts vom Programmierer ausgeschlossen werden, indem in der
      Unit UseHDeb.PAS die Anweisung "HeapDebInit([])" ver?ndert wird. In der
      als Parameter angegebenen leeren Menge kann eine Menge von Interruptnum-
      mern definiert werden, die vom Heap Debugger nicht benutzt werden
      sollen. Eine ?nderung dieses Aufrufes in "HeapDebInit([$F0..$FF])" w?rde
      z.B. die Interruptvektoren F0h bis FFh f?r die Benutzung durch den Heap
      Debugger ausschlie?en und somit f?r das Hauptprogramm freihalten.


      ___ Stabilit?t und Performance _________________________________________

      Wie schon erl?utert sollte der Heap Debugger nicht als Bestandteil fer-
      tiger Applikationen eingesetzt werden. Der Heap Debugger sollte aus-
      schlie?lich als Debuggingwerkzeug in der Entwicklungsphase verwendet
      werden.

      Der permanente Einsatz des Heap Debuggers w?hrend der Softwareentwick-
      lung kann die Stabilit?t der entwickelten Software erheblich verbessern
      und die Entwicklungszeit verk?rzen.

      Es ist jedoch nicht auszuschlie?en, da? der Heap Debugger in der Ent-
      wicklungsphase eine potentielle Ursache f?r Programmabst?rze sein kann,
      auch wenn dies von uns bisher nicht beobachtet werden konnte. Folgende
      Tatsachen sollten beachtet werden:
 
      Seite 15


      - Der Heap Debugger ?berwacht nicht nur die korrekte Verwendung des
        Heapspeichers. Er ben?tigt auch selbst Heapspeicher f?r diese Aufgabe.
        Wenn ein Programm zeitweise eine gro?e Anzahl von Heapspeicherbl?cken
        allokiert, so kann der zus?tzliche Speicherbedarf des Heap Debuggers
        erheblich sein. Mit zus?tzlichen 24 Byte je allokiertem (und noch
        nicht wieder deallokiertem) Speicherblock sollte gerechnet werden.
      - Die Ausf?hrung des Heap Debuggers erfordert zus?tzlich Platz auf dem
        Stack, und zwar sowohl bei der Ausf?hrung von Speicheroperationen als-
        auch bei der Ausgabe der Reports in der Exitprozedur der Unit UseHDeb.
        Hier ist zu beachten, da? teilweise keine ?berpr?fung des Stacks m?g-
        lich ist, so da? ein zu klein dimensionierter Stack ein Programm zum
        Absturz bringen kann.
      - Bei massiven Fehlern des Applikationsprogrammierers bei dem Umgang mit
        Heapspeicher kann der Einsatz des Heap Debuggers, der wie gesagt auch
        selbst mit Heapspeicher arbeitet, den Absturz eines Programmes sogar
        erst ausl?sen, was, in einer zuf?llig anderen Konstellation, ohne den
        Heap Debugger vielleicht nicht passiert w?re. Solche Abst?rze k?nnen
        zum Beispiel dann passieren, wenn die Applikation versucht, einen vor-
        her gar nicht allokierten Speicherbereich freizugeben. In diesem Fall
        ist ein Programmabsturz als klares Indiz f?r einen Programmierfehler
        jedenfalls einem tr?gerischen fehlerfreien Programmablauf vorzuziehen.
      - Der Heap Debugger braucht f?r seine Arbeit zus?tzliche Rechenzeit. Je
        mehr Speicherbl?cke allokiert werden, um so mehr steigt der Zeitbedarf
        des Heap Debuggers, insbesondere beim Wiederfreigeben von Speicher.
        Diese Performanceeinbu?e wird aber allenfalls bei sehr zeitkritischen
        Anwendungen irgendwie sp?rbar sein.
      - Der Heap Debugger ben?tigt, wie schon im vorherigen Abschnitt erw?hnt,
        f?r seine Arbeit drei freie Softwareinterrupts, deren Vektoren er zum
        Anfang des Programms auf eigene Routinen umlenkt und zum Ende des Pro-
        gramms wieder restauriert. Wenn ein Programm durch einen fatalen Feh-
        ler so abrupt beendet wird, da? die Exitprozedur von UseHDeb nicht
        mehr durchlaufen wird, dann werden auch diese Interruptvektoren nicht
        mehr wieder auf ihre alten Werte eingestellt. Wenn anschlie?end gela-
        dene Programme aber von korrekten Werten in diesen Vektoren abh?ngig
        sind, so kann dies zu Problemen f?hren. Wenn sich solche Abst?rze sehr
        h?ufig wiederholen, dann kann der Heap Debugger irgendwann keine
        freien Interrupts mehr finden und kann nicht gestartet werden.


      ___ Eingriffsm?glichkeiten f?r den Programmierer _______________________

      Es ist f?r einige F?lle denkbar, da? ein Programmierer ?nderungen am
      Heap Debugger vornehmen m?chte, um z.B. die Reportausgabe seinen eigenen
      Vorstellungen anzupassen. Aus diesem Grunde wird die Unit UseHDeb im
      Quellcode mitgeliefert. Programm?nderungen d?rfen nur an dieser Unit und
      nur zu eigenen, nichtkommerziellen Zwecken vorgenommen werden.

      Dar?berhinaus bietet das Interface der Unit HDeb7?.TP? folgende typi-
      sierte Konstanten an, die zur Laufzeit eines Programms ver?ndert werden
      k?nnen:
 
      Seite 16


      1)   SuspendHeapdeb : Boolean = false;

      Wird diese Konstante zur Laufzeit des Hauptprogramms auf TRUE gesetzt,
      so werden anschlie?end keine Heap Operationen vom Heap Debugger mehr
      aufgezeichnet. Nach R?ck?nderung des Wertes auf FALSE arbeitet der Heap
      Debugger wieder normal. Dies kann z.B. n?tzlich sein, um quasi statische
      Allokationen, die sonst bei jeder Reportausgabe des Heap Debuggers auf-
      gef?hrt werden, f?r den Heap Debugger "unsichtbar" zu machen und dadurch
      einen "sauberen" Report zu erm?glichen.

      2)   RecordZeroSize : Boolean = false;

      Solange diese Konstante den Wert FALSE hat, werden Allokationen und De-
      allokationen mit der L?nge Null vom Heap Debugger ignoriert. Weil solche
      Operationen reine Sch?nheitsfehler sind und unseres Wissens keinen Scha-
      den anrichten k?nnen, ist diese Konstante auf FALSE voreingestellt.

      3)   RTEOnWrongSizedFree : Byte = 0;

      Wenn in diese Konstante ein anderer Wert als Null geladen wird, dann
      wird bei jeder Deallokation, die nicht die gleiche L?nge wie die zuge-
      h?rige Allokation aufweist (Flag "S"), sofort ein Run-Time-Error ausge-
      l?st. Die Nummer des Run-Time-Errors wird durch diese Konstante
      bestimmt.

      4)   RTEOnUnknownFree : Byte = 0;

      Wenn in diese Konstante ein anderer Wert als Null geladen wird, dann
      wird bei jeder Deallokation, zu der keine passende Allokation (gleiche
      Anfangsadresse des Heapspeicherblocks) gefunden werden kann (Flag "M"),
      sofort ein Run-Time-Error ausgel?st. Die Nummer des Run-Time-Errors wird
      durch diese Konstante bestimmt.


      BEKANNTE EINSCHR?NKUNGEN UND PROBLEME __________________________________

      ___ Mark/Release _______________________________________________________

      Von der Verwendung der Befehle Mark und Release erh?lt der Heap Debugger
      keinerlei Kenntnis und kann sie also auch nicht ber?cksichtigen. Dar?ber
      hinaus kann die Anweisung Release den Heap Debugger erheblich st?ren
      (bis hin zum Programmabsturz), weil dadurch eventuell auch Aufzeichnun-
      gen des Heap Debuggers verworfen werden, ohne da? der Heap Debugger die-
      ses erkennen kann.

      Allerdings werden die Befehle Mark und Release fast gar nicht mehr ver-
      wendet, denn sie bringen, unabh?ngig von der Unvertr?glichkeit mit dem
      Heap Debugger, noch eine Reihe anderer Probleme mit sich. Wahrscheinlich
      sind sie in der aktuellen Version des Compilers nur noch aus Kompatibi-
      lit?tsgr?nden implementiert. Von der Verwendung von Mark und Release ist
      also allgemein abzuraten. Mark und Release stehen nur unter DOS zur Ver-
      f?gung.
 
      Seite 17


      ___ MemAllocSeg ________________________________________________________

      Die Funktion MemAllocSeg in der Unit Memory (unter Windows: OMemory)
      stellt den Heap Debugger vor ein gro?es Problem: Die Aufgabe dieser
      Funktion ist es, einen Heapspeicherbereich anzufordern, dessen Anfangs-
      adresse genau auf dem Anfang eines Speichersegmentes liegt, also die
      Offsetadresse 0000 hat. Um dieses zu erreichen, greift die Funktion
      MemAllocSeg tief in die Trickkiste, wobei wir zwischen den verschiedenen
      Zielplattformen unterscheiden m?ssen:

      Real Mode:

      Um garantiert einen Heapspeicherbereich mit der Offsetadresse 0000 allo-
      kieren zu k?nnen, reserviert die Funktion MemAllocSeg mittels GetMem zu-
      n?chst einen etwas gr??eren Bereich, um anschlie?end sofort wieder einen
      kleinen Teil davon (n?mlich 8 Bytes), die entweder am Anfang oder am
      Ende des gerade allokierten gr??eren Bereichs liegen, mittels FreeMem
      freizugeben. Hier wird also etwas getan, was zwar in engen Grenzen er-
      laubt, aber verp?nt ist: Der Heap Debugger "beobachtet" diese Operatio-
      nen und wird sie sp?ter in seinem Report ausgeben. Das kann dann z.B. so
      aussehen:

         program TEST;
         uses UseHDeb, Memory;
         var p: pointer;
         begin
           {...}
           p := MemAllocSeg(100);
           FreeMem(p, 100);
         end.

      HEAP-DEBUGGER-DIAGNOSE:
      1 Pointer wurden registiert
      3 Debug-Eintraege vorhanden
      auflisten (J/N) ? j

      Nr    Pointer   Size  Flags          Aufrufer         Datei  Zeile
       1  1A4D:0000    112    S     020B[1438]:001F    MEMORY.PAS    327
          1A53:0008      8   F M    020B[1438]:00D5    MEMORY.PAS    355
          1A4D:0000    100   FS     0000[122D]:003A      TEST.PAS      7

      Oder so:

      HEAP-DEBUGGER-DIAGNOSE:
      1 Pointer wurden registiert
      3 Debug-Eintraege vorhanden
      auflisten (J/N) ? j

      Nr    Pointer   Size  Flags          Aufrufer         Datei  Zeile
       1  1531:0008    112    S     020C[0F1A]:001F    MEMORY.PAS    327
          1531:0008      8   FS     020C[0F1A]:00D5    MEMORY.PAS    355
          1532:0000    100   F M    0000[0D0E]:004A      TEST.PAS      7

      Der Programmierer ist wohl oder ?bel gezwungen, solche nicht ganz ast-
      reinen Heap-Operationen zu dulden und derartige Diagnosen des Heap
      Debuggers zu ignorieren.
 
      Seite 18


      (Die Referenz auf die Sourcecodestellen in der Unit Memory werden nur
       dann ausgegeben, wenn diese Unit mit der Option $D+ ?bersetzt worden
       ist.)

      Protected Mode (DOS/DPMI):

      Hier hat es die Funktion MemAllocSeg etwas einfacher als im Real Mode:
      Sie ruft einfach die Funktion "MemAllocateBlock" auf, welche von der
      RTM.EXE zur Verf?gung gestellt wird und eine entsprechene DPMI-Funktion
      darstellt. Dadurch wird ein Heapspeicherblock allokiert, der garantiert
      bei der Offsetadresse 0000 beginnt. Wie schon im Abschnitt "Globaler und
      lokaler Heap" beschrieben, erh?lt der Heap Debugger von diesem Vorgang
      keine Kenntnis. Die Freigabe des so allokierten Heapspeicherblocks wird
      jedoch ?berlicherweise mit der Funktion FreeMem vorgenommen, wovon der
      Heap Debugger s

#####  To see the rest of this file, please download it  #####

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.