Valgrind ist ein Softwarepacket um Linux Programme zu debuggen (Fehler aufspüren). Die weiteren Fähigkeiten interessieren uns vorerst nicht. Und da man am besten am Beispiel lernt werden wir dies hier auch so machen. Die Beispiele zeigen dabei jeweils eine Art von Fehler bei dem einen Valgrind helfen kann.
Anmerkung: Dieses Tutorial wurde für die Lehrveranstaltung Einfürung in die strukturierte Programmierung von Studienassistent Andreas Weinberger geschrieben. (Stand 15.11.2006, valgrind Version 2.2.0). Feedback und Anregungen bitte per Email an mich (esp-t5-andreas@iicm.edu).
Warnung: Valgrind ist nur ein Hilfsmittel um auf Fehler zu prüfen. Es kann aber nicht alles finden. Es ersetzt keinesfalls das saubere und durchdachte Arbeiten (Schlammpig zu arbeiten und im Nachhinein alle Fehler ausbessern ist der falsche Weg. Man sollte Fehler so gut es geht von vornherein vermeiden).
Da valgrind am Pluto vorinstalliert ist und die Abgaben auch auf
diesem laufen müssen wird alles dort vorgezeigt. Als erstes
muss man sich dazu am Pluto per ssh anmelden. Als nächstes
holt Ihr euch den benötigten Beispielcode
wget http://www.sbox.tugraz.at/home/w/weinberg/esp/valgrind/valgrind_tutorial.tar.gz
und entpackt diesen
tar xzvf valgrind_tutorial.tar.gz
01 #include <stdlib.h>
02 int main(int argc, char *argv[])
03 {
04 int number1, number2;
05 if (number1 == 5)
06 number2 = number1 + 1;
07 return 0;
08 }
Den Code wie gewohnt kompilieren:
Und nun rufen wir valgrind auf:
Es gibt uns folgenden Fehler an:
Conditional jump or move depends on uninitialised value(s)Davor gibt es die Adresse im Speicher an wo der Fehler auftrat. Um damit etwas anfangen zu können muss man sich schon recht gut auskennen und auch mit Debuggern fit sein. Aber man kann es sich auch wesentlich einfacher machen. Dazu kompilieren wir nochmal:
Beachtet den neuen Paramter "-g" an den Kompiler. Das ist die Anweisung an den gcc Debug Informationen zu generieren. Wir rufen nun wieder valgrind auf:
Diesmal wird der Fehler genauer angegeben: "at 0x8048354: main (example01.c:5)". Die Zahl 5 nach dem Dateinamen sagt uns das der Fehler in Zeile 5 liegt (die Angabe stimmt in einfachen Fällen immer, kann aber sehr selten auch einmal falsch sein). Wenn wir nun einen Blick in den Sourcecode werfen sehen wir das es sich um die Zeile mit dem if handelt. Dort findet offensichtlich ein Vergleich statt. Die Fehlermeldung sagt uns das dieses if (Conditional jump) von einer nicht initalisierten Variable abhängt. Da es nur eine gibt muss es number1 sein. Diese wir eine Zeile darüber deklariert und dort tatsächlich nicht intialisiert. Wenn das If ausgeführt ist enthält die Variable einen zufälligen Wert. Das ist mit ziemlicher Sicherheit ein Fehler, gehört also ausgebessert. Die Lösung ist die Variable bei der Deklaration zu intialsieren. Probiert dies nun aus (Source ändern, kompilieren und wieder valgrind aufrufen).