Analýza zdrojového kódu zefektivňuje vývoj softwaru

Vysoce škálovatelné softwarové systémy představují pro všechny, kdo se na jejich vývoji podílejí, enormně komplexn...


Vysoce škálovatelné softwarové systémy představují pro všechny, kdo se na
jejich vývoji podílejí, enormně komplexní projekty. Chyby jsou v této sféře
nevyhnutelným zlem a už po desítky let se všichni odborníci ze softwarové
oblasti pokoušejí hledat metody, jak s nimi účinně bojovat. Ačkoliv ve svém
životě se možná nikdy s perfektním zdrojovým kódem nesetkáte, je příjemné
vědět, že na cestě jsou mnohem lepší analytické nástroje a slibné nové
přístupy, které mohou pomoci tento problém napravit.
Metoda označovaná jako Test-Driven Development (TDD, vývoj řízený testováním)
je jedním z populárních nových přístupů ke hledání programových chyb. Může s
sebou nicméně nést značnou režii, neboť nezbytný testovací framework, který
zajišťuje korektnost programu, může vyžadovat i tolik řádků kódu, jako samotný
program. Další z populárních metod je Run-Time Checking (RTC, kontrola běhu
programu). Vkládáním speciálních měřicích nástrojů do programů nebo zachycením
volání API jsou produkty typu Rational Purify společnosti IBM nebo
BoundsChecker firmy Compuware schopny najít problematická místa, jako je
korupce paměti, únik zdrojů nebo chybné využití služeb operačního systému.
Metody TDD a RTC jsou obě velmi užitečnými a vzájemně se doplňujícími
technikami. Ale konec konců, všechny chyby se nacházejí ve zdrojovém kódu.
Ačkoliv je pro programátory vždy důležité, aby prováděli revizi svého vlastního
kódu (nebo tak činili i navzájem mezi sebou), úplná a komplexní analýza si žádá
automatizaci.
Objevující se nástroje či akcelerace na poli výzkumu nových metod jsou přitom
předzvěstí zajímavé budoucnosti softwarového vývoje. Zajímavou a přesvědčivou
demonstrací možností a výhod automatické analýzy zdrojového kódu je databáze
linuxových bugů společnosti Coverity. Je možné si ji prohlédnout také on-line
(li nuxbugs.coverity.com). Například v dubnu byla užitečná při identifikaci
stovek chyb ve zdrojovém kódu Linuxu verze 2.6. Analyzátor firmy Coverity
označovaný SWAT (Software Analysis Toolset) vznikl na základě výzkumu profesora
Dawsona Englera ze Stanfordu, který externě působí jako vědecký šéf v Coverity.
Společnost Microsoft chystá ve světě Windows také něco nového: Statický
analyzátor zdrojového kódu s názvem PREfast, který je již léta interně využíván
v samotném Microsoftu, bude začleněn do sady Visual Studio 2005 Team System.
PREfast je modernizovanou verzí výkonného analyzátoru PREfix, komerčního
produktu, který koncem 90. let nabízela firma Intrinsa. Tu Microsoft získal v
roce 1999 a technologii začal nejprve využívat ve svém středisku Programmer
Productivity Research Centrer.

