ein Kapitel zurück                                           ein Kapitel weiter

logo http://dmalloc.com/

dmalloc

Author: Gerrit Bruchhäuser

Quellenverzeichnis:

Die Homepage

Englisches Online Handbuch

Einleitung

Besondere Mermale
Die Installation
Einbinden der Bibliothek
DMALLOC_OPTIONS

dmalloc_shutdown()
dmalloc_log_heap_map()
dmalloc_log_stats()
dmalloc_log_unfreed()
dmalloc_verify()
dmalloc_debug()
dmalloc_debug_current()
dmalloc_mark()
dmalloc_log_changed()

Download: dmalloc-4.8.2.tar.gz


Einleitung

Das tool dmalloc ist recht klein aber denoch extrem flexibel. Aus der Internet Seite geht hervor das es von Gray Watson programmiert wurde. Leider sind dort keine weiteren Informationen zum Author oder dem Entstehen von dmalloc zu finden. Wie auch immer ist dmalloc auf vielen Plattformen verfügbar und findet sehr viele fehler, was es sehr beliebt macht.

Besondere Merkmale

  • Datei und Zeileninformazionen werden mit angegeben
  • Gibt Adressen zurück (hilfreich zusammen mit debuggern)
  • Grenzberreich überprüfung
  • Heap beständigkeit wird überprüft
  • Gibt Profiling informationen mit aus
  • Findet Memory leaks

Generell wird dmalloc, wie die meisten anderen memory tools, mit zu einem Programm hinzugelinkt. Das bedeutet also das man zumindest neu linken muss wenn man sein Programm mit dmalloc testen möchte.

Möchte man das Zeileninformationen mit bei der Ausgabe erscheinen, so muss man zusätzlich die Datei dmalloc.h mit in das zu testende Programm einbinden. Dabei ist allerdings darauf zu achten das man diese Datei nach allen Anderen include Dateien einbindet. Tut man dies nicht, so leuft man gefahr einer Rekursion bei einem malloc aufruf.

Die Installation ist nicht sonderlich schwierig, allerdings nimmt sie etwas Zeit in Anspruch.

Die Installation

  1. Man sollte sicherstellen, das man die neueste Version von dmalloc installiert.
  2. Als nächstes schaue man sich die Datei settings.dist einmal an und passe diese gegebenfalls an seine bedürfnisse an. Sie enthällt Konfigurationsmöglichkeiten um bestimmte features der Bibliothek zu beeinflussen. Das Script configure wird später diese Datei in die Datei settings.h hineinkopieren, welche architecktur specifischen Einstellungen enthällt.
  3. Mit dem Befehl sh ./configure wird dmalloc an das System angepasst. Bevor man diesen Befehl ausführt, sollte man gegebenenfalls noch einmal einen Blick in die Datei config.help hineinwerfen in welcher weitere nützliche konfigurationsmöglichkeiten beschrieben sind. (Thread supprot...) Die meisten Sachen kann man aber auch mit ./configure --help erfragen.
  4. configure hat die Dateien Makefile und conf.h erstellt, welche man überprüfen sollte.
  5. Ein Aufruf von make sollte normalerweise genug sein, um die dmalloc Bibliotheken (libdmalloc.a und libdmalloclp.a) zu erstellen. Wenn das wie auch immer nicht funktionieren hat, so ist im contrib Verzeichnis Hilfe zu finden. Achtung: Wenn man auf die Datei return.h trifft, dann sollte man als erstes alle compiler optimierungen ausschalten. Sollte das auch nicht helfen, so ist das Macro USE_RETURN_MACROS in der Datei settings.h zu deactivieren.
  6. Sollte man (wie auch immer) vergessen haben das man auch noch die Thread sichere dmalloc Variante haben möchte, so kann man diese mit make threads nachträglich erstellen.
  7. Mit make tests erstellt man das Testprogramm dmalloc_t.
  8. make light sollte das Testprogramm einige male starten, um die Funktion der Bibliothek zu testen.
  9. Als letztes kann man mit make install die Bibliotheken installieren. Hat man auch noch die Thread sichere Variante compiliert, so muss man zusätzlich make installh und für C++ make installcc aufrufen. Die dmalloc Bibliothecken sollten nun in '/usr/local/lib' und die Haeder Datei dmalloc.h in '/usr/local/include' zu finden sein.

