Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet

Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet
Det er enkelt å prøve en statisk kodeanalysator. Men å implementere det, spesielt i utviklingen av et stort gammelt prosjekt, krever dyktighet. Hvis det gjøres feil, kan analysatoren legge til arbeid, bremse utviklingen og demotivere teamet. La oss kort snakke om hvordan du kan nærme oss integreringen av statisk analyse i utviklingsprosessen og begynne å bruke den som en del av CI/CD.

Innledning

Nylig ble min oppmerksomhet rettet mot publikasjonen "Komme i gang med statisk analyse uten å overvelde teamet". På den ene siden er dette en god artikkel det er verdt å sette seg inn i. På den andre siden ser det ut til at den fortsatt ikke gir et fullstendig svar på hvordan man smertefritt kan implementere statisk analyse i et prosjekt med mye Artikkelen sier at Du kan godta teknisk gjeld og kun jobbe med ny kode, men det er ikke noe svar på hva du skal gjøre med denne tekniske gjelden senere.

Vårt PVS-Studio-team gir sitt syn på dette emnet. La oss se på hvordan problemet med å implementere en statisk kodeanalysator oppstår i utgangspunktet, hvordan du kan overvinne dette problemet og hvordan du smertefritt gradvis eliminerer teknisk gjeld.

Problemer

Det er vanligvis ikke vanskelig å starte og se hvordan en statisk analysator fungerer [1]. Du kan se interessante feil eller til og med skumle potensielle sårbarheter i koden. Du kan til og med fikse noe, men da gir mange programmerere opp.

Alle statiske analysatorer produserer falske positiver. Dette er en funksjon i metoden for statisk kodeanalyse, og ingenting kan gjøres med det. I det generelle tilfellet er dette et uløselig problem, som bekreftet av Rices teorem [2]. Maskinlæringsalgoritmer vil heller ikke hjelpe [3]. Selv om en person ikke alltid kan se om denne eller den koden er feil, bør du ikke forvente dette fra programmet :).

Falske positiver er ikke et problem hvis den statiske analysatoren allerede er konfigurert:

  • Deaktivert irrelevante regelsett;
  • Noen irrelevante diagnostikk har blitt deaktivert;
  • Hvis vi snakker om C eller C++, så er makroer merket opp som inneholder spesifikke konstruksjoner som gjør at ubrukelige advarsler vises på alle steder der slike makroer brukes;
  • Egne funksjoner er merket som utfører handlinger som ligner på systemfunksjoner (sin egen analog memcpy eller printf) [4];
  • Falske positiver er spesifikt deaktivert ved å bruke kommentarer;
  • Og så videre.

I dette tilfellet kan vi forvente en lav falsk positiv rate på omtrent 10-15 % [5]. Med andre ord, 9 av 10 analysatoradvarsler vil indikere et reelt problem i koden, eller i det minste "sterkluktende kode". Enig, dette scenariet er ekstremt hyggelig, og analysatoren er en ekte venn av programmereren.

Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet
I virkeligheten, i et stort prosjekt, vil det første bildet være helt annerledes. Analysatoren utsteder hundrevis eller tusenvis av advarsler for eldre kode. Det er umulig å raskt forstå hvilke av disse advarslene som er relevante og hvilke som ikke er det. Det er irrasjonelt å sette seg ned og begynne å håndtere alle disse advarslene, siden hovedarbeidet i dette tilfellet vil stoppe i dager eller uker. Vanligvis har et team ikke råd til et slikt scenario. Det vil også være et stort antall diff som ødelegger endringshistorien. Og rask masseredigering av så mange fragmenter i koden vil uunngåelig resultere i nye skrivefeil og feil.

