Ubuntu 16.04 Xenial Xerus
Ubuntu 12.04 Precise Pangolin
Valgrind ist eine häufig bei der Analyse von Programmfehlern ("bug analysis") verwendete, quelloffene Kommandozeilen-Werkzeugsammlung (mit einigen vorhandenen grafischen Frontends) zum Debuggen, Profilen und zur dynamischen Fehleranalyse von Linux-Programmen.
Die unter Ubuntu 16.04 in den Quellen vorliegende Version 3.11 ist momentan (05.09.2016) nicht voll funktionsfähig; als Notlösung kann aber die Version aus Ubuntu 16.10 verwendete werden!
Eine Anleitung, valgrind aus dem Source-Code zu erstellen findet sich in diesem Blog-Beitrag .
Valgrind startet das zu testende Programm in einer virtuellen Maschine, so dass kein Programm direkt auf der Gast-CPU ausgeführt wird. Stattdessen übersetzt Valgrind das Programm in einen temporären, einfacheren und Plattform-unabhängigen Byte-Code, den sogenannten Ucode. Nach der Konvertierung können verschiedene Valgrind-Hilfsprogramme ("tools") diverse Transformationen vornehmen (z.B. Überwachen des Speichers oder Erstellen eines Ablauf-Profils), bevor Valgrind den neuen Code nimmt, in Maschinencode übersetzt und schließlich ausführt.
Zwar lässt die Konvertierung in den Ucode und zurück ein Programm um ein vielfaches langsamer laufen, dazu addieren sich dann noch die Zeiten der verschiedenen Werkzeuge, jedoch ist der Ucode wesentlich geeigneter für das Debuggen und das Erstellen der Werkzeuge, und die langsame Ausführungszeit ist für die meisten Programme kein Problem. Hinzu kommt der Vorteil, dass das zu prüfende Programm nicht aufbereitet zu werden, ja nicht einmal im Quellcode vorzuliegen braucht.
Valgrind funktioniert am besten mit Programmen, die Debugging-Information enthalten (also mit dem Flag -g in gcc/g++ kompiliert wurden), damit es Probleme zeilengenau aufspüren kann. Unter Ubuntu sollte man daher (falls vorhanden) vor dem Testen mit Valgrind das Debugging-Paket des zu testenden Programms (<Paket>-dbg) installieren, z. B. pidgin-dbg.
Valgrind ist in den Ubuntu-Quellen enthalten. Dazu muss folgendes Paket installiert [1] werden:
valgrind
mit apturl
Paketliste zum Kopieren:
sudo apt-get install valgrind
sudo aptitude install valgrind
Zur manuellen Installation werden neben den Paketen zum Kompilieren noch folgende Pakete benötigt [1]:
autotools-dev
debhelper
dpatch
gdb
libc6-dev
gcc-multilib
libc6-dbg (empfohlen: verbessert die Ergebnisse von Valgrind)
mit apturl
Paketliste zum Kopieren:
sudo apt-get install autotools-dev debhelper dpatch gdb libc6-dev gcc-multilib libc6-dbg
sudo aptitude install autotools-dev debhelper dpatch gdb libc6-dev gcc-multilib libc6-dbg
Von der Valgrind-Homepage sollte man sich die aktuelle Version als Quellcode herunterladen und entpacken. Danach wird das Programm gemäß der Debian-Paketierungsmethode kompiliert und installiert [2].
Alternativ kann ein grafisches Frontend für Valgrind installiert werden. Dazu muss man das Paket
alleyoop (universe)
mit apturl
Paketliste zum Kopieren:
sudo apt-get install alleyoop
sudo aptitude install alleyoop
installieren.
Weitere GUIs sind auf der Valgrind-Homepage aufgelistet. Diese sind allerdings nicht alle in den Ubuntu-Paketquellen zu finden.
Zu den GUIs ist zu sagen, dass bei Valgrind eine GUI so gut wie überflüssig ist, wenn man Log-Dateien ("logfiles") nur erstellen will (möchte diese jedoch auswerten, bietet eine GUI sicherlich Vorteile).
Valgrind ist ein Programmpaket, welches aus mehreren einzelnen Hilfsprogrammen ("tools") besteht. Es können außerdem mehrere inoffizielle Tools in den Quellcode eingebunden werden, diese sind auf der Valgrind-Homepage aufgelistet. Folgende Hilfsprogramme helfen einem bei der Fehleranalyse:
Das wichtigste Tool ist memcheck, welches folgende Fehler finden kann:
Benutzung von nicht initialisiertem Speicher
Lese- und Schreibzugriffe auf freigegebenen Speicher
Schreiben über die Speichergrenzen hinaus
Speicherlecks
Das Werkzeug helgrind hilft bei der Suche nach Race Conditions und erleichtert das Debuggen mit Threads.
cachegrind ist auf jede Programmiersprache anwendbar und führt den Code 20-100-mal langsamer als normal aus. Es überprüft Fehler im Zugriff auf die Cache-Verwaltung der CPU.
callgrind ermittelt umfangreiche Statistiken über das eingesetzte Programm. Die Zahlen sind auf verschiedenen Systemen direkt miteinander vergleichbar, weil diese nicht die benötigte Ausführungszeit messen, sondern die Anzahl der CPU-Takte. Es gibt auch an, ob Algorithmen besonders schnell im Cache der CPU laufen können und wie oft es zu einem Treffer ("cache hit") oder Nicht-Treffer ("cache miss") kommt. Die Größe der Caches kann man variieren, somit lassen sich verschiedene CPUs simulieren.
massif zeigt den verwendeten Dynamischen Speicher (Heap-Memory) des Programms an.
lackey gibt allgemeine Informationen über die Programmausführung aus.
Im Wesentlichen startet man Valgrind mit dem Befehl [3]
valgrind --tool=<tool-name> <Programm> <Programm-Optionen>
Das Tool memcheck benötigt keine Valgrind-Option, man kann das --tool=memcheck
also weglassen.
Für <Programm>
und <Programm-Optionen>
wird das zu debuggende Programm mit den Optionen eingesetzt. Wenn man z.B. das Programm ls mit der Option -l
durch callgrind testen möchte, startet man
valgrind --tool=callgrind ls -l
Valgrind hat sehr viele Optionen, mit denen man das Debuggen steuern, regeln und verbessern kann. Eine vollständige Liste findet sich in der Manpage z.B. auf: www.valgrind.org
Die wichtigsten Optionen sind:
--tool=<toolname>
(Standard: memcheck)
Startet das genannte Valgrind-Tool, z.B. Memcheck, Helgrind, Cachegrind usw.
--track-fds=<yes|no>
(Standard: no)
Falls diese Option aktiviert ist, wird Valgrind eine Liste von offenen Dateien ausgeben, zusammen mit Informationen darüber, wann, wie und wo die Datei geöffnet wurde.
--time-stamp=<yes|no>
(Standard: no)
Falls diese Option aktiviert ist, zeigt Valgrind in der Log-Datei einen auf Millisekunden genauen Zeitstempel bei jeder Aktion an.
--log-file=<Dateiname>
Legt fest, dass Valgrind alle Log-Nachrichten in der angegebenen Datei speichert. Beispiel:
valgrid --log-file=valgrind-log_pidgin.txt
--log-socket=<Ip-Adresse:Port-Nummer>
Legt fest, dass Valgrind alle Log-Nachrichten an die festgelegte IP-Adresse sendet. Dabei muss der Port nicht zwingend genannt werden, Standard-Port ist 1500. Falls die IP-Adresse nicht erreichbar ist, wählt Valgrind den Standard-Error-Output (stderr). Beispiel:
valgrind --tool=callgrind --log-socket=127.0.0.1:1234
--leak-check=<no|summary|yes|full>
(Standard: summary)
Normalerweise gibt Valgrind beim Fund von Speicherlecks ("memory leaks") nur die Meldung aus, dass solche gefunden wurden (plus Anzahl). Falls der Wert auf full
steht, gibt es zusätzliche Informationen zum Speicherleck aus. Dies ist nur bei memcheck
verwendbar.
Wenn man (z.B. mit Hilfe von Apport) einen Fehlerbericht zu einem Programmabsturz bei Launchpad erstellt, kommt es häufig vor, dass die Entwickler mehr Informationen zu dem Absturz ("crash") haben möchten. Deshalb fordern sie mit dem folgenden Text einen Valgrind-Log:
Thank you for taking the time to report this bug and helping to make Ubuntu better. Please try to obtain a valgrind log following the instructions at https://wiki.ubuntu.com/Valgrind and attach the file to the bug report. This will greatly help us in tracking down your problem.
Um eine für die Entwickler brauchbare Log-Datei zu erstellen, startet man Valgrind mit dem folgenden Befehl
G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind -v --tool=memcheck --leak-check=full --num-callers=40 --log-file=valgrind.log <Programm> <Programm-Optionen>
G_SLICE
und G_DEBUG
sind Umgebungsvariablen von GLib , die (in diesem Fall) das Debuggen verbessern bzw. erst ermöglichen.
Nach dem Start sollte man die Schritte durchführen, die nötig sind, um den Fehler oder Absturz zu reproduzieren.
Die Log-Datei valgrind.log befindet sich in dem aktuellen Ordner, man kann diese nun bei Launchpad in dem Fehlerbericht ("bug report") hochladen und so den Entwicklern zur Verfügung stellen.
Diese Revision wurde am 7. September 2016 21:12 von Heinrich_Schwietering erstellt.