Einbinden der Bibliothek

  1. Man muss sicherstellen das dass System eine der beiden Funktionen on_exit oder atexit berreitstellt. Tut es das nicht, so muss man selbst an einer beliebigen Stelle (am besten am Ende) des zu testenden Programms die Funktion dmalloc_shutdown, welche die Logdatei von dmalloc mit allen noch nicht gefreeten pointern auf die Fesplatte schreibt, aufrufen.
  2. Um schneller mit dmalloc arbeiten zu können kann man sich einen alias definieren, welcher in einer bash oder ksh so aussieht: function dmalloc { eval `command dmalloc -b $*`; } In einer csh oder tcsh sieht der alias so aus: alias dmalloc 'eval `\dmalloc -C \!*`' Es ist nicht umbedingt erforderlich diesen alias zu setzen, obwohl er in der Manual angegeben ist. Er bewirkt das die Ausgabe vom dmalloc Befehl wiederum als Befehl ausgeführt wird.
  3. Um Zeilennummern mit ausgegeben zu bekommen, kann man optional die Datei dmalloc.h mit in die zu testenden Dateien mit einbinden. Man muss dann allerdings darauf achten das diese nach allen Anderen include Dateien aufgeführt ist.
  4. Nun ist es an der Zeit die dmalloc Bibliothek mit in das Programm hinzuzulinken. Die Bibliothek sollte hinter allen anderen Bibliotheken stehen, um möglichst viele Fehler zu finden. (Beispiel: gcc -o main main.c -legal -ldmalloc)
  5. Bevor man sein Programm startet sollte man dmalloc noch anweisen Fehler zu finden, was z.B. mit dem Befehl dmalloc -l logfile -i 100 low leicht zu machen ist. Man kann das natürlich auch per Hand machen, indem man die Umgebungsvarieble DMALLOC_OPTIONS verändert.
  6. Als letztes steht noch ein starten des Programms und das auswerten der Logdatei aus.

DMALLOC_OPTIONS

debug lockon log addr inter start log-stats log-non-free log-thread-id log-trans log-stamp log-admin log-blocks log-unknown log-bad-space log-nonfree-space log-elapsed-time log-current-time check-fence check-heap check-lists check-blank check-funcs force-linear catch-signals realloc-copy free-blank error-abort alloc-blank heap-check-map print-messages catch-null never-reuse allow-free-null error-dump

DMALLOC_OPTIONS

Mit der Umgebungsvariablen DMALLOC_OPTIONS kann man geziehlt auf das Verhalten der Bibliothek einfluss nehmen. Nachfolgend sind die einzelnen gültigen Optionen aufgeführt welche mit DMALLOC_OPTIONS=Wert gesetzt werden können.