Proč právě teď?
Analyzátory kódu jako takové vlastně nepředstavují nic nového. Jejich původ
sahá až k nástroji Lint z raných 70. let, který programátorům umožňoval
vyhledávat běžné chyby v programech psaných v jazyce C. Současné obnovení zájmu
o tyto pozoruhodné techniky pobízí experty k tomu, aby nabídli několik možných
vysvětlení.
Brian Chess, vedoucí výzkumu ve společnosti Fortify Software, jejíž analyzátor
je specializován na detekci bezpečnostních slabin ve zdrojovém kódu v jazycích
C, C++, Java, JSP a PL/SQL, si myslí, že takovou analýzu dnes činí zcela
nezbytnou součástí vývoje zejména obavy a požadavky týkající se bezpečnosti.
Mnohých chyb v C a C++ si je běžný smrtelník stěží schopen povšimnout, avšak
pro automatizované analyzátory je jejich nalezení relativně jednoduché to se
týká třeba správy paměti. Například přetečení paměti (buffer overflow) v době,
kdy počítače ještě nebyly permanentně propojeny s okolním světem internetu,
sice znamenalo nepříjemný nedostatek, ovšem ne nutně přímo katastrofu. Nicméně
dnes je právě tento typ chyb útočníky zcela běžně využíván, takže je více než
žádoucí se jich vyvarovat.
Engler je nicméně přesvědčen, že objasnění založené na argumentech bezpečnosti
je třeba brát se špetkou skepse. Jeho výzkumy na konci 90. let byly zaměřeny na
zlepšení spolehlivosti softwaru. "Bezpečnostní analýza byla jednou z jejich
součástí," říká, "avšak v podstatě nám šlo zejména o stabilitu systémů."
Dalším z faktorů, který pohání analýzu zdrojového kódu kupředu, je Moorův zákon
důkladná či přímo vyčerpávající analýza kódu může vést ke značné spotřebě
výpočetních zdrojů. Například v Microsoftu vykonává PREfix hlubokou analýzu
milionů řádků C a C++ kódu, avšak může ji provádět pouze nepříliš často jakožto
součást centralizovaných build procesů (procesů realizace jednotlivých verzí
kódu). K rutinním denním kontrolám vývojáři typicky využívají PREfast, na
zdroje méně náročný protějšek PREfixu.
Ovšem s tím, jak dostupný hrubý výpočetní výkon v poslední době roste, je možné
jej více obětovat pro verifikaci programu. Engler poznamenává, že rychlejší CPU
mohou vést k opomíjení optimalizace, na niž se tradičně zaměřovali
profesionálové zabývající se kompilací kódu. "Současně se zužováním řady
aplikací, které z optimalizace těží," upozorňuje, "se objevují tlaky hledat
nějaké jiné oblasti zájmu."
Chess z firmy Fortify si myslí, že došlo k fundamentálnímu filozofickému posunu
v přístupu k problematice analýzy kódu. "Dříve věnovali odborníci pozornost
především korektnosti programu," říká. "Cílem bylo dokázat, že program bude za
všech podmínek pracovat tak, jak by měl." Nyní se podle něj důraz přesunul
směrem ke snáze zvládnutelné formě testování, spočívající v tom, že "existují
specifické vlastnosti, které daný program nemá mít". Příkladem takových
vlastností je zmíněná možnost přetečení zásobníku nebo výskyt mrtvých bodů
(které mohou způsobit zablokování systému).
Chris Lucas, manažer Microsoftu v oblasti skupinových programů pro Visual
Studio Team Developer Edition, si myslí, že namísto lepších technik jsou dnes
tím, co vede k vyšší účinnosti analýzy zdrojového kódu, především lepší
pravidla. Podobně jako rozbor linuxového kódu pomocí nástrojů firmy Coverity i
analýza kódu pod Windows prováděná Microsoftem se ukazuje být efektivním
způsobem vedoucím k vyčištění chyb. Sada pravidel používaných v rámci firmy se
vyvinula cestou postupných iterací.
"Specialisté v PPRC (Programmer Productivity Research Center) nejdříve
identifikovali některá zajímavá pravidla," popisuje Lucas, "a ta byla poté
aplikována na zdrojovou bázi Windows." Pravidla, která umožnila nalezení
důležitých nedostatků bez toho, aby způsobila přílišný "šum", byla kodifikována
a následně cyklicky opakovaně uplatňována. "Jde tedy především o vyladění sady
vhodných pravidel," vysvětluje Lucas.
Benjamin Chelf, který studoval u Englera a nyní je hlavním analytikem v
Coverity, souhlasí s tím, že dnešní analyzátor už nepřipomíná zastaralé metody.
"Nejde jen o další nástroj, který neustále chrlí zbytečná varování," říká.
Nalezení odpovídající úrovně analýzy bylo pro nástroje, jež rozbor kódu
provádějí, vždy klíčovým úkolem. Při příliš malé přesnosti může takový nástroj
vývojáře zaplavit chybnými výsledky testů, zatímco při příliš vysoké úrovni
přesnosti by mohlo trvat léta, než bude analýza dokončena. Naštěstí se však
evoluce v posledních letech značně urychlila. "Řešení se dostávají do správné
rovnováhy," tvrdí Chelf a doporučuje vývojářům, aby zkusili přehodnotit své
dosavadní domněnky a předpoklady.