Og viktigst av alt, en slik bragd i kampen mot advarsler gir liten mening. Enig i at siden prosjektet har vært vellykket i mange år, er de fleste kritiske feilene i det allerede rettet. Ja, disse rettelsene var veldig dyre, måtte feilsøkes, fikk negative tilbakemeldinger fra brukere om feil, og så videre. En statisk analysator vil hjelpe å fikse mange av disse feilene på kodingsstadiet, raskt og billig. Men for øyeblikket, på en eller annen måte, er disse feilene fikset, og analysatoren oppdager hovedsakelig ikke-kritiske feil i den gamle koden. Denne koden kan ikke brukes, den kan brukes svært sjelden, og en feil i den kan ikke føre til merkbare konsekvenser. Kanskje et sted har skyggen fra knappen feil farge, men dette forstyrrer ikke noens bruk av produktet.

Selvsagt er selv små feil fortsatt feil. Og noen ganger kan en feil skjule en reell sårbarhet. Men å gi opp alt og bruke dager/uker på å håndtere feil som knapt viser seg ser ut som en tvilsom idé.

Programmerere ser, ser, ser på alle disse advarslene om den gamle arbeidskoden... Og de tenker: vi kan klare oss uten statisk analyse. La oss skrive litt ny nyttig funksjonalitet.

På hver sin måte har de rett. De regner med at de først må kvitte seg med alle disse advarslene. Først da vil de kunne dra nytte av regelmessig bruk av kodeanalysatoren. Ellers vil nye advarsler ganske enkelt drukne i gamle, og ingen vil ta hensyn til dem.

Dette er samme analogi som med kompilatoradvarsler. Det er ikke uten grunn at de anbefaler å holde antallet kompilatorvarsler på 0. Hvis det er 1000 advarsler, så når det er 1001, vil ingen ta hensyn til det, og det er ikke klart hvor man skal lete etter denne nyeste advarselen.

Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet
Det verste i denne historien er hvis noen ovenfra i dette øyeblikket tvinger deg til å bruke statisk kodeanalyse. Dette vil bare demotivere teamet, siden det fra deres synspunkt vil være ytterligere byråkratisk kompleksitet som bare kommer i veien. Ingen vil se på analysatorens rapporter, og all bruk vil bare være "på papir". De. Formelt sett er analyse innebygd i DevOps-prosessen, men i praksis kommer dette ingen til gode. Vi hørte detaljerte historier på standene fra konferansedeltakerne. En slik opplevelse kan fraråde programmerere å bruke statiske analyseverktøy i lang tid, om ikke for alltid.

Implementering og eliminering av teknisk gjeld

Faktisk er det ikke noe vanskelig eller skummelt ved å introdusere statisk analyse selv i et stort gammelt prosjekt.

CI / CD

Dessuten kan analysatoren umiddelbart bli en del av den kontinuerlige utviklingsprosessen. For eksempel inneholder PVS-Studio-distribusjonen verktøy for enkelt å se rapporten i formatet du trenger, og varsler til utviklere som har skrevet problematiske deler av koden. For de som er mer interessert i å lansere PVS-Studio fra CI/CD-systemer, anbefaler jeg at du gjør deg kjent med tilsvarende seksjon dokumentasjon og en serie artikler:

Men la oss gå tilbake til spørsmålet om et stort antall falske positiver i de første stadiene av implementering av kodeanalyseverktøy.

Retting av eksisterende teknisk gjeld og håndtering av nye advarsler

Moderne kommersielle statiske analysatorer lar deg studere kun nye advarsler som vises i ny eller endret kode. Implementeringen av denne mekanismen varierer, men essensen er den samme. I den statiske analysatoren PVS-Studio implementeres denne funksjonaliteten som følger.

For raskt å begynne å bruke statisk analyse, foreslår vi at PVS-Studio-brukere bruker mekanismen for masseundertrykkelse av advarsler [6]. Den generelle ideen er følgende. Brukeren startet analysatoren og mottok mange advarsler. Siden et prosjekt som har vært under utvikling i mange år lever, utvikler seg og tjener penger, så vil det mest sannsynlig ikke være mange advarsler i rapporten som indikerer kritiske mangler. Med andre ord, kritiske feil har allerede blitt fikset på en eller annen måte ved hjelp av dyrere metoder eller takket være tilbakemeldinger fra kunder. Følgelig kan alt som analysatoren finner for øyeblikket betraktes som teknisk gjeld, noe som er upraktisk å prøve å eliminere umiddelbart.

Du kan fortelle PVS-Studio å vurdere disse advarslene som irrelevante for nå (lagre teknisk gjeld til senere), og den vil ikke lenger vise dem. Analysatoren lager en spesiell fil der den lagrer informasjon om feil som ennå ikke er interessante. Og nå vil PVS-Studio utstede advarsler kun for ny eller endret kode. Dessuten er alt dette implementert smart. Hvis for eksempel en tom linje legges til i begynnelsen av kildekodefilen, forstår analysatoren at ingenting har endret seg, og vil fortsette å være stille. Denne markup-filen kan settes inn i et versjonskontrollsystem. Filen er stor, men dette er ikke et problem, siden det ikke nytter å lagre den ofte.

Nå vil alle programmerere se advarsler kun relatert til ny eller endret kode. Dermed kan du begynne å bruke analysatoren, som de sier, fra neste dag. Og du kan gå tilbake til teknisk gjeld senere, og gradvis rette opp feil og konfigurere analysatoren.

Så det første problemet med implementeringen av analysatoren i et stort gammelt prosjekt er løst. La oss nå finne ut hva vi skal gjøre med teknisk gjeld.

Feilrettinger og refaktoreringer

Det enkleste og mest naturlige er å sette av litt tid til å analysere massivt undertrykte analysatorvarsler og gradvis håndtere dem. Et sted bør du fikse feil i koden, et sted bør du refaktorere for å fortelle analysatoren at koden ikke er problematisk. Enkelt eksempel:

if (a = b)

De fleste C++ kompilatorer og analysatorer klager på slik kode, siden det er stor sannsynlighet for at de faktisk ønsket å skrive (a == b). Men det er en uuttalt avtale, og dette er vanligvis notert i dokumentasjonen, at hvis det er flere parenteser, anses det som at programmereren bevisst skrev en slik kode, og det er ikke nødvendig å banne. For eksempel i PVS-Studio-dokumentasjonen for diagnostikk V559 (CWE-481) det er tydelig skrevet at følgende linje vil bli ansett som riktig og sikker:

if ((a = b))

Et annet eksempel. Er det glemt i denne C++-koden? bryte eller ikke?

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

PVS-Studio-analysatoren vil gi en advarsel her V796 (CWE-484). Dette er kanskje ikke en feil, i så fall bør du gi parseren et hint ved å legge til attributtet [[faller gjennom]] eller for eksempel __attribute__((fallthrough)):

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

Det kan sies at slike kodeendringer ikke fikser feilen. Ja, dette er sant, men det gjør to nyttige ting. For det første blir analysatorrapporten kvitt falske positiver. For det andre blir koden mer forståelig for personene som er involvert i vedlikeholdet. Og dette er veldig viktig! For dette alene er det verdt å utføre mindre refaktoriseringer for å gjøre koden klarere og enklere å vedlikeholde. Siden analysatoren ikke forstår om "pause" er nødvendig eller ikke, vil det også være uklart for andre programmerere.

I tillegg til feilrettinger og refactorings, kan du spesifikt undertrykke åpenbart falske analysatoradvarsler. Noe irrelevant diagnostikk kan deaktiveres. Noen mener for eksempel advarsler er meningsløse V550 om å sammenligne float/double verdier. Og noen klassifiserer dem som viktige og studieverdige [7]. Hvilke advarsler som anses som relevante og hvilke som ikke er det, er opp til utviklingsteamet å avgjøre.

Det finnes andre måter å undertrykke falske varsler på. For eksempel ble makromarkering nevnt tidligere. Alt dette er beskrevet mer detaljert i dokumentasjonen. Det viktigste er å forstå at hvis du gradvis og systematisk nærmer deg arbeidet med falske positiver, er det ingenting galt med dem. De aller fleste uinteressante advarslene forsvinner etter konfigurasjon, og bare steder som virkelig krever nøye studier og noen endringer i koden gjenstår.

Dessuten hjelper vi alltid våre kunder med å sette opp PVS-Studio hvis det oppstår problemer. Dessuten var det tilfeller der vi selv eliminerte falske advarsler og korrigerte feil [8]. Bare i tilfelle bestemte jeg meg for å nevne at dette alternativet for utvidet samarbeid også er mulig :).

Ratchet metode

Det er en annen interessant tilnærming for å gradvis forbedre kodekvaliteten ved å eliminere advarselen om statisk analysator. Poenget er at antallet advarsler bare kan reduseres.

Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet

Antall advarsler utstedt av den statiske analysatoren registreres. Quality gate er konfigurert på en slik måte at du nå kun kan legge inn en kode som ikke øker antall operasjoner. Som et resultat starter prosessen med å gradvis redusere antall alarmer ved å justere analysatoren og korrigere feil.

Selv om en person ønsker å jukse litt og bestemmer seg for å passere kvalitetsporten, ikke ved å eliminere advarsler i den nye koden, men ved å forbedre den gamle tredjepartskoden, er dette ikke skummelt. Likevel roterer skrallen i én retning, og gradvis vil antallet defekter reduseres. Selv om en person ikke ønsker å fikse sine egne nye defekter, vil han fortsatt måtte forbedre noe i nabokoden. På et tidspunkt slutter de enkle måtene å redusere antall advarsler på, og det kommer et punkt da virkelige feil vil bli fikset.

Denne metodikken er beskrevet mer detaljert i en veldig interessant artikkel av Ivan Ponomarev "Implementer statisk analyse i prosessen, i stedet for å bruke den til å finne feil", som jeg anbefaler å lese til alle som er interessert i å forbedre kodekvaliteten.

Forfatteren av artikkelen har også en rapport om dette emnet: "Kontinuerlig statisk analyse".

Konklusjon

Jeg håper at leserne etter denne artikkelen vil akseptere statiske analyseverktøy og vil implementere dem i utviklingsprosessen. Har du spørsmål er vi alltid klare rådgi brukere av vår statiske analysator PVS-Studio og hjelpe med implementeringen.

Det er andre typiske tvil om statisk analyse virkelig kan være praktisk og nyttig. Jeg prøvde å fjerne de fleste av disse tvilene i publikasjonen "Grunner til å introdusere PVS-Studio statisk kodeanalysator i utviklingsprosessen" [9].

Takk for oppmerksomheten og kom скачать og prøv PVS-Studio-analysatoren.

Ytterligere lenker

  1. Andrey Karpov. Hvordan kan jeg raskt se interessante advarsler som PVS-Studio-analysatoren produserer for C- og C++-kode?
  2. Wikipedia. Rice sin teorem.
  3. Andrey Karpov, Victoria Khanieva. Bruke maskinlæring i statisk analyse av programkildekode.
  4. PVS-Studio. Dokumentasjon. Ytterligere diagnoseinnstillinger.
  5. Andrey Karpov. Kjennetegn på PVS-Studio-analysatoren ved bruk av eksemplet med EFL Core Libraries, 10-15 % falske positiver.
  6. PVS-Studio. Dokumentasjon. Masseundertrykkelse av analysatormeldinger.
  7. Ivan Andryashin. Om hvordan vi testet statisk analyse på prosjektet vårt av en pedagogisk simulator for røntgenendovaskulær kirurgi.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Hvordan PVS-Studio-teamet forbedret Unreal Engine-koden.
  9. Andrey Karpov. Grunner til å introdusere den statiske kodeanalysatoren PVS-Studio i utviklingsprosessen.

Hvordan implementere en statisk kodeanalysator i et eldre prosjekt uten å demotivere teamet

Hvis du vil dele denne artikkelen med et engelsktalende publikum, vennligst bruk oversettelseslenken: Andrey Karpov. Hvordan introdusere en statisk kodeanalysator i et eldre prosjekt og ikke ta motet fra teamet.

Kilde: www.habr.com

Legg til en kommentar