Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima

Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima
Lako je isprobati statički analizator koda. Ali za njegovu provedbu, posebno u razvoju velikog starog projekta, potrebna je vještina. Ako se radi pogrešno, analizator može dodati posao, usporiti razvoj i demotivirati tim. Hajdemo ukratko razgovarati o tome kako pravilno pristupiti integraciji statičke analize u razvojni proces i početi je koristiti kao dio CI/CD.

Uvod

Nedavno mi je pažnju privukla publikacija "Početak rada sa statičkom analizom bez preopterećenja tima". S jedne strane, ovo je dobar članak s kojim se vrijedi upoznati. S druge strane, čini mi se da još uvijek ne daje potpuni odgovor kako bezbolno implementirati statičku analizu u projekt s puno naslijeđenog koda. U članku se kaže da možete prihvatiti tehnički dug i raditi samo na novom kodu, ali nema odgovora što kasnije učiniti s tim tehničkim dugom.

Naš PVS-Studio tim nudi svoje viđenje ove teme. Pogledajmo kako uopće nastaje problem implementacije statičkog analizatora koda, kako prevladati taj problem i kako bezbolno postupno eliminirati tehnički dug.

pitanja

Obično nije teško pokrenuti i vidjeti kako radi statički analizator [1]. Možda ćete vidjeti zanimljive pogreške ili čak zastrašujuće potencijalne ranjivosti u kodu. Možete čak i popraviti nešto, ali onda mnogi programeri odustanu.

Svi statički analizatori proizvode lažno pozitivne rezultate. Ovo je značajka metodologije statičke analize koda i tu se ništa ne može učiniti. U općem slučaju, to je nerješiv problem, što potvrđuje i Riceov teorem [2]. Ni algoritmi strojnog učenja neće pomoći [3]. Čak i ako osoba ne može uvijek reći je li ovaj ili onaj kod pogrešan, onda to ne biste trebali očekivati ​​od programa :).

Lažni pozitivni rezultati nisu problem ako je statički analizator već konfiguriran:

  • Onemogućeni irelevantni skupovi pravila;
  • Neke irelevantne dijagnostike su onemogućene;
  • Ako govorimo o C ili C++, onda su označene makronaredbe koje sadrže specifične konstrukcije koje uzrokuju pojavljivanje beskorisnih upozorenja na svakom mjestu gdje se takve makronaredbe koriste;
  • Označene su vlastite funkcije koje izvode radnje slične funkcijama sustava (vlastiti analog memcpy ili printf) [4];
  • Lažno pozitivni rezultati su posebno onemogućeni korištenjem komentara;
  • I tako dalje.

U ovom slučaju možemo očekivati ​​nisku lažno pozitivnu stopu od oko 10-15% [5]. Drugim riječima, 9 od 10 upozorenja analizatora ukazivati ​​će na stvarni problem u kodu ili barem na "kod s jakim mirisom". Slažem se, ovaj scenarij je izuzetno ugodan, a analizator je pravi prijatelj programera.

Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima
U stvarnosti, u velikom projektu, početna slika će biti potpuno drugačija. Analizator izdaje stotine ili tisuće upozorenja za naslijeđeni kod. Nemoguće je brzo shvatiti koja su od ovih upozorenja relevantna, a koja nisu. Neracionalno je sjesti i početi se baviti svim tim upozorenjima, budući da će glavni posao u ovom slučaju stati danima ili tjednima. Tipično, tim si ne može priuštiti takav scenarij. Također će biti ogroman broj razlika koje kvare povijest promjena. A brzo masovno uređivanje tolikih fragmenata u kodu neizbježno će rezultirati novim tipfelerima i pogreškama.

I što je najvažnije, takav podvig u borbi protiv upozorenja nema mnogo smisla. Složite se da je, budući da projekt uspješno radi dugi niz godina, većina kritičnih pogrešaka u njemu već ispravljena. Da, ti su popravci bili vrlo skupi, morali su se otklanjati pogreške, primili su negativne povratne informacije korisnika o greškama i tako dalje. Statički analizator bi pomogao popraviti mnoge od ovih grešaka u fazi kodiranja, brzo i jeftino. Ali u ovom trenutku, na ovaj ili onaj način, te su pogreške popravljene, a analizator uglavnom otkriva nekritične pogreške u starom kodu. Ovaj kod se ne smije koristiti, može se koristiti vrlo rijetko, a pogreška u njemu ne mora dovesti do vidljivih posljedica. Možda je negdje sjena s gumba pogrešne boje, ali to nikome ne smeta u korištenju proizvoda.

Naravno, čak i manje pogreške ostaju pogreške. A ponekad greška može sakriti stvarnu ranjivost. Međutim, odreći se svega i provoditi dane/tjedne rješavajući nedostatke koji se jedva očituju izgleda kao dvojbena ideja.

Programeri gledaju, gledaju, gledaju sva ta upozorenja o starom radnom kodu... I misle: možemo i bez statičke analize. Idemo napisati neke nove korisne funkcije.

Na svoj su način u pravu. Shvatili su da se prvo moraju nekako riješiti svih tih upozorenja. Tek tada će moći imati koristi od redovite upotrebe analizatora koda. Inače će se nova upozorenja jednostavno utopiti u starim i nitko na njih neće obraćati pozornost.

Ovo je ista analogija kao s upozorenjima prevoditelja. Ne preporučuju bez razloga da se broj upozorenja kompilatora drži na 0. Ako postoji 1000 upozorenja, onda kad ih bude 1001, nitko neće obraćati pozornost na to, a nije jasno gdje tražiti ovo najnovije upozorenje.

Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima
Najgora stvar u ovoj priči je ako vas netko odozgo u ovom trenutku natjera na statičku analizu koda. To će samo demotivirati tim, jer će s njihove točke gledišta biti dodatna birokratska složenost koja će samo smetati. Nitko neće gledati izvješća analizatora, a sva će upotreba biti samo "na papiru". Oni. Formalno, analiza je ugrađena u DevOps proces, ali u praksi to nikome ne koristi. Čuli smo detaljne priče na štandovima od sudionika konferencije. Takvo iskustvo može obeshrabriti programere od korištenja alata za statičku analizu dugo vremena, ako ne i zauvijek.

Provedba i uklanjanje tehničkog duga

Zapravo, nema ničeg teškog ili zastrašujućeg u uvođenju statičke analize čak iu veliki stari projekt.

CI / CD

Štoviše, analizator se može odmah uključiti u kontinuirani razvojni proces. Na primjer, distribucija PVS-Studio sadrži uslužne programe za prikladno pregledavanje izvješća u formatu koji vam je potreban i obavijesti programerima koji su napisali problematične dijelove koda. Za one koji su više zainteresirani za pokretanje PVS-Studio iz CI/CD sustava, preporučujem da se upoznate s odgovarajućim odjeljak dokumentaciju i niz članaka:

Ali vratimo se problemu velikog broja lažno pozitivnih rezultata u prvim fazama implementacije alata za analizu koda.

Popravljanje postojećeg tehničkog duga i rješavanje novih upozorenja

Moderni komercijalni statički analizatori omogućuju proučavanje samo novih upozorenja koja se pojavljuju u novom ili promijenjenom kodu. Implementacija ovog mehanizma je različita, ali suština je ista. U statičkom analizatoru PVS-Studio ova je funkcionalnost implementirana na sljedeći način.

Za brzi početak korištenja statičke analize predlažemo korisnicima PVS-Studio korištenje mehanizma za masovno potiskivanje upozorenja [6]. Opća ideja je sljedeća. Korisnik je pokrenuo analizator i primio mnogo upozorenja. Budući da je projekt koji je u razvoju dugi niz godina živ, razvija se i zarađuje, tada najvjerojatnije u izvješću neće biti puno upozorenja koja ukazuju na kritične nedostatke. Drugim riječima, kritične pogreške već su popravljene na ovaj ili onaj način skupljim metodama ili zahvaljujući povratnim informacijama korisnika. Sukladno tome, sve što analizator trenutno pronađe može se smatrati tehničkim dugom, koji je nepraktično pokušavati odmah eliminirati.

Možete reći PVS-Studio da ova upozorenja za sada smatra nevažnima (sačuvajte tehnički dug za kasnije), i on ih više neće prikazivati. Analizator stvara posebnu datoteku u koju sprema informacije o pogreškama koje još nisu zanimljive. I sada će PVS-Studio izdavati upozorenja samo za novi ili promijenjeni kod. Štoviše, sve je to pametno implementirano. Ako se, na primjer, prazna linija doda na početak datoteke izvornog koda, tada analizator razumije da se zapravo ništa nije promijenilo i nastavit će šutjeti. Ova oznaka oznake može se staviti u sustav kontrole verzija. Datoteka je velika, ali to nije problem, jer nema smisla često je pohranjivati.

Sada će svi programeri vidjeti upozorenja koja se odnose samo na novi ili promijenjeni kod. Dakle, možete početi koristiti analizator, kako kažu, od sljedećeg dana. Kasnije se možete vratiti tehničkom dugu i postupno ispravljati pogreške i konfigurirati analizator.

Dakle, prvi problem s implementacijom analizatora u veliki stari projekt je riješen. Sada shvatimo što učiniti s tehničkim dugom.

Ispravci grešaka i preinake

Najjednostavnije i najprirodnije je odvojiti malo vremena za analizu masovno potisnutih upozorenja analizatora i postupno se nositi s njima. Negdje biste trebali ispraviti greške u kodu, negdje biste trebali refaktorirati kako biste analizatoru rekli da kod nije problematičan. Jednostavan primjer:

if (a = b)

Većina C++ prevoditelja i analizatora žali se na takav kod, budući da postoji velika vjerojatnost da su oni zapravo htjeli pisati (a == b). Ali postoji neizgovoreni dogovor, a to se obično navodi u dokumentaciji, da ako postoje dodatne zagrade, onda se smatra da je programer namjerno napisao takav kod, i nema potrebe zaklinjati se. Na primjer, u dokumentaciji PVS-Studio za dijagnostiku V559 (CWE-481) jasno je napisano da će se sljedeći redak smatrati točnim i sigurnim:

if ((a = b))

Još jedan primjer. Je li to zaboravljeno u ovom C++ kodu? razbiti ili ne?

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

PVS-Studio analizator će ovdje izdati upozorenje V796 (CWE-484). Ovo možda nije pogreška, u kojem slučaju trebate dati savjet parseru dodavanjem atributa [[propasti]] ili na primjer __atribut__((pad)):

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

Može se reći da takve izmjene koda ne ispravljaju grešku. Da, to je istina, ali čini dvije korisne stvari. Prvo, izvješće analizatora uklanja lažno pozitivne rezultate. Drugo, kod postaje razumljiviji za ljude uključene u njegovo održavanje. A ovo je vrlo važno! Samo zbog toga vrijedi izvršiti manja refaktoriranja kako bi kod bio jasniji i lakši za održavanje. Budući da analizator ne razumije je li "break" potreban ili ne, to će također biti nejasno kolegama programerima.

Uz ispravke grešaka i refaktoriranje, možete posebno potisnuti očito lažna upozorenja analizatora. Neke nevažne dijagnostike mogu se onemogućiti. Na primjer, netko misli da su upozorenja besmislena V550 o usporedbi float/double vrijednosti. A neki ih klasificiraju kao važne i vrijedne proučavanja [7]. Koja se upozorenja smatraju relevantnima, a koja ne, odlučuje razvojni tim.

Postoje i drugi načini za suzbijanje lažnih dojava. Na primjer, makro označavanje je spomenuto ranije. Sve je to detaljnije opisano u dokumentaciji. Najvažnije je shvatiti da ako postupno i sustavno pristupate radu s lažno pozitivnim rezultatima, s njima nema ništa loše. Velika većina nezanimljivih upozorenja nestaje nakon konfiguracije, a ostaju samo mjesta koja stvarno zahtijevaju pažljivo proučavanje i neke promjene u kodu.