Různé tempo
Všichni se shodují na tom, že moderní metody analýzy zdrojového kódu vedou ke
zlepšení kvality softwaru. Nicméně jednotlivé techniky se odlišují s ohledem na
rozsah analýzy a množství specifických znalostí týkajících se operačních
systémů a aplikačních frameworků, které nástroj pro vykonání této úlohy využívá.
Nejsilnější formou co do rozsahu je globální analýza tzn. interprocedurální.
Jde o to, zda jsou vzory detekované v jedné funkci nebo metodě korelovány se
vzory nacházejícími se kdekoliv v programu. Analyzátor sleduje tok dat v celém
programu, vytváří si model programu a simuluje cesty jeho provádění. Do této
kategorie spadají nástroje Coverity a Fortify, stejně jako PREfix,
centralizovaný analyzátor Microsoftu.
Desktopová verze nástroje Microsoftu, PREfast, je naproti tomu
intraprocedurálním analyzátorem, který je zaměřen na lokální porovnávání vzorů.
Programátoři nicméně mohou okomentovat funkce použitím jazyka SAL (Structured
Annotation Language), což je notace umožňující PREfastu provádět mocnější
interprocedurální rozbor. Dalším z analyzátorů provádějících porovnávání vzorů
je ten, který je začleněn v produktu DevPartner Studio firmy Compuware. Jeho
doménou analýzy je VB .Net a C#.
Analýza, která pojme celý rozsah či rámec programu, stále těží ze znalostí
prostředí (či kontextu), ve kterém běží. Nástroj Fortify při sledování
například postupuje od javových metod k uloženým procedurám databáze a pak zase
zpátky. "Konvenční přístupy říkají, že pokud používáte vazby parametrů
(parameter binding), nestane se váš systém obětí útoku typu SQL Injection při
němž jsou do SQL dotazu vkládána nevhodná data," říká Chess. Avšak vzhledem k
tomu, že vložené procedury jsou také schopny sestavovat SQL kód, jsou do
analýzy rovněž zahrnuty. Podobně Fortify sleduje i interakci programů s jejich
XML konfiguračními soubory. "Jestliže konfigurační soubory ,nesešijete
dohromady kódem," upozorňuje Chess, "nikdy nemůžete vědět, jak se bude program
chovat."
Přístup Coverity klade naproti tomu na vlastnosti a znalosti specifické
platformy menší důraz. S použitím statistické analýzy vzorů nalezených v
programu vyvozuje, že určité odchylky od standardu jsou pravděpodobně chybami.
Pro ilustraci Engler popisuje druhy pravidel, která jsou v programech
implicitní: "Jestliže provedete A, pak musíte provést B. V kontextu X nikdy
nelze provést Y." Jak automatická dedukce pracuje? "Spočítejte si, jak často po
A následuje B, oproti tomu, kolikrát se A objevuje osamoceně," říká Engler.
"Jestliže zjistíte, že A a B se v tisíci případů vyskytují společně a jednou
nikoliv, můžete si být téměř jisti, že ten jediný případ bude znamenat chybu."
Lucas z Microsoftu přijímá obě zmíněné strategie. PREfast a jeho doprovodný
nástroj FxCop, který pracuje s jazyky platformy .Net vyrostl na základě studií
Microsoftu týkajících se jeho vlastních programovacích praktik. Některé z
pravidel, která se objevila, jsou silně specifická pro danou doménu popisují
korektní použití API a frameworků atd. "V oblasti platformy .Net například
FxCop vyhledává problémy týkající interoperability COM, běžné bezpečnostní
nedostatky a obvyklé chyby, jež vedou ke špatnému výkonu při běhu kódu," říká
Lucas.
Analyzátor Compuwaru vykonává podobné typy kontroly. Pravidlo označované "open
to file path hacking" kupříkladu zaručuje, že jestliže je zabezpečená cesta
souborového systému, pak je bezpečná i UNC (Universal Naming Convention) cesta.

Tvorba pravidel
Obecně vzato mají analyzátory pro Javu a .Net tendence zaměřovat se na
specifické problémy dané domény. To proto, že chyby vztahující ke špatnému
použití paměti, které poutají zájem u C a C++ nástrojů, neboť činí programy
psané v těchto jazycích nestabilní a náchylné k napadení, se v prostředí
řízeného kódu většinou nevyskytují. To ale neznamená, že zde nemohou nastat
žádné komplikace týkající se správy paměti, jimž je třeba věnovat pozornost. V
řízených programech může například stále docházet k únikům paměti (pro některé
objekty), avšak důraz se zde přesunuje především k vyšší úrovni analýzy.
V srdci každého analyzátoru zdrojového kódu jsou implementována pravidla, která
popisují vzory odpovídající určitým chybám. Nástroje zpravidla poskytují
obecnou sadu pravidel a typicky uživatelům, resp. vývojářům, navíc umožňují
přidávat pravidla nová, s nimiž jsou kodifikovány znalosti týkající se jejich
vlastních systémů i programátorských praktik.
O pravidla, jež posuzují vzory v textu zdrojového kódu, může být rozšířen i
analyzátor používaný v DevPartner Studiu od Compuwaru. Podle produktového
manažera Petera Varhola je tato technika často využívána pro prosazení či
vynucení pravidel týkajících se stylu psaní kódu. K témuž účelu využívá nástroj
firmy Coverity jazyk MetaL určený ke psaní pravidel.
Fortify rovněž podporuje uživatelsky psaná pravidla. "Je rozhodující," říká
Chess, "aby zákazníci, kteří nechtějí odkrýt některé proprietární detaily
týkající se jejich systémů, byli schopni pracovat nezávisle, potřebují-li
rozšířit rozsah analýzy." PREfast, s těsnou vazbou na kompilátor Microsoftu,
uživatelská pravidla nepodporuje, avšak FxCop ano, a to s využitím jazyků
platformy .Net při psaní těchto pravidel.
Je možné, že se dočkáme standardního způsobu, jak reprezentovat taková
pravidla, který by umožnil přímé srovnání analyzátorů a sdílení znalostí o
běžně se vyskytujících vzorech? Teoreticky ano, v praxi se to však zdá být v
dohledné době spíše nepravděpodobné.
Rozšiřitelnost je důležitá, nicméně dodavatelé analyzátorů zdrojového kódu se
dnes soustřeďují na něco jiného. Musejí se nejprve snažit přesvědčit
programátory, aby změnily pohled na relativně novou kategorii nástrojů, které
mnozí z nich dosud při své práci zavrhovali coby irelevantní. Vyzkoušejte je,
nabádají výrobci, ať zjistíte, jestli takové vyšetření vašeho zdrojového kódu
vedlo k identifikaci významných chyb, které byste jinak nenašli.









Komentáře
K tomuto článku není připojena žádná diskuze, nebo byla zakázána.