Esittely latautuu. Ole hyvä ja odota

Esittely latautuu. Ole hyvä ja odota

Virheiden käsittely Hyvä ohjelma ei koskaan kaadu hallitsemattomasti, vaan tuottaa järkevän virheilmoituksen tai muuten käsittelee virhetilanteen jollain.

Samankaltaiset esitykset


Esitys aiheesta: "Virheiden käsittely Hyvä ohjelma ei koskaan kaadu hallitsemattomasti, vaan tuottaa järkevän virheilmoituksen tai muuten käsittelee virhetilanteen jollain."— Esityksen transkriptio:

1 Virheiden käsittely Hyvä ohjelma ei koskaan kaadu hallitsemattomasti, vaan tuottaa järkevän virheilmoituksen tai muuten käsittelee virhetilanteen jollain mielekkäällä tavalla. Erityisesti yleiskäyttöiset funktiot pitää suunnitella niin, että niitä käyttävät ohjelmat voivat varautua niiden virhetilanteisiin. Standardikirjastossa on joukko virhetilanteiden käsittelyyn tarkoitettuja funktioita ja makroja.

2 <assert.h> assert(skalaarilauseke);
assert on makro, jota käytetään funktion tavoin: sen argumentti on lauseke, jonka pitäisi olla tosi. Jos se on epätosi, assert keskeyttää ohjelman virheilmoitukseen, joka tulostaa tyypillisesti “Assertion failed”, ao. lausekkeen, tiedostonimen ja rivinumeron. Sitä käytetään ohjelmankehityksen aikana. Kun ohjelma on ”valmis”, assert-testit voi ohittaa määrittelemällä makron NDEBUG.

3 #include <assert.h> ...
// assert-esimerkki #include <assert.h> ... // koodia jonka jälkeen olemme 99.99% varmoja, // että y > 0, mutta emme ihan... assert(y>0); Ajo: $ ./myprog myprog: myprog.c:1200: main: Assertion 'y>0' failed. Aborted.

4 <errno.h> errno.h määrittelee globaalin muuttujan errno, joka sisältää viimeksi tapahtuneen kirjastofunktion havaitseman virhetilanteen koodin, ja koodin mahdollisia arvoja vastaavat makrot. Standardi vaatii koodit EDOM, “domain error”: argumentin lukualueen ylitys esim. sqrt(-1.0), asin(2.0) jne ERANGE, “range error”: paluuarvon lukualueen ylitys esim. exp( ) (todennäköisesti) C99:ssä on lisäksi EILSEQ (liittyy leveisiin merkkeihin) ja konekohtaisesti yleensä paljon muitakin (alkavat E[A-Z]); Unix/Linux-ympäristössä ks. man errno.

5 perror ja strerror Virhekoodien käsittelyyn on pari funktiota:
void perror(const char *s); // stdio.h char *strerror(int errnum); // string.h perror keskeyttää ohjelman ja tulostaa annetun tekstin ja järjestelmän virheilmoituksen, strerror palauttaa annettua virhekoodia vastaavan tekstin. Esim. errno=0; /* jos edellisen virheen jäljiltä muuta */ if (x=sqrt(y), errno) { fprintf(log, “%d: %s\n”, __LINE__ strerror(errno)); perror(“sqrt failed”); exit(EXIT_FAILURE); }

6 Debuggaus: gdb gdb (Gnu debugger) on erityisesti gcc:n ja C:n ja C++:n kanssa toimiva komentorividebuggeri (toimii joidenkin muidenkin kielten kanssa rajoitetusti). Debuggerin perustoimintoja ovat ohjelman suorittaminen askel kerrallaan, tilapäinen keskeyttäminen halutussa kohdassa ja muuttujien arvojen katsominen (ja muuttaminen) testausta varten.

7 Debuggerin käyttöä varten ohjelma kannattaa kääntää -g -optiolla (tallettaa mm. muuttujanimet binääriin). Ohjelma käynnistetään sitten debuggerilla tyyliin gdb ./myprog Jos ohjelmalle halutaan välittää argumentteja: gdb --args ./myprog a b c Argumentit voi myös asettaa käynnistyksen jälkeen: (gdb) set a b c On myös mahdollista “ottaa kiinni” jo käynnissä oleva ohjelma prosessi-id:llä: gdb -pid pid

