(K) Valgrind-harjoitus¶
Huomautus
Valgrind toimii Linux-etätyöpöydällä ja Linux-koneilla, mutta todennäköisesti ei Mac- eikä Windows-koneilla (tai valgrindin asentaminen näille koneille ei onnistu).
Macilla saat kuitenkin valgrindin käyttöösi ssh:n avulla: Kirjoita Macin komentorivillä komento:
ssh user_id@linux-desktop.tuni.fi
missä kohdan user_id
tilalle kirjoitat oman käyttäjätunnuksesi.
Jos tulostuu kysymys “Are you sure you want to continue …”,
voit vastata “yes”.
Tämän jälkeen jatka, kuten on kerrottu vähän alempana löytyvässä
kohdassa Komennon valgrind suorittaminen komentorivillä.
Tavoite:
Opin käyttämään valgrind
-työkalua muistinhallinnan ongelmien
jäljittämiseen ja tulkitsemaan tämän työkalun tulosteita.
Tämä on tärkeää siksi, että lopuissa projekteissa yksi läpäisyvaatimus on,
että ohjelmassa ei ole muistin käsittelyyn liittyviä ongelmia.
Siitä on tarkoitus varmistua ohjelman
testausvaiheessa valgrind
-työkalun avulla.
Ohjeita:
Hae ohjelmakoodipohja: templates/09/valgrind/
->
student/09/valgrind/
.
Tutkitaan seuraavaa pientä ohjelmaa, josta jo pintapuolisesti tutkimalla huomataan useita muistin käsittelyyn liittyviä ongelmatilanteita:
#include <iostream>
using namespace std;
int main() {
int number1;
int number2 = 111;
int *ptr1 = new int;
int *ptr2 = new int(222);
cout << number1 << " "
<< number2 << " "
<< *ptr1 << " "
<< *ptr2 << endl;
delete ptr1;
*ptr1 = 333;
}
Seuraavissa kohdissa annetaan ohjeet valgrind
-työkalun käyttöön
sekä Qt Creatorissa että komentorivillä.
Mikäli mahdollista kannattaa kokeilla näitä molempia ja vertailla niitä
toisiinsa.
Komennon valgrind
suorittaminen Qt Creatorissa¶
Avaa student/09/valgrind/
-hakemistoon siirtämäsi projekti Qt Creatorissa.
Jos haluat, voit suorittaa ohjelman. Application Output -ikkunaan pitäisi tulostua “exited with code 0”, eli ohjelman suoritus päättyi paluuarvolla EXIT_SUCCESS, mikä tarkoitaa, että kaikki meni hyvin (siitä huolimatta, että ohjelmassa ei oikeastaan ole mitään muuta kuin virheitä). Huomaa, että kun ohjelmassa on näin paljon muistinkäsittelyyn liittyviä ongelmia kuin tässä esimerkkiohjelmassa, niin ei ole mitenkään taattua, että sen suorittaminen sujuu ongelmitta. Tehtävää laadittaessa ohjelman on pystynyt suorittamaan loppuun asti linux-desktopille asennetulla kääntäjäversiolla, mutta emme voi taata, että ohjelma toimii samoin kaikissa ympäristöissä.
Suorita valgrind
valitsemalla Analyze > Valgrind Memory Analyzer
.
Ohjelma käynnistyy, mutta tällä kertaa Application Output -ikkunaan
tulostuu “Analyzing finished”.
Lisäksi Qt Creatorissa aukeaa ikkuna Memcheck, jonka mustassa yläpalkissa
pitäisi lukea “Memory Analyzer Tool finished, 8 issues were found”.
Tässä tehtävässä tutkimme tämän ikkunan sisältöä.
Jos Qt Creatorisi ei näytä otsikoiden Issue ja Location alla mitään,
klikkaa ikkunan mustassa yläpalkissa olevaa filtteriä esittävää
kuvaketta ja rastita kohta “External Errors”, niin
valgrind
-työkalun löytämät 8 ongelmaa ilmestyvät listaan.
Qt Creatorin Memcheck-ikkunassa on kaksi saraketta: Issue ja Location. Location-sarakkeeseen pääsee käsiksi kahdella tavalla sen jälkeen, kun on alas päin osoittavaa nuolen kärkeä klikaten avannut jonkin pitkistä riveistä tutkiaksesi sen sisältöä:
- vierittämällä Memcheck-ikkunan alareunan vierityspalkkia oikealle
- asettamalla hiiren kursorin sen rivin kohdalle, johon liittyvästä Location-sarakkeesta olet kiinnostunut ja odottamalla, kunnes näkyviin ilmestyy laatikko, jossa on kohta Location niiden rivien tapauksessa, jolloin Location-sarake sisältää jotakin.
Komennon valgrind
suorittaminen komentorivillä¶
Käynnistä komentorivikäyttöliittymä ja navigoi hakemistoon, jossa em. ohjelmakoodi on talletettuna (edellisen kohdan projektihakemisto).
Käännä lähdekoodisi käsin syöttämällä Linux-komentoriville käännöskäsky:
g++ -std=c++11 -Wall -g main.cpp
Jos lähdekoodissa ei ollut virheitä, syntyy tuloksena suoritettava ohjelma (konekielitiedosto) nimeltä
a.out
.Jos haluat, voit kokeilla ohjelman suorittamista kirjoittamalla Linux-komentoriville käskyn:
./a.out
Suorita seuraavaksi
valgrind
-komento valmiiksi käännetylle ohjelmalle:valgrind --quiet --leak-check=full ./a.out
Jos ohjelmassa ei ole muistinkäsittelyyn liittyviä ongelmia, näytölle ei tulostu mitään ylimääräistä oman ohjelmasi tulosteiden lisäksi.
Koska tässä esimerkkiohjelmassa oli muistinkäsittelyongelmia,
valgrind
tulostaa käsittämättömän määrän informaatiota, jota alamme nyt tutkia. Sinun pitää katsoa tulostetta alusta alkaen, eli vieritä terminaalia ylöspäin niin pitkälle, että näet kirjoittamasivalgrind
-komennon. (Vinkki: terminaali-ikkuna kannattaa myös venyttää mahdollisimman korkeaksi työskentelyn helpottamiseksi.)
Komentorivillä tulosteen jokaisen rivin alussa näkyy jotain tämäntyylistä “==6647==” ja joillakin riveillä lisäksi jotakin tämäntyylistä “at 0x4F31BE3:”. Qt Creatorissa näitä ei näytetä ollenkaan, joten voit päätellä, että ne eivät ole olennaisia tietoja ja voit lukea komentorivitulostetta siten, että et huomioi näitä ollenkaan.
Lopuksi, kokeile vielä suorittaa Qt Creatorissa
Analyze > Valgrind Memory Analyzer with GDB
.
Huomaat, että tämä käynnistää valgrind
-työkalun debuggaustilassa, jolloin
ohjelmakoodia voi askeltaa rivi kerrallaan, kuten debuggerissa yleensäkin.
Nyt Application Output -ikkunasta löytyy samannäköinen
tuloste kuin terminaali-ikkunastakin.
Kun lopetat, varmista, että debuggeri on suljettu!
Useimmiten Qt Creator siirtyy Edit-tilasta Debug-tilaan, kun
suoritat komennon valgrind
.
Joskus voi käydä niin, että Qt Creator ei toimi näin, vaan Memcheck-ikkunan
näkymiseksi sinun pitää itse siirtyä Edit-tilasta Debug-tilaan.
Tämän “ominaisuuden” (?) ilmentyessä on hyvä ymmärtää, että valgrind
suoritetaan Qt Creatorissa aina Debug-tilassa.