Ohjelma-analysaattorit Tomi Solala Helsingin yliopisto Tietojenkäsittelytieteen laitos 14.11.2000
Sisällys 1. Johdanto... 1 2. Ohjelmakoodin oikeellisuuden tarkistus... 2 2.1 FlexeLint... 2 2.2 LCLint... 3 3. Ohjelmamittojen analysointi (software metrics)... 3 3.1 Krakatau Metrics for Java and C/C++... 4 4. Ohjelmakoodin visualisointi... 5 4.1 CC-Rider... 5 5. Ohjelmakoodin automaattinen dokumentointi... 6 5.1 CC-Rider... 7 6. Yhteenveto... 8 Lähteet... 9
Ohjelma-analysaattorit 1/9 1. Johdanto Ohjelmiston koon ja monimutkaisuuden kasvaessa hankaloituu ohjelmiston hallinta ja ylläpito huomattavasti. Virheiden todennäköisyys kasvaa, virheiden havaitseminen, paikantaminen ja korjaaminen vaikeutuvat. Ohjelmiston pienenkin osan muuttaminen saattaa olla riski, koska muutokset voivat aiheuttaa ennalta arvaamattomia seurauksia ohjelmiston muissa osissa. Ohjelmistojen hallintaa ja ylläpitoa vaikeuttaa lisäksi joukko yleisesti tunnettuja ongelmia: Ohjelmiston puutteellinen dokumentointi Ohjelmakoodin dokumentointi on usein aikaa vievää, työlästä ja hankalaa. Lisäksi dokumentit vaativat päivityksen aina koodin muuttuessa. Heikko tai puuttuva dokumentointi vaikeuttaa ohjelmiston hallintaa ja ylläpitoa. Syynä heikkoon dokumentointiin on usein sopivien, dokumentointi työtä helpottavien työkalujen puuttuminen. Ohjelmiston rakenteen analysointi hankalaa Ohjelmiston rakenteen analysointi on usein hankalaa ja työlästä. Suurien järjestelmien rakenteen ja toiminnallisuuden esittäminen järkevässä ja ymmärrettävässä muodossa on vaikeaa, vaikka käytössä olisikin tehtävään sopivia analysointityökaluja. Automaattisen laadunvalvonnan puutteet Ohjelmistoprojekteissa määritellään yleensä jonkinlaiset laatustandardit, joita tuotettavan ohjelmiston tulee noudattaa. Laadunvalvonta ja verifiointi on kuitenkin hankalaa ja epätarkkaa ilman automaattisia työkaluja. Edellä mainittuja ongelmia helpottamaan on kehitetty erilaisia työkaluohjelmia, ohjelma-analysaattoreita. Ohjelma-analysaattorit käyttävät tarkoitukseen sopivia algoritmeja ohjelmien analysointiin ja esittävät analysoinnin tulokset erilaisina raportteina, graafisina esityksinä ja dokumentteina. Ohjelma-analysaattorit voidaan jakaa käyttötarkoituksen perustella karkeasti neljään luokkaan. Käyttötarkoitukset ovat: ohjelmakoodin oikeellisuuden tarkistus ohjelmamittojen (software metrics) analysointi ohjelmakoodin visualisointi ohjelmakoodin automaattinen dokumentointi Seuraavissa luvuissa tarkastellaan ohjelma-analysaattoreita edellä kuvatun luokittelun mukaisesti.
Ohjelma-analysaattorit 2/9 2. Ohjelmakoodin oikeellisuuden tarkistus Ohjelmointikielen kääntäjä tarkistaa että käännettävä koodi on kyseisen ohjelmointikielen syntaksin mukaista. Useat kääntäjät kykenevät suorittamaan myös syntaksitarkistusta korkeamman tason analysointia, ja varoittamaan mahdollisista ohjelmointivirheistä. Kääntäjien ohjelmakoodin analysointi ominaisuudet ovat usein kuitenkin melko rajoitettuja. Tämän takia ohjelmakoodin oikeellisuuden tarkistamiseen on kehitetty erillisiä työkaluja, jotka analysoivat ohjelmakoodia monimutkaisia algoritmeja käyttäen. Analysaattoreiden tarkoituksena on löytää ohjelmakoodista mahdollisiksi ohjelmointivirheiksi havaittuja, usein kuitenkin ohjelmointikielen syntaksin mukaisia rakenteita, kuten esimerkiksi alustamattomien muuttujien käyttöä, funktion paluuarvon tarkistamatta jättämistä, muistin käsittely virheitä, jne. Ensimmäinen ohjelmakoodin oikeellisuuden tarkistus työkalu oli S.C.Johnssonin 1970-luvun alkupuolella kehittämä C-koodin analysointi työkalu lint [Dar89]. Lint kykeni melko monipuoliseen C-koodin staattiseen analysointiin. C-kielen kehittyessä, alkuperäisen lintin pohjalta kehitettiin kaksi uutta ohjelma analysaattoria LCLint [LCL00] ja FlexeLint [GIM00] (FlexeLintin PC ympäristössä toimiva versio on nimeltään PC-Lint). Nämä ohjelma analysaattorit ovat vielä nykyäänkin laajassa käytössä. Seuraavissa luvuissa tutustaan lyhyesti FlexeLint ja LCLint ohjelmien toimintaan. 2.1 FlexeLint FlexeLint on Gimpel Softwaren vuonna 1984 kehittämä staattinen C ja C++ lähdekoodin tarkistus ja analysointi työkalu. FlexeLint analysoi lähdekoodia erittäin monipuolisesti. Se etsii lähdekoodista mahdollisia virheitä, epäjohdonmukaisuuksia, suorittaa siirrettävyys testejä, jne. Havaituista virheistä tai mahdollisista virheistä FlexeLint ilmoittaa virheilmoituksilla ja varoituksilla (kuva 1). Analysoinnin laajuutta ja monipuolisuutta kuvaa se että uusimmassa FlexLint versiossa erilaisia virheilmoituksia ja varoituksia on jo yli 700 kappaletta. --- Module: mm001.c _ pxname, g_psmm->smyaddr.stask.u32inst); mm001.c 294 Warning 644: Variable 'pxname' (line 228) may not have been initialized --- Module: mm002.c _ } mm002.c 709 Info 715: Symbol 'p_umoduleid' (line 689) not referenced --- Module: mm900.c mm900.c 1210 Warning 429: Custodial pointer 'pastcpmsgbuf' (line 983) has not been freed or returned Kuva 1: FlexeLint virheilmoituksia
Ohjelma-analysaattorit 3/9 2.2 LCLint LCLint on John Guttag:n ja Jim Horning:n kehittämä staattinen C ja C++ lähdekoodin tarkistus ja analysointi työkalu. LCLint on ilmainen ohjelma, sen C-kielinen lähdekoodi on vapaasti saatavilla GPL (GNU General Public License) lisenssin alla. Tämän johdosta LCLintin käyttö on mahdollista kaikissa ympäristöissä joihin on saatavilla ANSI C kääntäjä. LCLint sisältää kaikki normaalit lint toiminnot ja tarjoaa tämän lisäksi normaalia linttiä kehittyneempiä ja vahvempia lähdekoodin tarkistus menetelmiä [Orc00]. Kehittyneemmät tarkistusmenetelmät perustuvat ohjelmoijan ohjelmakoodiin lisäämiin erikoiskommentteihin jotka antavat lisätietoa ohjelman toiminnasta, esimerkiksi olettamuksia funktioiden parametreista, muuttujien arvoista, jne. LCLint tukee siis myös ohjelman semanttisen rakenteen verifiointia. Kuvassa 2 on yksinkertainen esimerkki erikoiskommentoidusta ohjelmasta ja vastaavasta LCLint raportista. static void foo(int *a, int *b) /*@modifies *a@*/ { *a=1, *b=2; } main() { int p=10, q=20; foo(&p, &q); return 0; } ------------------------------------------------- LCLint 2.4b --- j.c: (in function foo) j.c:3:11: Undocumented modification of *b: *b = 2 An externally-visible object is modified by a function, but not listed in its modifies clause. (-mods will suppress message) Finished LCLint checking --- 1 code error found Kuva 2: Erikoiskommentoitu ohjelma ja vastaava LCLint raportti LCLintin kehittäjät ovat kehittäneet LCLinttiä vastaavan työkalun prototyypin myös Java lähdekoodin tarkistamiseen [Eva00]. 3. Ohjelmamittojen analysointi (software metrics) Ohjelmamitoilla (software metrics) kuvataan mm. ohjelman pituutta, kokoa ja vaikeusastetta. Näiden mittojen perusteella voidaan arvioida esimerkiksi ohjelman kompleksisuutta. Ohjelman kompleksisuuden määrittäminen voi olla hyödyllistä, sillä monimutkainen koodi on jo itsessään riskialtis virheille ja monimutkaisuuden kasvaessa myös ohjelman testattavuus vaikeutuu. Lisäksi monimutkainen koodi vaikeuttaa ohjelman ylläpitoa ja päivitystä.
Ohjelma-analysaattorit 4/9 Ohjelmamittoja voidaan käyttää ohjelmistoprojekteissa ohjelmakoodin laadunvalvontaan ja verifiointiin. Projektissa voidaan määritellä ohjelmamitoille rajaarvot joiden sisällä ohjelmistokomponenttien tulee olla. Ohjelmistokomponentit voidaan analysoida ohjelmistomitta-analysaattorilla ja saatuja tuloksia voidaan verrata asetettuihin raja-arvoihin. Yleisimmin käytettyjä ohjelmamittoja ovat mm. Halsteadin mitat [Hal77]: ohjelman pituus (program length), ohjelman koko (program volume), ohjelman vaikeusaste / virhealttius (difficulty level / error propeness), ohjelman taso (program level), ohjelman ymmärtämiseen kuluva aika (time to understand a program), virhe-ennuste (bug prediction) sekä McCaben "syklomaattinen" luku (cyclomatic number) joka kuvaa ohjelman loogista kompleksisuutta. 3.1 Krakatau Metrics for Java and C/C++ Krakatau Metrics for Java and C/C++ ohjelmisto [POW00] on ohjelmamittojen analysointityökalu Java ja C/C++ ohjelmointikielille. Ohjelmisto tukee yli 70:tä erilaista ohjelmistomittaa. Kuvassa 3 on esitetty erään ohjelman analysoinnin tulokset. Kuva 3: Krakatau Metrics ohjelmistomitta ikkuna Krakatau Metrics for Java and C/C++ ohjelmisto sisältää monipuoliset työkalut ohjelmistomittojen analysointiin, esittämiseen ja tulkitsemiseen. Ohjelmisto pohjautuu projekteihin. Käyttäjä voi määrittää projektiin kuuluvat tiedostot, konfiguroida projektissa käytettävät ohjelmistomitat ja mahdolliset raja-arvot joiden sisällä ohjelmistokomponenttien mittojen tulee olla. Analysoinnin tulokset ohjelma osaa esittää taulukkoina, erilaisina graafisina kuvina ja HTML dokumentteina. Ohjelmistoa
Ohjelma-analysaattorit 5/9 voidaan käyttää myös laadunvalvontaan: asetettujen raja-arvojen ulkopuolelle asettuvat ohjelmistokomponentit voidaan poimia analysointituloksista automaattisesti. 4. Ohjelmakoodin visualisointi Visualisoinnin tarkoituksena on kuvata ohjelman rakenne graafisessa muodossa. Tämä helpottaa usein monimutkaisten ohjelmien rakenteen hahmottamista. Ohjelmakoodin visualisointi helpottaa etenkin huonosti dokumentoitujen tai mahdollisesti kolmannen osapuolen tekemien ohjelmien ymmärtämistä ja analysointia. Useimmat ohjelmakoodin visualisointityökalut osaavat esittää luokat, funktiot, muuttujat, luokka hierarkiat, kutsupuut, kontrolli rakenteet, jne. graafisessa muodossa. Visualisointi työkaluja löytyy kaikille yleisimmin käytetyille kielille, etenkin C++ ja Java ohjelmointikielten visualisointityökalu tarjonta on kattava. 4.1 CC-Rider CC-Rider [WES00] on Western Wares:n valmistama visualisointi- ja dokumentointityökalu C/C++ kielillä toteutetuille ohjelmille. CC-Rider osaa luoda ohjelmakoodista mm. erilaisia luokka hierarkia (kuva 4), funktio kutsu (kuva 5) ja tiedostorakenne kaavioita. Ohjelmisto tarjoaa myös monipuoliset näkymien konfigurointi mahdollisuudet sekä mahdollisuuden navigoida lähdekoodissa ja editoida lähdekoodia suoraan kaavioista. Kuva 4: esimerkki ohjelman luokka hierarkia CC-Riderilla visualisoituna
Ohjelma-analysaattorit 6/9 Kuva 5: esimerkki ohjelman kutsupuu CC-Riderilla visualisoituna 5. Ohjelmakoodin automaattinen dokumentointi Ohjelmakoodin dokumentointi on usein aikaa vievää ja hankalaa. Lisäksi dokumentit vaativat päivityksen aina koodin muuttuessa Syynä heikkoon dokumentointiin on usein sopivien, dokumentointi työtä helpottavien työkalujen puuttuminen. Ohjelmakoodin dokumentointia ja dokumenttien ylläpitoa voidaan helpottaa automaattisilla lähdekoodin dokumentointityökaluilla. Dokumentointityökalut luovat dokumentin ohjelmistosta analysoimalla ohjelmiston lähdekoodin rakennetta. Työkalut osaavat sisällyttää dokumentteihin myös ohjelmoijan koodiin lisäämät kommentit. Osa työkaluista tukee myös erikoiskommenttien käyttöä. Erikoiskommenttien avulla ohjelmakoodiin voidaan sisällyttää lisätietoa dokumentointityökalun käytettäväksi. Ohjelmakoodin automaattiset dokumentointityökalut luovat yleensä hierarkkisia, mahdollisesti hyperlinkitettyjä kuvauksia analysoitavasta koodista. Useimmat dokumentointityökalut tukevat ASCII, RTF, PostScript ja HTML dokumentti formaatteja. Automaattisia lähdekoodin dokumentointi työkaluja on saatavilla useimpiin ohjelmointiympäristöihin.
Ohjelma-analysaattorit 7/9 5.1 CC-Rider CC-Rider ohjelmisto osaa generoida RTF, ASCII, WinHelp ja HTML muotoisia dokumentteja C/C++ lähdekoodista. Ohjelmisto ei vaadi (eikä tue) lähdekoodiin sisällytettäviä erikoiskommentteja. Ohjelmisto kerää automaattisesti lähdekoodista esimerkiksi muuttujien määrittelyjä edeltävät tai samalla rivillä määrittelyn jälkeen olevat kommentit määriteltävän muuttujan dokumentaatioksi. CC-Rider luo dokumentit erilaisten dokumenttipohjien perusteella. Käyttäjä voi määritellä uusia dokumenttipohjia ja muokata ohjelman mukana tulevia pohjia käyttötarkoitukseen sopiviksi. Ohjelmisto osaa dokumentoida funktiot ja niiden parametrit, makrot, tyyppi määritykset (typedefs), luokat, struktuurit, joukot (unions),enumeraatiot, enumeroidut arvot, luokkien jäsenet, ylikuormitetut nimet, luokka ja funktio pohjat (templates), julkiset, yksityiset, perityt ja suojatut jäsenet, jne. Kuvassa 6 on esimerkki erään luokan automaattisesti generoidusta dokumentista. Kuva 6: Esimerkki CC-Riderilla automaattisesti generoidusta dokumentista
Ohjelma-analysaattorit 8/9 6. Yhteenveto Ohjelma-analysaattoreita voidaan käyttää mm. ohjelmakoodin oikeellisuuden tarkistamiseen, ohjelmamittojen analysointiin, ohjelmakoodin visualisointiin ja ohjelmakoodin automaattiseen dokumentointiin. Ohjelmakoodin oikeellisuuden tarkistustyökalut auttavat löytämään ohjelmistosta mahdollisia ohjelmointivirheitä. Ohjelmakoodin oikeellisuuden tarkistustyökaluja voidaan käyttää ohjelmistoprojektin toteutusvaiheessa ohjelmakoodin laadun tarkkailuun ja virheiden poistamiseen. Ohjelmamittojen analysointityökalut laskevat ohjelmakoodista erilaisia mittoja joiden avulla voidaan arvioida esimerkiksi ohjelman kompleksisuutta. Ohjelmamittoja voidaan käyttää ohjelmistoprojekteissa ohjelmakoodin laadunvalvontaan ja verifiointiin esimerkiksi katselmuksissa. Ohjelmakoodin visualisointi- ja rakenteen analysointityökaluilla voidaan ohjelmiston rakenne kuvata graafisessa graafisessa muodossa. Visualisointi- ja rakenteen analysointityökaluista on hyötyä etenkin ohjelmistoprojektin dokumentoinnissa ja ylläpidossa. Ohjelmakoodin automaattiset dokumentointityökalut luovat dokumentin ohjelmistosta analysoimalla ohjelmiston lähdekoodin rakennetta. Automaattisista dokumentointityökaluista on hyötyä etenkin ohjelmiston ylläpidossa. Ohjelmistoon tehdyt muutokset voidaan päivittää dokumentteihin automaattisesti. Tässä esitelmässä mainitut ohjelmat ovat ainoastaan yksittäisiä esimerkkejä erilaisista ohjelma-analysaattoreista. Useimmista esitelmässä mainituista ohjelmista on saatavilla ilmaiset kokeiluversiot.
Ohjelma-analysaattorit 9/9 Lähteet Dar89 Eva00 GIM00 Darwin I., Checking C Programs with lint, O'Reilly & Associates, 1989. Evans D., Annotation-Assisted Lightweight Static Checking, The First International Workshop on Automated Program Analysis, Testing and Verification (ICSE 2000), Feb 2000 Gimpel Software Home Page, <URL:http://www.gimpel.com/index.html> Hal77 Halstead M.H., Elements of Software Science, 1977 LCL00 LCLint Home Page, <URL:http://lclint.cs.virginia.edu/> Orc00 Orcero D. S., The Code Analyser LCLint, Linux Journal, May 2000, <URL: http://www2.linuxjournal.com/lj-issues/issue73/3599.html> POW00 WES00 Power Software - Software Metrics Krakatau for C/C++ and Java, <URL:http://www.powersoftware.com/english/kr/index.html> CC-RIDER C and C++ Source Code Analysis Navigation Documentation and Program Visualization Tool, <URL:http://www.westernwares.com/>