
Preizkus statičnega analizatorja kode je preprost. Vendar pa njegova izvedba, zlasti na velikem, starejšem projektu, zahteva spretnost. Če se je lotimo nepravilno, lahko doda delo, upočasni razvoj in demotivira ekipo. Na kratko si oglejmo, kako pravilno integrirati statično analizo v razvojni proces in jo začeti uporabljati kot del CI/CD.
Predstavitev
Pred kratkim je mojo pozornost pritegnila objava ""Po eni strani je to dober članek, ki ga je vredno prebrati. Po drugi strani pa mislim, da ne ponuja popolnega odgovora na vprašanje, kako brez težav implementirati statično analizo v projektu z veliko starejše kode. Članek nakazuje, da lahko sprejmete tehnični dolg in delate izključno z novo kodo, vendar ne obravnava, kaj storiti s tem tehničnim dolgom pozneje."
Naša ekipa PVS-Studio ponuja svoj pogled na to temo. Poglejmo, kako nastane problem implementacije statičnega analizatorja kode, kako premagati ta izziv in kako neboleče in postopoma odpraviti tehnični dolg.
Problematično
Zagon in ogled delovanja statičnega analizatorja običajno ni težaven [V kodi boste morda opazili zanimive napake ali celo grozljive potencialne ranljivosti. Morda boste celo lahko kaj popravili, a prav tu mnogi programerji obupajo.
Vsi statični analizatorji dajejo lažno pozitivne rezultate. To je značilnost metodologije statične analize kode in glede tega se ne da ničesar storiti. Na splošno je to nerešljiv problem, kar potrjuje Riceov izrek [Tudi algoritmi strojnega učenja ne bodo pomagali []. Če niti oseba ne more vedno ugotoviti, ali je določena koda napačna, potem tega ne smete pričakovati od programa :).
Lažno pozitivni rezultati niso problem, če je statični analizator že konfiguriran:
- Onemogočeni zastareli nabori pravil;
- Nekatere nepomembne diagnostične funkcije so bile onemogočene;
- Če govorimo o jeziku C ali C++, so makri, ki vsebujejo specifične konstrukte, označeni, kar povzroči, da se neuporabna opozorila pojavijo povsod, kjer se takšni makri uporabljajo;
- Označene so lastne funkcije, ki izvajajo dejanja, podobna sistemskim funkcijam (lastni analogni memcpy ali printf) [];
- Lažno pozitivni rezultati so bili posebej onemogočeni z uporabo komentarjev;
- In tako naprej.
V tem primeru lahko pričakujemo nizko stopnjo lažno pozitivnih rezultatov, približno 10–15 % []. Z drugimi besedami, 9 od 10 opozoril analizatorja bo kazalo na resnično težavo v kodi ali vsaj na "vonj po kodi". Strinjate se, takšen scenarij je izjemno prijeten in analizator je pravi prijatelj programerja.

V resnici bo pri velikem projektu začetna slika povsem drugačna. Analizator izda na stotine ali tisoče opozoril v starejši kodi. Nemogoče je hitro ugotoviti, katera od teh opozoril so pomembna in katera ne. Neracionalno je sesti in začeti pregledovati vsa ta opozorila, saj bo to za več dni ali tednov ustavilo glavno delo. Običajno si ekipa takšnega scenarija ne more privoščiti. Prav tako bo ustvarilo ogromno število razlik, ki pokvarijo zgodovino sprememb. Hitro urejanje toliko fragmentov kode naenkrat bo neizogibno povzročilo nove tipkarske napake in napake.
In kar je najpomembneje, takšen podvig v boju proti opozorilom nima veliko smisla. Strinjate se, da če projekt uspešno teče že vrsto let, je večina kritičnih napak že odpravljenih. Da, ti popravki so bili zelo dragi, zahtevali so odpravljanje napak, prejemanje negativnih povratnih informacij uporabnikov o hroščih in tako naprej. Statični analizator bi pomagal odpraviti številne od teh napak v fazi kodiranja, hitro in poceni. Toda trenutno so te napake tako ali drugače odpravljene, analizator pa v glavnem zazna nekritične napake v stari kodi. Ta koda se morda ne uporablja ali se uporablja zelo redko, napaka v njej pa morda nima opaznih posledic. Morda je senca gumba nekje napačne barve, vendar to ne ovira nikogaršnje uporabe izdelka.
Seveda so tudi manjše napake še vedno napake. In včasih lahko napaka skriva resnično ranljivost. Vendar se zdi dvomljiva ideja, da bi vse zavrgli in porabili več dni ali tednov za reševanje napak, ki se komaj pojavijo.
Programerji strmijo in strmijo v vsa ta opozorila v svoji stari, delujoči kodi ... In si mislijo: brez statične analize bomo shajali. Napišimo raje kakšno novo, uporabno funkcionalnost.
Po svoje imajo prav. Verjamejo, da se morajo najprej nekako znebiti vseh teh opozoril. Šele nato bodo lahko imeli koristi od redne analize kode. Sicer bodo nova opozorila preprosto preglasila starejša in nihče jim ne bo posvečal pozornosti.
Analogija je tukaj enaka kot pri opozorilih prevajalnika. Ni brez razloga priporočljivo, da število opozoril prevajalnika ostane na 0. Če je opozoril 1000, potem ko jih je 1001, nihče ne bo pozoren in ni jasno, kje iskati to najnovejše opozorilo.

Najhuje v tej situaciji je, če nekdo višje na tej točki vsili uporabo statične analize kode. To ekipo le demotivira, saj z njihovega vidika dodaja dodatno birokratsko zapletenost, ki le ovira napredek. Nihče ne bo gledal poročil analizatorja in vsa uporaba bo "na papirju". Z drugimi besedami, analiza je formalno integrirana v proces DevOps, vendar v praksi ne prinaša nobene koristi nikomur. Slišali smo podrobne zgodbe udeležencev konferenc, ko so govorili na stojnicah. Takšne izkušnje lahko programerje odvrnejo od uporabe orodij za statično analizo za dolgo časa, če ne za vedno.
Izvajanje in odprava tehničnega dolga
Pravzaprav ni nič zapletenega ali strašljivega pri izvajanju statične analize niti v velikem starem projektu.
CI / CD
Poleg tega je analizator mogoče takoj integrirati v vaš proces neprekinjenega razvoja. Distribucija PVS-Studio na primer vključuje pripomočke za priročen ogled poročila v želeni obliki, pa tudi obvestila za razvijalce, ki so napisali problematične dele kode. Za tiste, ki jih zanimajo podrobnejše informacije o zagonu PVS-Studio iz sistemov CI/CD, priporočam branje ustrezne dokumentacije. dokumentacija in serija člankov:
Vrnimo se k vprašanju velikega števila lažno pozitivnih rezultatov v zgodnjih fazah uvajanja orodij za analizo kode.
Odpravljanje obstoječega tehničnega dolga in obravnavanje novih opozoril
Sodobni komercialni statični analizatorji analizirajo le nova opozorila, ki se pojavijo v novi ali spremenjeni kodi. Implementacije tega mehanizma se razlikujejo, vendar je bistvo enako. V statičnem analizatorju PVS-Studio je ta funkcionalnost implementirana na naslednji način.
Za hiter začetek uporabe statične analize uporabnikom PVS-Studio ponujamo mehanizem za preprečevanje množičnih opozoril []. Splošna ideja je naslednja. Uporabnik je zagnal analizator in prejel številna opozorila. Ker je projekt v razvoju že vrsto let, je aktiven, raste in ustvarja prihodek, poročilo verjetno ne bo vsebovalo veliko opozoril, ki kažejo na kritične napake. Z drugimi besedami, kritične napake so bile že odpravljene, tako ali drugače, z dražjimi sredstvi ali po zaslugi povratnih informacij strank. V skladu s tem lahko vse, kar analizator trenutno najde, štejemo za tehnični dolg, ki ga ni praktično takoj odpraviti.
PVS-Studio lahko naročite, naj ta opozorila zaenkrat obravnava kot nepomembna (tehnični dolg preložite na pozneje) in jih ne bo več prikazoval. Analizator ustvari posebno datoteko, v kateri shrani informacije o trenutno nezanimivih napakah. Zdaj bo PVS-Studio izdajal opozorila le za novo ali spremenjeno kodo. Poleg tega je vse to inteligentno izvedeno. Če se na primer na začetek datoteke z izvorno kodo doda prazna vrstica, analizator razume, da se v bistvu ni nič spremenilo, in bo ostal tiho. To označevalno datoteko je mogoče dodati v sistem za nadzor različic. Datoteka je velika, vendar to ni problem, saj je ni smiselno pogosto dodajati.
Zdaj bodo vsi programerji videli opozorila, povezana le z novo ali spremenjeno kodo. To pomeni, da lahko analizator začnejo uporabljati že naslednji dan, če se tako izrazimo. Tehnični dolg se lahko obravnava kasneje, napake pa postopoma odpravlja in analizator se izpopolnjuje.
Torej, prva težava z implementacijo analizatorja v velik, zastarel projekt je rešena. Zdaj pa ugotovimo, kaj storiti s tehničnim dolgom.
Odpravljanje napak in refaktoriranje
Najenostavnejša in najbolj naravna stvar je, da si vzamete nekaj časa za pregled množično potlačenih opozoril analizatorja in jih postopoma odpravite. Nekatere napake v kodi je treba odpraviti, druge pa zahtevajo refaktoriranje, da analizatorju sporočite, da koda ni problematična. Preprost primer:
if (a = b)Večina prevajalnikov in analizatorjev C++ se pritožuje nad tovrstno kodo, saj obstaja velika verjetnost, da so jo dejansko želeli napisati (a == b)Vendar pa obstaja neizrečen dogovor, ki je običajno naveden v dokumentaciji, da če so prisotni dodatni oklepaji, se domneva, da je programer namerno napisal kodo na ta način in ni razloga za pritožbo. Na primer, v dokumentaciji PVS-Studio za diagnostiko Jasno je zapisano, da bo naslednja vrstica veljala za pravilno in varno:
if ((a = b))Še en primer. Ali je v tej kodi C++ kaj pozabljenega? odmor ali ne?
case A:
foo();
case B:
bar();
break;Analizator PVS-Studio bo tukaj izdal opozorilo. To morda ni napaka, zato morate razčlenjevalniku dati namig z dodajanjem atributa ali na primer __attribute__((prepad)):
case A:
foo();
[[fallthrough]];
case B:
bar();
break;Lahko bi rekli, da takšne spremembe kode ne odpravljajo hroščev. Da, to je res, vendar naredijo dve dobri stvari. Prvič, poročilo analizatorja odstrani lažno pozitivne rezultate. Drugič, koda postane bolj razumljiva za ljudi, ki jo vzdržujejo. In to je ključnega pomena! Že samo to naredi manjše refaktoriranje smiselno, saj koda postane jasnejša in lažje vzdrževana. Če analizator ne razume, ali je potreben "prelom", to ne bo jasno tudi vašim kolegom programerjem.
Poleg popravkov napak in preoblikovanja lahko selektivno preprečite očitno lažna opozorila analizatorja. Nekatere nepomembne diagnostične funkcije je mogoče onemogočiti. Na primer, nekateri ljudje menijo, da so opozorila nesmiselna. o primerjavi vrednosti float/double. Nekateri jih imajo za pomembne in vredne preučevanja [Razvojna ekipa mora odločiti, katera opozorila se štejejo za pomembna in katera ne.
Obstajajo tudi drugi načini za preprečevanje lažno pozitivnih rezultatov. Na primer, označevanje makrov je bilo omenjeno že prej. Vse to je podrobneje opisano v dokumentaciji. Najpomembneje je razumeti, da če se lažno pozitivnih rezultatov lotevate postopoma in sistematično, niso velika težava. Velika večina nepomembnih opozoril po konfiguraciji izgine, tako da ostanejo le tista področja, ki resnično zahtevajo skrben pregled in nekaj sprememb kode.
Strankam vedno pomagamo tudi pri konfiguraciji PVS-Studia, če se pojavijo kakršne koli težave. Poleg tega smo že sami odpravili lažne pozitivne rezultate in napake.]. Za vsak slučaj sem se odločil omeniti, da je možna tudi ta možnost podaljšanega sodelovanja :).
Ratchet metoda
Obstaja še en zanimiv pristop k postopnemu izboljševanju kakovosti kode z odpravo opozoril statičnega analizatorja. Ideja je, da se število opozoril lahko le zmanjšuje.