8 Kaatuneen ohjelman core dumpin voi myös lukea:
gdb -core core Usein sen kanssa lisäksi halutaan ohjelma, josta symbolit löytyvät: gdb -core core -exec myprog Muitakin optioita on, mainittakoon vielä gdb -x komentotiedosto ... jolla voi suorittaa tekstitiedostoon talletetun joukon gdb:b komentoja.

9 Ohjelma käynnistetään gdb:n alla komennolla run (r).
Sitä ennen kannattaa yleensä asettaa ainakin yksi breakpoint eli keskeytyskohta, kohta koodissa johon tultaessa gdb keskeyttää ohjelman (muuttujien katsomista yms varten) komennolla break (b), argumenttina funktionimi, rivinumero tai (konekielisen) käskyn osoite: (gdb) break main (gdb) r break-komennolle voi antaa myös ehdon: (gdb) b 150 if i>5 keskeyttäisi ohjelman rivillä 150 jos i>5 on tosi.

10 Ohjelman voi myös asettaa keskeytymään tietyn muuttujan tai lausekkeen arvon muuttuessa asettamalla watchpointin komennolla watch: (gdb) watch x Komennolla info voi tarkistaa mitä breakpointteja tai watchpointteja on asetettu: (gdb) info b (gdb) info watch ja niitä voi poistaa komennoilla clear (sijainnin mukaan) ja delete (numeron mukaan): (gdb) clear main (gdb) delete 1

11 Ohjelman keskeydyttyä suoritusta voi jatkaa eri tavoin,
tärkeimmät: continue [n] seuraavaan breakpointiin (n:n ohi) step [n] suorittaa seuraavan lähdekoodirivin (n riviä) next [n] samoin mutta suorittaa funktiot pysähtymättä (step askeltaa funktioiden sisään) finish jatkaa suoritusta funktion loppuun stepi [n] suorittaa seuraavan konekielikäskyn nexti [n] kuten stepi mutta suorittaa funktiokutsun pysähtymättä sen sisällä

12 Muuttujien (tai yleensä muistipaikkojen) arvoja (ja niistä muodostettuja lausekkeita) voi tarkastella komennolla print (p): (gdb) print x (gdb) p 2+*x (gdb) p (char *)p Prosessorin rekistereihin voi viitata $-alkuisilla nimillä, rekisteriluettelon saa komennolla info registers. (gdb) p $cs Komennolla display saa lausekkeen tulostuksen toistumaan aina kun ohjelma pysähtyy.

13 Muuttujan tai rekisterin arvoa voi muuttaakin print-komennolla:
(gdb) print x=4 (gdb) set var x=4 (gdb) set $rbp = 0x1234 (set-komennossa “var” on tarpeen vain jos muuttujan nimi muistuttaa jotain set'in avainsanaa.) Siinä voi käyttää myös esim. osoitinviittauksia tai rekistereiden arvoja ($-etuliitteellä, ja yleensä typecast tarvitaan jos rekisteriä käyttää pointterina): (gdb) p *(int *)$rsp = 0

14 Ohjelman lähdekoodia voi tarkastella komennolla list:
(gdb) list 5 (gdb) list myfun (gdb) list 5,10 Ohjelmassa voi myös hypätä haluttuun kohtaan, esim. riville 50: (gdb) jump 50 jump samalla jatkaa ohjelman suoritusta. Ohjelmaosoittimen voi myös siirtää suoraan: (gdb) p $pc = 0x485

15 Ohjelman tilan voi tallettaa ja palata siihen myöhemmin, jos esim
Ohjelman tilan voi tallettaa ja palata siihen myöhemmin, jos esim. huomaa vahingossa ohittaneensa kriittisen kohdan: (gdb) checkpoint (gdb) info checkpoints ... (gdb) restart checkpoint-id restart palauttaa prosessin tilan --rekisteri, muuttujat, kaiken mahdollisen-- sellaiseksi kuin se oli checkpoint-kohdassa.

16 Lisätietoa gdb:n komennoista saa komennolla help:
(gdb) help Netistä löytyy myös paljon dokumentaatiota, ks.


Lataa ppt "Virheiden käsittely Hyvä ohjelma ei koskaan kaadu hallitsemattomasti, vaan tuottaa järkevän virheilmoituksen tai muuten käsittelee virhetilanteen jollain."

Samankaltaiset esitykset


Iklan oleh Google