Hellä ensikosketus Tomi Kiviniemi
Asialista Vähän debuggauksen filosofiaa. GDB:n peruskäyttö Netbeansissä. GDB:n peruskäyttö komentoriviympäristössä. Hieman edistyneempää sähellystä komentoriviympäristössä.
GDB Mikä? Miksi? GDB eli GNU Debugger on ohjelma, joka mahdollistaa ohjelmien suorituksen tarkan analysoinnin. Muuttujien tilan tarkasteleminen ja muuttaminen. Ohjelman ajaminen rivi riviltä. Ajon keskeyttäminen etukäteen määritellyissä kohdissa (breakpoint). Täydellistä koodia on maailmassa valitettavan vähän, ja esimerkiksi debug-tulosteet ovat usein turhan kömpelö tapa listiä bugeja. Debuggeri on hyödyllinen myös tutustuttaessa ohjelman (sisäiseen) toimintaan. Se tarjoaa eräänlaisen hiekkalaatikkoympäristön, jota on varsinkin tämän kurssin puitteissa suositeltavaa hyödyntää ihan puhtaassa oppimistarkoituksessa. Erityisesti macin omistajien on syytä kääntää katseensa GDB:n sijaan esimerkiksi LLDB:hen.
Peruskäyttö käytännössä
Komentorivi on ystävä pwd kertoo nykyisen kansion koko polun, siis käytännössä oman sijaintisi ls listaa kansiossa olevat tiedostot cd siirtyy haluttuun kansioon cd directory_x cd.. (edelliseen kansioon) Oman ohjelman nimeltä main ajaminen:./path/to/the/folder/main (piste merkkaa nykyistä kansiota) Kurssin tehtävissä main löytyy aina tehtäväkansiosta katsoen polusta./src/main Oletusarvoisesti Netbeans tallentaa kurssin tehtävät kotikansiosta ( ) katsoen paikkaan /NetBeansProjects/aalto-C-spring-2016/
GDB:n käyttö komentorivillä Ensinnäkin kääntäessä kääntövipujen on syytä olla kunnossa. GCC:n tapauksessa kaikkein olennaisin vipu on -g. Kääntäjäoptimoinnit (-O) kannattaa myös jättää pois. Kurssin tehtävissä kaikki on oletuksena jo valmiiksi hoidossa. gdb./src/main Käynnistää debug-session ohjelmalle main. Vahvasti interaktiivisen ohjelman debuggaus ei yleensä onnistu erityisen hyvin tällä tavalla. Yksi ratkaisu tähän on jo olemassaolevan prosessin liittäminen GDB:hen (attaching an existing process). Kiinnostujat kiinnostuu, nyt ei asiaa käsitellä tarkemmin.
Tärkeimmät komennot start / run käynnistää, alussa keskeytyspiste / ei keskeytyspistettä next / step seuraava rivi, ohittaa funktion / siirtyy funktioon print tulostaa asioita print variable (muuttujan arvo) print *variable (osoitinmuuttujassa olevasta osoitteesta löytyvä arvo (!)) print &variable (muuttujan osoite (!!)) print array[5] (taulukon arvo indeksillä 5) print *array@5 (viisi ensimmäistä taulukon arvoa) break asettaa keskeytyspisteen, breakpointin, jossa ohjelman suoritus keskeytyy break file.c:10 (tiettyyn tiedostoon tietylle riville) break function_name (tiettyyn funktioon) clear poistaa keskeytyspisteet continue jatkaa ohjelman suoritusta
Hyödyllisiä komentoja set variable asettaa muuttujalle uuden arvon set variable a=5 bt backtrace, näyttää kutsupinon: funktiot, joiden kautta tänne ollaan päädytty frame [n] vaihtaa kehystä (siirtyminen kutsupinossa) list [position] listaa lähdekoodia list nykyisen kohdan ympäriltä list 15 rivistä 15 eteenpäin quit poistuu GDB:stä help pika-apua syntaksiin yms. help bt
Muutama edistyneempi ominaisuus
Kun tavallinen breakpoint ei riitä Ehdollinen breakpoint on ilmeinen vaihtoehto. Tyypillinen käyttöesimerkki on toistolausekkeen pysäyttäminen haluttuun kohtaan. break [where] if (condition) break main.c:15 if (i==20) Asettamalla watchpoint saadaan ajo keskeytettyä aina, kun jotain muuttujaa tai lauseketta käytetään (esimerkiksi muutetaan arvoa). watch [variable] kirjoittamisen havainnointi watch weird_variable rwatch lukemisen havainnointi awatch molemmat
Examine Examine on hieman print-komennon kaltainen, raa an muistin tarkastelemiseen tarkoitettu äärimmäisen hyödyllinen komento. x/nfu [address] n montako blokkia? f yhden blokin esitysformaatti (mm. x heksana ja t binäärinä) u yhden blokin koko (mm. b tavu (8 bittiä) ja w sana (4 tavua)) x/10xb &a Kymmenen tavun kokoista blokkia heksamuodossa lähtien muuttujan a osoitteesta. x/2tw &a Kaksi sanan kokoista blokkia (yhteensä siis 2 4 8 = 64 bittiä) binäärimuodossa lähtien muuttujan a osoitteesta.