Također, uvijek pomažemo našim klijentima postaviti PVS-Studio ako se pojave bilo kakve poteškoće. Štoviše, bilo je slučajeva kada smo sami otklanjali lažna upozorenja i ispravljali pogreške [8]. Za svaki slučaj odlučio sam napomenuti da je moguća i ova opcija za produženje suradnje :).

Ratchet metoda

Postoji još jedan zanimljiv pristup postupnom poboljšanju kvalitete koda uklanjanjem upozorenja statičkog analizatora. Suština je da se broj upozorenja može samo smanjivati.

Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima

Bilježi se broj upozorenja koje je izdao statički analizator. Vrata kvalitete su konfigurirana na takav način da sada možete unijeti samo kod koji ne povećava broj operacija. Kao rezultat toga, proces postupnog smanjenja broja alarma započinje podešavanjem analizatora i ispravljanjem grešaka.

Čak i ako osoba želi malo varati i odluči proći vrata kvalitete ne uklanjanjem upozorenja u svom novom kodu, već poboljšanjem starog koda treće strane, to nije zastrašujuće. Svejedno, čegrtaljka se okreće u jednom smjeru, a postupno će se broj nedostataka smanjivati. Čak i ako osoba ne želi popraviti vlastite nove nedostatke, ipak će morati poboljšati nešto u susjednom kodu. U jednom trenutku prestaju jednostavni načini smanjenja broja upozorenja i dolazi trenutak kada će pravi bugovi biti ispravljeni.

Ova metodologija je detaljnije opisana u vrlo zanimljivom članku Ivana Ponomareva "Implementirajte statičku analizu u proces, umjesto da je koristite za pronalaženje grešaka“, koju preporučujem pročitati svima zainteresiranima za poboljšanje kvalitete koda.

Autor članka također ima izvješće o ovoj temi: "Kontinuirana statička analiza".

Zaključak

Nadam se da će nakon ovog članka čitatelji više prihvatiti alate za statičku analizu i da će ih htjeti implementirati u razvojni proces. Ako imate pitanja, uvijek smo spremni savjetovati korisnicima našeg statičkog analizatora PVS-Studio i pomoć pri njegovoj implementaciji.

Postoje i druge tipične dvojbe o tome može li statička analiza doista biti prikladna i korisna. Većinu ovih dvojbi pokušao sam odagnati u publikaciji “Razlozi za uvođenje PVS-Studio statičkog analizatora koda u razvojni proces” [9].

Hvala na pažnji i dođite preuzimanje i isprobajte PVS-Studio analizator.

Dodatne veze

  1. Andrej Karpov. Kako mogu brzo vidjeti zanimljiva upozorenja koja PVS-Studio analizator proizvodi za C i C++ kod?
  2. Wikipedia. Riceov teorem.
  3. Andrej Karpov, Viktorija Khanieva. Korištenje strojnog učenja u statičkoj analizi izvornog koda programa.
  4. PVS-Studio. Dokumentacija. Dodatne dijagnostičke postavke.
  5. Andrej Karpov. Karakteristike PVS-Studio analizatora na primjeru EFL Core Libraries, 10-15% lažno pozitivnih rezultata.
  6. PVS-Studio. Dokumentacija. Masovno potiskivanje poruka analizatora.
  7. Ivan Andryashin. O tome kako smo testirali statičku analizu na našem projektu edukacijskog simulatora rendgenske endovaskularne kirurgije.
  8. Pavel Eremejev, Svjatoslav Razmislov. Kako je tim PVS-Studio poboljšao kod Unreal Enginea.
  9. Andrej Karpov. Razlozi za uvođenje PVS-Studio statičkog analizatora koda u razvojni proces.

Kako implementirati statički analizator koda u naslijeđeni projekt bez demotiviranja tima

Ako želite podijeliti ovaj članak s publikom koja govori engleski, upotrijebite vezu za prijevod: Andrey Karpov. Kako uvesti statički analizator koda u naslijeđeni projekt i ne obeshrabriti tim.

Izvor: www.habr.com

Dodajte komentar