Login
Login-Name Passwort


 
Newsletter
Werbung

Mi, 5. März 2003, 00:00

Speicherüberprüfung unter Linux

Typische Probleme, auf die man Programmieren immer wieder stößt, sind Memory Leaks (nicht wieder freigegebener und vergessener Speicher) und andere Probleme mit der dynamischen Speicherverwaltung, die ohne entsprechende Tools nur schwer zu finden sind. Bereits die GNU Libc unterstützt aber das Debuggen der Speicherverwaltung, darüber hinaus gibt es diverse Werkzeuge, die bei der Suche nach Fehlern im Zusammenhang mit malloc, free und Konsorten helfen.

Im folgenden stelle ich drei Hilfsmittel vor, die beim Auffinden von Problemen mit der Speicherverwaltung helfen können. Selbstverständlich ist die Auswahl rein subjektiv und unvollständig.

mtrace()

Wenn die Funktion mtrace(), die in der Libc enthalten ist, aufgerufen wird, werden alle Speicheranforderungen (malloc, ...) und -freigaben (free, ...) in eine Datei, die durch die Environment-Variable MALLOC_TRACE festgelegt wird, geloggt. Normalerweise ruft man mtrace() als erste Funktion in main() auf.

Das Kommando mtrace wertet diese Datei dann aus.

Beispiel

$ MALLOC_TRACE=mlog program
$ mtrace programm mlog
Memory not freed:
-----------------
Address Size Caller
0x08049310 0xa00 at /home/berberic/blafasel/test/main.c:98

Damit die Ausgabe die Quelldateien und die Zeilennummern enthalten kann, muß das bearbeitete Programm Debuginformation enthalten (mit -g übersetzt und nicht gestrippt).

MALLOC_CHECK_

Durch die Environmentvariable MALLOC_CHECK_ können in der GNU Libc integrierte Überprüfungen der Speicherverwaltung angeschaltet werden:

MALLOC_CHECK_=1:
entdeckte Probleme werden auf stderr ausgegeben.
MALLOC_CHECK_=2:
bei Problemen (heap corruption) wird sofort abgebrochen. Dies ist nützlich in Zusammenhang mit einem Debugger und Debuginformation im Programm.

Beispiele

$ MALLOC_CHECK_=1 program
malloc: using debugging hooks
free(): invalid pointer 0x80495f8!
$ MALLOC_CHECK_=2 program
Aborted
$ MALLOC_CHECK_=2 gdb program
[···]
(gdb) run
Starting program: /tmp/X
Program received signal SIGABRT, Aborted.
0x4004f781 in kill () from /lib/libc.so.6
(gdb) where
#0 0x4004f781 in kill () from /lib/libc.so.6
#1 0x4004f464 in raise () from /lib/libc.so.6
#2 0x40050be1 in abort () from /lib/libc.so.6
#3 0x40096a30 in malloc_set_state () from /lib/libc.so.6
#4 0x40094a29 in free () from /lib/libc.so.6
#5 0x08048463 in main () at X.c:6

Mit dem gdb kann man also feststellen, daß der Fehler in der Datei X.c in Zeile 6 in der Funktion main() entdeckt wurde (die Ursache kann natürlich wie immer ganz woanders liegen) und kann von dort aus die Suche starten.

libefence

Die Bibliothek libefence kann das Schreiben vor oder hinter einen allokierten Speicherbereich feststellen. Dazu muß mit der Bibliothek gelinkt werden (-lefence). Das Verhalten läßt sich über das Environment steuern. Einige wichtige Variablen sind:

EF_PROTECT_BELOW=1:
testet auf Zugriffe vor dem Anfang des allokierten Speicherbereichs, anstatt auf Zugriff nach dem Ende wie normal.
EF_PROTECT_FREE=1:
verwendet freigegebenen Speicher nicht wieder um Zugriffe auf bereits freigegebenen Speicher festzustellen
EF_ALLOW_MALLOC_0=1:
Erlaubt malloc()-Aufrufe mit 0 Byte angefordertem Speicher.

Beispiel

$ program
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
ElectricFence Aborting: free(4015dff4): address not from malloc().
Illegal instruction

Auch hier "stürzt" das Programm wieder an der Stelle ab, an der der Fehler entdeckt wird, und mit Hilfe eines Debugger kann sie gefunden werden. Da efence die virtuelle Speicherverwaltung ausnutzt, entgehen ihm bei Datentypen, die kleiner als das Alignment der Systemspeicherblöcke sind, manchmal Fehler.

Doku

Zu mtrace() und MALLOC_CHECK_ finden sich ausführliche Beschreibungen in der GNU Libc-Dokumentation. libefence kommt mit einer manpage. Weitere Werkzeuge findet man z. B. bei freshmeat.

Kommentare (Insgesamt: 0 || Kommentieren )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung