Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe

Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe
Enostavno je preizkusiti statični analizator kode. Toda za njegovo izvajanje, zlasti pri razvoju velikega starega projekta, je potrebna spretnost. Če je izveden nepravilno, lahko analizator doda delo, upočasni razvoj in demotivira ekipo. Na kratko se pogovorimo o tem, kako pravilno pristopiti k integraciji statične analize v razvojni proces in jo začeti uporabljati kot del CI/CD.

Predstavitev

Pred kratkim je mojo pozornost pritegnila publikacija "Kako začeti s statično analizo brez preobremenjenosti ekipe". Po eni strani je to dober članek, s katerim se je vredno seznaniti. Po drugi strani pa se mi zdi, da še vedno ne daje popolnega odgovora, kako neboleče implementirati statično analizo v projekt z veliko Članek pravi, da lahko sprejmete tehnični dolg in delate samo na novi kodi, ni pa odgovora, kaj storiti s tem tehničnim dolgom pozneje.

Naša ekipa PVS-Studio ponuja svoj pogled na to temo. Poglejmo, kako sploh nastane problem implementacije statičnega analizatorja kode, kako to težavo premagati in kako neboleče postopoma odpraviti tehnični dolg.

Problematično

Običajno ni težko zagnati in videti, kako deluje statični analizator [1]. V kodi boste morda videli zanimive napake ali celo grozljive potencialne ranljivosti. Lahko celo kaj popraviš, potem pa mnogi programerji obupajo.

Vsi statični analizatorji proizvajajo lažno pozitivne rezultate. To je značilnost metodologije analize statične kode in glede tega ni mogoče storiti ničesar. V splošnem primeru je to nerešljiv problem, kar potrjuje Riceov izrek [2]. Tudi algoritmi strojnega učenja ne bodo pomagali [3]. Tudi če oseba ne more vedno ugotoviti, ali je ta ali ona koda napačna, potem tega ne smete pričakovati od programa :).

Lažni pozitivni rezultati niso problem, če je statični analizator že konfiguriran:

  • Onemogočeni nepomembni nizi pravil;
  • Nekatere nepomembne diagnostike so bile onemogočene;
  • Če govorimo o C ali C++, potem so označeni makri, ki vsebujejo specifične konstrukte, zaradi katerih se neuporabna opozorila pojavljajo na vsakem mestu, kjer so takšni makri uporabljeni;
  • Označene so lastne funkcije, ki izvajajo dejanja, podobna sistemskim funkcijam (lastni analog memcpy ali printf) [4];
  • Lažni pozitivni rezultati so posebej onemogočeni z uporabo komentarjev;
  • In tako naprej.

V tem primeru lahko pričakujemo nizko lažno pozitivno stopnjo približno 10-15 % [5]. Z drugimi besedami, 9 od 10 opozoril analizatorja bo nakazovalo resnično težavo v kodi ali vsaj »kodo z močnim vonjem«. Strinjam se, ta scenarij je izjemno prijeten, analizator pa je pravi prijatelj programerja.

Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe
V resnici bo pri velikem projektu začetna slika povsem drugačna. Analizator izda na stotine ali tisoče opozoril za podedovano kodo. Nemogoče je hitro razumeti, katera od teh opozoril so pomembna in katera ne. Neracionalno je sedeti in se začeti ukvarjati z vsemi temi opozorili, saj se bo glavno delo v tem primeru ustavilo za dneve ali tedne. Običajno si ekipa ne more privoščiti takšnega scenarija. Ogromno bo tudi razlik, ki kvarijo zgodovino sprememb. In hitro množično urejanje toliko fragmentov v kodi bo neizogibno povzročilo nove tipkarske napake in napake.

