Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima

Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima
Lako je isprobati statički analizator koda. Ali za njegovu implementaciju, 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. Hajde da ukratko porazgovaramo o tome kako pravilno pristupiti integraciji statičke analize u proces razvoja i početi da je koristimo kao deo 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 projekat sa puno U članku se kaže da možete prihvatiti tehnički dug i raditi samo na novom kodu, ali nema odgovora šta da radite sa ovim tehničkim dugom kasnije.

Naš PVS-Studio tim nudi svoj pogled na ovu temu. Pogledajmo kako uopće nastaje problem implementacije statičkog analizatora koda, kako ovaj problem prevazići i kako bezbolno postepeno eliminirati tehnički dug.

Problemi

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

Svi statički analizatori daju lažne pozitivne rezultate. Ovo je karakteristika metodologije statičke analize koda i ništa se ne može učiniti povodom toga. U opštem slučaju, ovo je nerješiv problem, što potvrđuje Riceova teorema [2]. Ni algoritmi mašinskog učenja neće pomoći [3]. Čak i ako osoba ne može uvijek reći da li je 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ć konfigurisan:

  • Onemogućeni irelevantni skupovi pravila;
  • Neke nebitne dijagnostike su onemogućene;
  • Ako govorimo o C ili C++, onda su označeni makroi koji sadrže specifične konstrukcije koje uzrokuju da se beskorisna upozorenja pojavljuju na svakom mjestu gdje se takvi makroi koriste;
  • Označene su vlastite funkcije koje obavljaju radnje slične sistemskim funkcijama (vlastiti analog memcpy ili printf) [4];
  • Lažni pozitivni rezultati su posebno onemogućeni korištenjem komentara;
  • I tako dalje.

U ovom slučaju možemo očekivati ​​nisku stopu lažno pozitivnih od oko 10-15% [5]. Drugim riječima, 9 od 10 upozorenja analizatora će ukazati na stvarni problem u kodu, ili barem na „kod jakog mirisa“. Slažem se, ovaj scenario je izuzetno prijatan, a analizator je pravi prijatelj programera.

Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima
U stvarnosti, u velikom projektu, početna slika će biti potpuno drugačija. Analizator izdaje stotine ili hiljade upozorenja za naslijeđeni kod. Nemoguće je brzo shvatiti koja od ovih upozorenja su relevantna, a koja nisu. Neracionalno je sjesti i početi se baviti svim ovim upozorenjima, jer će glavni posao u ovom slučaju prestati danima ili sedmicama. Tipično, tim si ne može priuštiti takav scenario. Takođe će postojati veliki broj razlika koje će pokvariti istoriju promena. A brzo masovno uređivanje tolikog broja fragmenata u kodu će neizbježno rezultirati novim tipkarskim greškama i greškama.

I što je najvažnije, takav podvig u borbi protiv upozorenja nema mnogo smisla. Slažete se da je, budući da projekat uspješno radi dugi niz godina, većina kritičnih grešaka u njemu već ispravljena. Da, ovi popravci su bili vrlo skupi, morali su biti otklonjeni, dobili su negativne povratne informacije korisnika o greškama, itd. Statički analizator bi pomogao da se poprave mnoge od ovih grešaka u fazi kodiranja, brzo i jeftino. Ali u ovom trenutku, na ovaj ili onaj način, ove greške su ispravljene, a analizator uglavnom otkriva nekritične greške u starom kodu. Ovaj kod se ne može koristiti, može se koristiti vrlo rijetko, a greška u njemu ne može dovesti do vidljivih posljedica. Možda je negdje sjena s gumba pogrešne boje, ali to ne ometa ničiju upotrebu proizvoda.

Naravno, čak i manje greške su i dalje greške. A ponekad greška može sakriti pravu ranjivost. Međutim, odustajanje od svega i provođenje dana/tjednima baveći se nedostacima koji se jedva manifestiraju izgleda kao sumnjiva ideja.

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

Na svoj način, oni su u pravu. Smatraju da se prvo moraju nekako riješiti svih ovih upozorenja. Tek tada će moći imati koristi od redovne upotrebe analizatora koda. U suprotnom, nova upozorenja će se jednostavno utopiti u starima i niko neće obraćati pažnju na njih.

Ovo je ista analogija kao i sa upozorenjima kompajlera. Ne bez razloga preporučuju da se broj upozorenja kompajlera zadrži na 0. Ako ima 1000 upozorenja, onda kada ih ima 1001, niko neće obraćati pažnju na to i nije jasno gdje tražiti ovo najnovije upozorenje.

Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima
Najgora stvar u ovoj priči je ako vas neko odozgo u ovom trenutku natjera da koristite statičku analizu koda. Ovo će samo demotivisati tim, jer će, sa njihove tačke gledišta, biti dodatne birokratske složenosti koja samo staje na put. Niko neće gledati izvještaje analizatora, a sva upotreba će biti samo „na papiru“. One. Formalno, analiza je ugrađena u DevOps proces, ali u praksi to nikome ne koristi. Na štandovima smo čuli detaljne priče od učesnika konferencije. Takvo iskustvo može obeshrabriti programere da koriste alate za statičku analizu dugo, ako ne i zauvijek.

Implementacija i eliminacija tehničkog duga

U stvari, nema ništa teško ili zastrašujuće u uvođenju statičke analize čak i u veliki stari projekat.

CI / CD

Štaviše, analizator se odmah može učiniti dijelom kontinuiranog procesa razvoja. Na primjer, PVS-Studio distribucija sadrži uslužne programe za praktičan pregled izvještaja u formatu koji vam je potreban i obavijesti programerima koji su napisali problematične dijelove koda. Za one koji su više zainteresovani za pokretanje PVS-Studio sa CI/CD sistema, preporučujem da se upoznaju sa odgovarajućim odjeljak dokumentaciju i niz članaka:

No, vratimo se pitanju velikog broja lažnih 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ćavaju vam da proučavate samo nova upozorenja koja se pojavljuju u novom ili promijenjenom kodu. Implementacija ovog mehanizma varira, ali suština je ista. U PVS-Studio statičkom analizatoru ova funkcionalnost je implementirana na sljedeći način.

Kako bi brzo počeli koristiti statičku analizu, predlažemo korisnicima PVS-Studio da koriste mehanizam za masovno suzbijanje upozorenja [6]. Opća ideja je sljedeća. Korisnik je pokrenuo analizator i dobio mnoga upozorenja. Budući da projekat koji se razvija dugi niz godina živi, ​​razvija se i zarađuje, onda najvjerovatnije u izvještaju neće biti mnogo upozorenja koja ukazuju na kritične nedostatke. Drugim riječima, kritične greške su već popravljene na ovaj ili onaj način korištenjem skupljih metoda ili zahvaljujući povratnim informacijama kupaca. Shodno 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-Studiju da smatra da su ova upozorenja za sada nevažna (sačuvajte tehnički dug za kasnije), i više ih neće prikazivati. Analizator kreira posebnu datoteku u koju čuva informacije o greškama koje još nisu zanimljive. I sada će PVS-Studio izdavati upozorenja samo za novi ili promijenjeni kod. Štaviše, sve je to pametno implementirano. Ako se, na primjer, na početak datoteke izvornog koda doda prazan red, tada analizator razumije da se, u stvari, ništa nije promijenilo, i nastavit će šutjeti. Ovaj markup fajl se može staviti u sistem kontrole verzija. Datoteka je velika, ali to nije problem, jer nema smisla da je često pohranjujete.

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. A kasnije se možete vratiti tehničkom dugu i postepeno ispravljati greške i konfigurirati analizator.

Dakle, prvi problem sa implementacijom analizatora u velikom starom projektu je rešen. Hajde sada da shvatimo šta da radimo sa tehničkim dugom.

Ispravke grešaka i refaktoring

Najjednostavnija i najprirodnija stvar 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 da kažete analizatoru da kod nije problematičan. Jednostavan primjer:

if (a = b)