debug
Sollte gleich einem Hexadecimalen Wert gesetzt werden welcher einer dazugehörigen Funktion entspricht. Der Wert 0x008 sagt zum Beispiel aus das man alle Transaktionen mitprotokollieren möchte. Es ist auch möglich mehrere Parameter an dieser Stelle zu kombinieren. Um Reichweitenüberprüfung zu aktivieren gibt es z.B. den Wert 0x400 welcher dann mit 0x008 zusammenaddiert 0x408 ergibt. Wer sich nicht alle Werte und deren Bedeutung merken will, sollte statt dieser Option die für den Menschen besser verständlichen Optionen verwenden.
lockon
Dieser Parameter setzt den "lock-on" Zeitraum. Dies gibt der Thread sicheren Variante der Bibliothek an mutex nicht zu locken oder zu initialisieren bis die hier angebene Anzahl von allokierungen gemacht wurden.
log
Gibt die Logdatei an, welche falls debug benutzt wird, alle wichtigen Informationen zum debuggen des Programms enthällt. Hat man mehr als einen Prozess, den man testen möchte, so kann man optional den Platzhalter %d für die PID des Prozesses im Logdatei namen angeben. Es ist allerdings wichtig zu wissen, das alle anderen Platzhalter dmalloc zu einem core bringen.
addr
Wenn diese Option angegeben ist, wird dmalloc beim antreffen der angebenen Adresse abbrechen. Die Adresse kann hier sogar ein :nummer Argument enthalten, welches die Anzahl der erlaubten allokierungen oder freigaben dieser Adresse angiebt. Ist diese Option z.B. auf den Wert 0x3e45:10 gesetzt, wird dmalloc beim zehnten versuch einer allokierung an Adresse 0x3e45 abbrechen. Diese Option ist nützlich wenn man alle Aktivitäten an einer bestimmten Adresse mitverfolgen möchte.
inter
Wenn man diese Option auf einen Wert X setzt, wird dmalloc den Heap nur jedes Xte mal überprüfen. Das bedeutet das man eine begrenzte Anzahl von Funktionen, während das Programm leuft, abschalten kann. Das macht das Programm natürlich schneller. Wenn man diese Option also z.B. auf den Wert 100 setzt, so wird dmalloc einen Fehler wahrscheinlich nicht beim ersten Auftreten finden. Allerdings kann es sein, das er er beim hundertsten Auftreten gefunden wird.
start
Dieser Wert gibt an, ab der wievielten Speicheroperation dmalloc anfangen soll den Heap zu testen. Dieser Wert kann auch in einem file:line Format angegeben werden, was dann bedeutet das dmalloc ab dem Antreffen einer malloc funktion der angebenen Zeile den Heap testet.
log-stats
Schreibt Statistische Werte mit in die Log Datei.
log-non-free
Protokolliert alle nicht gefreeten Pointer mit wenn das Programm sich beendet hat.
log-thread-id
Hängt die Thread ID mit an jede Information.
log-trans
Protokolliert generell alle Transaktionen mit.
log-stamp
Hängt eine Zeitmarke mit an alle Ausgaben.
log-admin
Gibt eine ganze menge Administrative Informationen mit aus.
log-blocks
Wenn dmalloc_log_heap_map aufgerufen wird, werden detailierte Block informationen mit ausgegeben.
log-unknown
Ist das gleiche wie log-non-free allerdings werden hiermit auch alle Allokierungen mitprotokolliert bei welchen keine Datei und Zeileninformationen verfügbar sind.
log-bad-space
Testet die Bytes um und in einem Schlechten Zeiger.
log-nonfree-space
Logt alle nicht gefreeten bytes.
log-elapsed-time
Logt alle gefreeten Zeiger mit Zeiten.
log-current-time
Protokolliert die aktuelle Zeit mit.
check-fence
Schaltet die Reichweitenüberprüfung ein.
check-heap
Überpüft die Heap Hauptstrucktur.
check-lists
Sichert die interne Heap liste.
check-blank
Stellt sicher das gefreete Adressberreiche nicht nocheinmal überschrieben werden. Wenn diese Option eingeschaltet ist, werden die Optionen free-blank und alloc-blank automatisch eingeschaltet.
check-funcs
Checkt die Argumente (nur Zeiger) von Funktionen.
force-linear
Beschwert sich über den Heap wenn die Funktion sbrk direckt hinter einer dmalloc funktion aufgerufen wird. Diese Funktion ist Standard mässig abgeschaltet da eine ganze menge System Funktionen von dieser Funktion gebrauch machen.
catch-signals
Fährt die Bibliothek automatisch bei einem der Signale SIGHUP, SIGINT, oder SIGTERM herunter. Das wird die Bibliothek anweisen die Logdatei auf die Festplatte zu schreiben, wenn man STRG-C drückt.
realloc-copy
Bei einem realloc immer einen neuen Zeiger zurückgeben.
free-blank
Schreibt ein besonderes Zeichen (hex 0xdf) in jedes gefreete Byte.
error-abort
Bricht das Programm bei einem Fehler ab und erstellt einen core.
alloc-blank
Schreibt in jedes allokierte Byte das Zeichen (octal 0xda).
heap-check-map
Schreibt ein Abbild des Heaps in die Logdatei wenn sich der Heap ändert.
print-messages
Alle dinge die in die Log Datei gehen, werden zusätzlich auf std. error ausgegeben.
catch-null
Bricht das Programm ab wenn die Bibliothek keinen Speicher mehr von sbrk zurückgegeben bekommt.
never-reuse
Gibt niemals einen einmal Allocierten Berreich ein zweites mal durch eine Funktion zurück. Diese Funktion sollte mit Vorsicht benutzt werden da das System nur eine Begrenzte Anzahl von Adressen zur verfügung hat.
allow-free-null
Die Bibliothek wird keinen Fehler melden wenn das Programm versucht einen NULL Zeiger frei zu geben.
error-dump
Erstellt bei einem Fehler einen core und fährt dann fort. Spätere cores überschreiben ältere. Diese Option wird nur funktionieren wenn das System fork unterstützt und das Konfigurationstool ohne eine Rekursion zu verursachen aufrufen kann.