In kar je najpomembneje, takšen podvig v boju proti opozorilom nima veliko smisla. Strinjam se, da ker projekt uspešno teče že vrsto let, je večina kritičnih napak v njem že odpravljenih. Da, ti popravki so bili zelo dragi, morali so jih odpraviti, prejeli so negativne povratne informacije uporabnikov o napakah in tako naprej. Statični analizator bi pomagal odpraviti veliko teh napak v fazi kodiranja, hitro in poceni. Toda trenutno so te napake tako ali drugače odpravljene in analizator zaznava predvsem nekritične napake v stari kodi. Ta koda se ne sme uporabljati, lahko se uporablja zelo redko in napaka v njej morda ne bo povzročila opaznih posledic. Morda je nekje senca od gumba napačne barve, vendar to nikogar ne moti pri uporabi izdelka.

Seveda so tudi manjše napake še vedno napake. In včasih lahko napaka skrije resnično ranljivost. Vendar je opustiti vse in se dneve/tedne ukvarjati z okvarami, ki se komaj pokažejo, videti kot dvomljiva ideja.

Programerji gledajo, gledajo, gledajo vsa ta opozorila o stari delovni kodi ... In si mislijo: lahko brez statične analize. Napišimo nekaj novih uporabnih funkcij.

Po svoje imajo prav. Ugotovijo, da se morajo najprej nekako znebiti vseh teh opozoril. Le tako bodo lahko imeli koristi od redne uporabe analizatorja kod. V nasprotnem primeru se bodo nova opozorila preprosto utopila v starih in nihče ne bo pozoren nanje.

To je ista analogija kot pri opozorilih prevajalnika. Ni brez razloga, da priporočajo ohranjanje števila opozoril prevajalnika na 0. Če je opozoril 1000, potem ko jih bo 1001, nihče ne bo pozoren na to in ni jasno, kje iskati to najnovejše opozorilo.

Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe
Najhuje v tej zgodbi je, če te nekdo od zgoraj v tem trenutku prisili k uporabi statične analize kode. To bo samo demotiviralo ekipo, saj bodo z njihovega vidika dodatne birokratske zaplete le v napoto. Nihče ne bo gledal poročil analizatorja in vsa uporaba bo le "na papirju". Tisti. Formalno je analiza vgrajena v proces DevOps, a v praksi to nikomur ne koristi. Na stojnicah smo slišali podrobne zgodbe udeležencev konference. Takšna izkušnja lahko programerje odvrne od uporabe orodij za statično analizo za dolgo časa, če ne za vedno.

Izvedba in odprava tehničnega dolga

Pravzaprav ni nič težkega ali strašljivega pri uvedbi statične analize tudi v velik star projekt.

CI / CD

Poleg tega lahko analizator takoj postane del stalnega razvojnega procesa. Na primer, distribucija PVS-Studio vsebuje pripomočke za udoben ogled poročila v obliki, ki jo potrebujete, in obvestila razvijalcem, ki so napisali problematične dele kode. Za tiste, ki jih bolj zanima zagon PVS-Studio iz sistemov CI/CD, priporočam, da se seznanite z ustreznimi razdelek dokumentacijo in vrsto člankov:

Toda vrnimo se k vprašanju velikega števila lažnih pozitivnih rezultatov na prvih stopnjah implementacije orodij za analizo kode.

Odpravljanje obstoječega tehničnega dolga in obravnavanje novih opozoril

Sodobni komercialni statični analizatorji vam omogočajo, da preučujete samo nova opozorila, ki se pojavijo v novi ali spremenjeni kodi. Izvedba tega mehanizma je različna, 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 predlagamo uporabo mehanizma za množično zatiranje opozoril [6]. Splošna ideja je naslednja. Uporabnik je zagnal analizator in prejel veliko opozoril. Ker je projekt, ki je bil v razvoju že več let, živ, se razvija in služi denar, potem najverjetneje v poročilu ne bo veliko opozoril, ki bi kazala na kritične napake. Z drugimi besedami, kritične napake so bile tako ali drugače že odpravljene z dražjimi metodami ali zahvaljujoč povratnim informacijam strank. V skladu s tem se lahko vse, kar analizator trenutno najde, šteje za tehnični dolg, ki ga je nepraktično poskušati takoj odpraviti.