Većina C++ kompajlera i analizatora žali se na takav kod, jer postoji velika vjerovatnoća da su oni zaista htjeli napisati (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 za psovanjem. Na primjer, u dokumentaciji PVS-Studio za dijagnostiku V559 (CWE-481) jasno je napisano da će se sljedeći red smatrati ispravnim i sigurnim:

if ((a = b))

Još jedan primjer. Da li je to zaboravljeno u ovom C++ kodu? pauza ili ne?

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

PVS-Studio analizator će ovdje izdati upozorenje V796 (CWE-484). Ovo možda nije greška, u kom slučaju biste trebali dati parseru nagovještaj dodavanjem atributa [[propasti]] ili na primer __atribut__((fallthrough)):

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

Može se reći da takve promjene koda ne popravljaju grešku. Da, to je istina, ali čini dvije korisne stvari. Prvo, izvještaj analizatora uklanja lažne pozitivne rezultate. Drugo, kod postaje razumljiviji za ljude koji su uključeni u njegovo održavanje. A ovo je veoma važno! Samo za ovo je vrijedno izvršiti manja refaktoriranja kako bi kod bio jasniji i lakši za održavanje. Budući da analizator ne razumije da li je „prekid“ potreban ili ne, to će biti nejasno i kolegama programerima.

Pored ispravki grešaka i refaktorisanja, možete posebno potisnuti očigledno lažna upozorenja analizatora. Neke nebitne dijagnostike se mogu onemogućiti. Na primjer, neko misli da su upozorenja besmislena V550 o upoređivanju float/double vrijednosti. A neki ih klasifikuju kao važne i vredne proučavanja [7]. Koja upozorenja se smatraju relevantnim, a koja nisu, odlučuje razvojni tim.

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

Također, uvijek pomažemo našim klijentima da postave PVS-Studio ako se pojave bilo kakve poteškoće. Štaviše, bilo je slučajeva kada smo sami eliminisali lažna upozorenja i ispravljali greške [8]. Za svaki slučaj odlučio sam da napomenem da je moguća i ova opcija za proširenu saradnju :).

Ratchet metoda

Postoji još jedan zanimljiv pristup za postepeno poboljšanje kvaliteta koda eliminacijom upozorenja statičkog analizatora. Suština je da se broj upozorenja može samo smanjiti.

Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima

Zapisuje se broj upozorenja koje je izdao statički analizator. Kvalitetna kapija je konfigurirana na način da sada možete unijeti samo šifru koja ne povećava broj operacija. Kao rezultat, proces postepenog smanjenja broja alarma počinje podešavanjem analizatora i ispravljanjem grešaka.

Čak i ako osoba želi malo prevariti i odluči proći kapiju kvalitete ne uklanjanjem upozorenja u svom novom kodu, već poboljšanjem starog koda treće strane, to nije strašno. Svejedno, čegrtaljka se okreće u jednom smjeru, a postupno će se broj nedostataka smanjiti. Čak i ako osoba ne želi popraviti svoje nove nedostatke, ipak će morati nešto poboljšati u susjednom kodu. U nekom trenutku se završavaju jednostavni načini za smanjenje broja upozorenja i dolazi trenutak kada će stvarne greške biti ispravljene.

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“, koji preporučujem da pročitaju svima koji su zainteresirani za poboljšanje kvalitete koda.

Autor članka ima i izvještaj na ovu temu: "Kontinuirana statička analiza".

zaključak

Nadam se da će nakon ovog članka čitatelji više prihvatiti alate za statičku analizu i poželjeti ih implementirati u proces razvoja. Ako imate bilo kakvih pitanja, uvijek smo spremni savjet korisnicima našeg statičkog analizatora PVS-Studio i pomoći u njegovoj implementaciji.

Postoje i druge tipične sumnje da li statička analiza zaista može biti zgodna i korisna. Većinu ovih nedoumica pokušao sam da razbijem u publikaciji “Razlozi za uvođenje PVS-Studio statičkog analizatora koda u proces razvoja” [9].

Hvala na pažnji i dođite скачать 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. Rajsova teorema.
  3. Andrej Karpov, Viktorija Khanieva. Korišćenje mašinskog 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 obrazovnog simulatora rendgenske endovaskularne hirurgije.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Kako je PVS-Studio tim poboljšao Unreal Engine kod.
  9. Andrej Karpov. Razlozi za uvođenje statičkog analizatora koda PVS-Studio u proces razvoja.

Kako implementirati statički analizator koda u naslijeđeni projekat bez demotivacije tima

Ako želite da podijelite ovaj članak sa publikom koja govori engleski, koristite link za prijevod: Andrey Karpov. Kako uvesti statički analizator koda u naslijeđeni projekat i ne obeshrabriti tim.

izvor: www.habr.com

Dodajte komentar