Schaltet alle Transaktions und statistiken ein, welche in die Datei dmalloc.log aufgenommen werden.

setenv DMALLOC_OPTIONS "log-trans,log-stats,log=dmalloc.log"

Schaltet das debug Flag 0x1f (Heap überprüfung) ein und setzt den Intervall auf 100.

setenv DMALLOC_OPTIONS "debug=0x1f,check-heap,inter=100"

Setzt malloc als Logdatei und schaut auf die Adresse '0x1234' und starte die Überprüfung wenn die Datei file.c Zeile 123 erreicht worden ist.

setenv DMALLOC_OPTIONS "log=malloc,addr=0x1234,start=file.c:123"

Gibt alle noch nicht gefreeten Pointer bei Programmende mit in die Datei dmalloc.log mit aus.

setenv DMALLOC_OPTIONS "log=dmalloc.log,log-non-free"

dmalloc_shutdown()

Schaltet die dmalloc funktionen aus und schreibt die zu loggenden Daten in die Logdatei. Die Bibliothek besitzt normalerweise einen Mechanismus um diese Funktion beim Programmende aufzurufen, was ein eigenes Aufrufen unnötig macht. Wie auch immer gibt es fälle (und Systeme) in denen es sinn macht diese Funktion von hand aufzurufen.

main()
{
        ...
        dmalloc_shutdown();
        exit(0);
}

dmalloc_log_heap_map()

Diese Funktion schreibt beim aufruf ein Grafisches Abbild des Heaps in die Logdatei.

dmalloc_log_stats()

Schreibt alle aktuellen Statistiken in die Logdatei.

dmalloc_log_unfreed()

Ein aufruf dieser Funktion bewirkt ein abbild aller nicht gefreeten Segmente in die Logdatei. Das kann sehr nützlch sein, um die Ausgabe z.B. mit einer späteren zu vergleichen.

1007906413: 3: dumping the unfreed pointers
1007906413: 3: dumping not-freed pointers changed since 0:
1007906413: 3:  not freed: '0x804c000|s1' (10 bytes) from 'main.c:14'
1007906413: 3:  not freed: '0x804c020|s1' (10 bytes) from 'main.c:8'
1007906413: 3:  total-size  count  source
1007906413: 3:          10      1  main.c:8
1007906413: 3:          10      1  main.c:14
1007906413: 3:          20      2  Total of 2
1007906413: 3:  known memory: 2 pointers, 20 bytes

dmalloc_verify()

int dmalloc_verify (char * PNT);

Diese Funktion kann zum Checken von verdächtigen Zeigern benutzt werden. Sie gibt entwder DMALLOC_VERIFY_ERROR oder DMALLOC_VERIFY_NOERROR zurück.

Achtung: Diese funktion kann nur die Sachen überprüfen, welche auch eingeschaltet sind! Ist zum Beispiel die Option fence-post nicht aktiviert, dann wird auch nicht danach überprüft!

dmalloc_debug()

void dmalloc_debug (long DEBUG)

Diese Funktion überschreibt die Einstellungen der Umgebungsvariablen.

dmalloc_debug_current()

long dmalloc_debug_current (void)

Gibt den aktuellen Wert der debug Umgebungsvariablen zurück.

dmalloc_mark()

Markiert einen Berreich welcher später dann mit der Funktion dmalloc_log_changed nützliche informationen über das Programm ausgiebt.

dmalloc_log_changed()

Schreibt alle Zeiger die sich seit dem Aufruf von der Funktion dmalloc_mark geändert haben in der Logdatei an.

ein Kapitel zurück          nach oben           ein Kapitel weiter


© 2001,2002 Gerrit Bruchäuser