PVS-Studio lahko naročite, naj ta opozorila zaenkrat šteje za nepomembna (tehnični dolg prihranite za pozneje) in jih ne bo več prikazoval. Analizator ustvari posebno datoteko, kamor shrani informacije o napakah, ki še niso zanimive. Zdaj bo PVS-Studio izdal opozorila samo za novo ali spremenjeno kodo. Poleg tega je vse to pametno izvedeno. Če je na primer na začetek datoteke izvorne kode dodana prazna vrstica, potem analizator razume, da se dejansko ni nič spremenilo, in bo še naprej tiho. To označevalno datoteko je mogoče vnesti v sistem za nadzor različic. Datoteka je velika, vendar to ni problem, saj je nima smisla pogosto shranjevati.

Zdaj bodo vsi programerji videli opozorila, povezana samo z novo ali spremenjeno kodo. Tako lahko začnete uporabljati analizator, kot pravijo, od naslednjega dne. Pozneje se lahko vrnete k tehničnemu dolgu in postopoma popravite napake ter konfigurirate analizator.

Tako je bila prva težava pri implementaciji analizatorja v velik stari projekt rešena. Zdaj pa ugotovimo, kaj storiti s tehničnim dolgom.

Popravki napak in preoblikovanje

Najenostavnejša in najbolj naravna stvar je, da si vzamete nekaj časa za analizo množično potlačenih opozoril analizatorja in se postopoma spopadete z njimi. Nekje bi morali popraviti napake v kodi, nekje bi morali narediti refaktor, da bi analizatorju povedali, da koda ni problematična. Preprost primer:

if (a = b)

Večina C++ prevajalnikov in analizatorjev se pritožuje nad takšno kodo, saj obstaja velika verjetnost, da so dejansko želeli pisati (a == b). Vendar obstaja neizgovorjen dogovor, in to je običajno navedeno v dokumentaciji, da če obstajajo dodatni oklepaji, se šteje, da je programer namerno napisal takšno kodo in ni treba priseči. Na primer v dokumentaciji PVS-Studio za diagnostiko V559 (CWE-481) jasno je zapisano, da bo naslednja vrstica pravilna in varna:

if ((a = b))

Še en primer. Je to pozabljeno v tej kodi C++? odmor ali ne?

case A:
  foo();
case B:
  bar();
  break;

Analizator PVS-Studio bo tukaj izdal opozorilo V796 (CWE-484). To morda ni napaka, v tem primeru morate razčlenjevalniku dati namig z dodajanjem atributa [[padejo skozi]] ali na primer __atribut__((fallthrough)):

case A:
  foo();
  [[fallthrough]];
case B:
  bar();
  break;

Lahko rečemo, da takšne spremembe kode ne odpravijo napake. Da, to je res, vendar naredi dve koristni stvari. Prvič, poročilo analizatorja se znebi lažnih pozitivnih rezultatov. Drugič, koda postane bolj razumljiva za ljudi, ki sodelujejo pri njenem vzdrževanju. In to je zelo pomembno! Samo zaradi tega se splača izvesti manjša preoblikovanja, da bo koda jasnejša in lažja za vzdrževanje. Ker analizator ne razume, ali je "break" potreben ali ne, bo tudi kolegom programerjem nejasno.

Poleg popravkov napak in refaktoriranja lahko posebej preprečite očitno lažna opozorila analizatorja. Nekatere nepomembne diagnostike je mogoče onemogočiti. Na primer, nekdo misli, da so opozorila nesmiselna V550 o primerjavi vrednosti float/double. In nekateri jih uvrščajo med pomembne in vredne preučevanja [7]. Katera opozorila se štejejo za ustrezna in katera ne, se odloči razvojna ekipa.

Obstajajo tudi drugi načini za preprečevanje lažnih opozoril. Prej je bila na primer omenjena makro oznaka. Vse to je podrobneje opisano v dokumentaciji. Najpomembneje je razumeti, da če postopoma in sistematično pristopite k delu z lažnimi pozitivnimi rezultati, z njimi ni nič narobe. Velika večina nezanimivih opozoril po konfiguraciji izgine in ostanejo le mesta, ki resnično zahtevajo natančno preučitev in nekaj sprememb v kodi.