Zabeleženo je število opozoril, ki jih ustvari statični analizator. Vrata kakovosti so konfigurirana tako, da je mogoče vstaviti le kodo, ki ne poveča števila opozoril. To sproži postopek postopnega zmanjševanja števila opozoril s konfiguriranjem analizatorja in odpravljanjem napak.
Tudi če se nekdo odloči za malo goljufanja in prestane preverjanje kakovosti ne z odpravo opozoril v svoji novi kodi, temveč z izboljšanjem stare kode tretjih oseb, to ni nič takega. Ročica se še vedno vrti v eno smer in število napak se bo postopoma zmanjševalo. Tudi če nekdo ne želi popraviti svojih novih napak, bo moral še vedno izboljšati nekaj v sosednji kodi. Na neki točki se bodo preprosti načini za zmanjšanje opozoril izčrpali in pride čas, ko bodo prave napake odpravljene.
Ta metodologija je podrobneje opisana v zelo zanimivem članku Ivana Ponomareva "", ki ga priporočam vsem, ki jih zanima izboljšanje kakovosti kode.
Avtor članka ima tudi poročilo na to temo: "".
Zaključek
Upam, da bo ta članek bralce spodbudil k boljši uporabi orodij za statično analizo in jih motiviral, da jih vključijo v svoj razvojni proces. Če imate kakršna koli vprašanja, vam bomo vedno z veseljem odgovorili. uporabnikom našega statičnega analizatorja PVS-Studio in pomoč pri njegovi implementaciji.
Obstajajo tudi drugi pogosti dvomi o tem, ali je statična analiza resnično priročna in uporabna. Večino teh dvomov sem poskušal razbliniti v publikaciji "Razlogi za implementacijo statičnega analizatorja kode PVS-Studio v vaš razvojni proces" [].
Hvala za vašo pozornost in pridite in preizkusite analizator PVS-Studio.
Dodatne povezave
- Andrej Karpov.
- Wikipedia. .
- Andrej Karpov, Viktorija Khanieva. .
- PVS-Studio. Dokumentacija. .
- Andrej Karpov. .
- PVS-Studio. Dokumentacija. .
- Ivan Andrjašin. .
- Pavel Eremejev, Svjatoslav Razmislov. .
- Andrej Karpov. .
Če želite ta članek deliti z angleško govorečim občinstvom, uporabite povezavo za prevod: Andrey Karpov. .
Vir: www.habr.com