Prav tako našim strankam vedno pomagamo nastaviti PVS-Studio, če se pojavijo kakršne koli težave. Poleg tega so bili primeri, ko smo sami odpravili lažna opozorila in popravili napake [8]. Za vsak slučaj sem se odločil omeniti, da je možna tudi ta opcija za podaljšanje sodelovanja :).

Ratchet metoda

Obstaja še en zanimiv pristop za postopno izboljšanje kakovosti kode z odpravo opozorila statičnega analizatorja. Bistvo je, da se lahko število opozoril samo zmanjša.

Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe

Zabeleži se število opozoril, ki jih izda statični analizator. Vrata kakovosti so konfigurirana tako, da lahko zdaj vnesete samo kodo, ki ne poveča števila operacij. Posledično se s prilagajanjem analizatorja in odpravljanjem napak začne proces postopnega zmanjševanja števila alarmov.

Tudi če želi oseba malo goljufati in se odloči prestopiti vrata kakovosti ne z odpravo opozoril v svoji novi kodi, ampak z izboljšanjem stare kode tretje osebe, to ni strašljivo. Kljub temu se raglja vrti v eno smer in postopoma se bo število napak zmanjšalo. Tudi če oseba ne želi popraviti svojih novih napak, bo še vedno morala nekaj izboljšati v sosednji kodi. Na neki točki se preprosti načini zmanjšanja števila opozoril končajo in pride točka, ko bodo prave napake odpravljene.

Ta metodologija je podrobneje opisana v zelo zanimivem članku Ivana Ponomareva "Implementirajte statično analizo v proces, namesto da z njim iščete napake«, ki ga priporočam v branje vsem, ki jih zanima izboljšanje kakovosti kode.

Avtor članka ima tudi poročilo o tej temi: "Kontinuirana statična analiza".

Zaključek

Upam, da bodo bralci po tem članku bolj sprejeli orodja za statično analizo in jih želeli implementirati v razvojni proces. Če imate kakršna koli vprašanja, smo vedno pripravljeni svetovati uporabnikov našega statičnega analizatorja PVS-Studio in pomoč pri njegovi implementaciji.

Obstajajo tudi drugi tipični dvomi o tem, ali je statična analiza res lahko priročna in uporabna. Večino teh dvomov sem poskušal razbliniti v publikaciji "Razlogi za uvedbo statičnega analizatorja kode PVS-Studio v razvojni proces" [9].

Hvala za vašo pozornost in pridite prenos in preizkusite analizator PVS-Studio.

Dodatne povezave

  1. Andrej Karpov. Kako lahko hitro vidim zanimiva opozorila, ki jih analizator PVS-Studio ustvari za kodo C in C++?
  2. Wikipedia. Riceov izrek.
  3. Andrej Karpov, Viktorija Khanieva. Uporaba strojnega učenja pri statični analizi izvorne kode programa.
  4. PVS-Studio. Dokumentacija. Dodatne diagnostične nastavitve.
  5. Andrej Karpov. Značilnosti analizatorja PVS-Studio na primeru EFL Core Libraries, 10-15% lažno pozitivnih rezultatov.
  6. PVS-Studio. Dokumentacija. Množično zatiranje sporočil analizatorja.
  7. Ivan Andrjašin. O tem, kako smo testirali statično analizo na našem projektu izobraževalnega simulatorja rentgenske endovaskularne kirurgije.
  8. Pavel Eremejev, Svjatoslav Razmislov. Kako je ekipa PVS-Studio izboljšala kodo Unreal Engine.
  9. Andrej Karpov. Razlogi za uvedbo statičnega analizatorja kode PVS-Studio v razvojni proces.

Kako implementirati statični analizator kode v stari projekt brez demotiviranja ekipe

Če želite ta članek deliti z angleško govorečim občinstvom, uporabite povezavo za prevod: Andrey Karpov. Kako uvesti statični analizator kode v stari projekt in ne odvrniti ekipe.

Vir: www.habr.com

Dodaj komentar