Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra

Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra
Hè facilitu per pruvà un analizzatore di codice staticu. Ma per implementà, soprattuttu in u sviluppu di un grande prughjettu anticu, esige abilità. Se fattu in modu incorrectu, l'analizzatore pò aghjunghje u travagliu, rallentà u sviluppu è demotivate a squadra. Parlemu brevemente di cumu avvicinà bè l'integrazione di l'analisi statica in u prucessu di sviluppu è cumincià à aduprà cum'è parte di CI/CD.

Introduzione

Recentemente a mo attenzione hè stata attirata à a publicazione "Cumincià cù l'analisi statica senza sopraffare a squadra". Per una banda, questu hè un bonu articulu chì vale a pena cunnosce. Per d 'altra banda, mi pari chì ùn furnisce micca una risposta cumpleta nantu à cumu implementà senza dolore l'analisi statica in un prughjettu cù assai. di codice legatu L'articulu dice chì Pudete accettà u debitu tecnicu è travaglià solu nantu à u codice novu, ma ùn ci hè micca risposta à ciò chì deve fà cù stu debitu tecnicu dopu.

A nostra squadra PVS-Studio offre a so vista nantu à questu tema. Fighjemu cumu u prublema di implementà un analizzatore di codice staticu hè in u primu locu, cumu per superà stu prublema, è cumu per eliminà gradualmente u debitu tecnicu.

I prublemi

Di solitu ùn hè micca difficiule di lancià è vede cumu funziona un analizatore staticu [1]. Puderete vede errori interessanti o ancu vulnerabili potenziali scary in u codice. Pudete ancu riparà qualcosa, ma allora parechji programatori rinuncianu.

Tutti l'analizzatori statici producenu falsi pusitivi. Questa hè una caratteristica di a metodulugia di l'analisi di codice staticu, è nunda ùn si pò fà. In u casu generale, questu hè un prublema insolubile, cum'è cunfirmatu da u teorema di Rice.2]. L'algoritmi di apprendimentu automaticu ùn aiuteranu nè [3]. Ancu s'è una persona ùn pò micca sempre dì s'ellu questu o quellu codice hè sbagliatu, allora ùn deve micca aspittà questu da u prugramma :).

I falsi pusitivi ùn sò micca un prublema se l'analizzatore staticu hè digià cunfiguratu:

  • Disabilitatu setti di regule irrilevanti;
  • Certi diagnostichi irrilevanti sò stati disattivati;
  • Se parlemu di C o C++, allora i macros sò marcati chì cuntenenu custruzzioni specifichi chì causanu avvisi inutili per apparisce in ogni locu induve tali macros sò usati;
  • E funzioni propiu sò marcati chì facenu azzione simili à e funzioni di u sistema (u so propiu analogu memcpy o stampa f) [4];
  • I falsi pusitivi sò specificamente disattivati ​​cù i cumenti;
  • E accussì.

In questu casu, pudemu aspittà una bassa rata falsa positiva di circa 10-15% [5]. In altre parolle, 9 di 10 avvisi di l'analizzatore indicà un veru prublema in u codice, o almenu "codice forte odore". Agree, stu scenariu hè assai piacevule, è l'analizzatore hè un veru amicu di u programatore.

Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra
In rialità, in un grande prughjettu, a stampa iniziale serà completamente diversa. L'analizzatore emette centinaie o millaie di avvisi per u codice legatu. Hè impussibile di capisce rapidamente quale di questi avvirtimenti sò pertinenti è quali ùn sò micca. Hè irrazionale à pusà è cumincià à trattà cù tutti questi avvirtimenti, postu chì u travagliu principale in questu casu si ferma per ghjorni o settimane. Di genere, una squadra ùn pò micca permette un tali scenariu. Ci sarà ancu un gran numaru di diffs chì spoil a storia di u cambiamentu. È l'edizione rapida di massa di tanti frammenti in u codice inevitabbilmente risultà in novi typos è errori.

E più impurtante, una tale impresa in a lotta contru l'avvirtimenti ùn hà pocu sensu. Accettate chì, postu chì u prugettu hè stata corretta cù successu per parechji anni, a maiò parte di l'errori critichi in questu sò digià corrette. Iè, sti correzioni eranu assai caru, anu da esse debugged, ricevutu feedback negativu di l'utilizatori nantu à i bug, è cusì. Un analizatore staticu aiuterà à risolve parechji di questi errori in u stadiu di codificazione, rapidamente è à pocu pressu. Ma à u mumentu, in una manera o l'altru, sti errori sò stati riparati, è l'analizzatore detecta principalmente errori non critichi in u vechju codice. Stu codice ùn pò esse usatu, pò esse usatu assai raramenti, è un errore in questu ùn pò micca purtà à cunsequenze notevuli. Forsi in un locu l'ombra da u buttone hè u culore sbagliatu, ma questu ùn interferiscenu micca cù l'usu di u pruduttu di nimu.

Di sicuru, ancu i sbagli minori sò sempre sbagli. È qualchì volta un sbagliu pò ammuccià una vera vulnerabilità. In ogni casu, rinunzià tuttu è passanu ghjorni / settimane à trattà cù difetti chì si manifestanu appena si pare una idea dubbiosa.

I programatori fighjanu, fighjate, fighjate tutti questi avvirtimenti nantu à u vechju codice di travagliu... È pensanu: pudemu fà senza analisi statica. Andemu à scrive una nova funziunalità utile.

In u so modu, sò ghjustu. Pensanu chì prima anu da sbarazzà in qualchì manera di tutti questi avvirtimenti. Solu allora puderanu prufittà di l'usu regulare di l'analizzatore di codice. Altrimenti, i novi avvirtimenti simpricamente affucà in i vechji, è nimu ùn li prestarà attenzione.

Questa hè a stessa analogia cum'è cù l'avvirtimenti di compilatore. Ùn hè micca senza ragiuni chì ricumandenu di mantene u numeru di l'avvirtimenti di compilatore à 0. Se ci sò 1000 avvirtimenti, allora quandu ci sò 1001, nimu hà da esse attentu à questu, è ùn hè micca chjaru induve cercà stu avvisu più novu.

Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra
U peghju in questa storia hè chì qualchissia da sopra à questu mumentu vi forza à utilizà l'analisi di codice staticu. Questu solu demotivate a squadra, postu chì da u so puntu di vista, ci sarà una cumplessità burocratica addiziale chì si mette solu in u modu. Nimu hà da guardà i rapporti di l'analizzatore, è tuttu l'usu serà solu "in carta". Quelli. Formalmente, l'analisi hè integrata in u prucessu DevOps, ma in a pratica ùn hè micca benefiziu per nimu. Avemu intesu storie dettagliate in cabine da i participanti à a cunferenza. Una tale sperienza pò scoraggià i programatori da aduprà strumenti di analisi statica per un bellu pezzu, se micca per sempre.

Implementazione è eliminazione di u debitu tecnicu

In fatti, ùn ci hè nunda di difficiule o spaventoso per l'introduzione di l'analisi statica ancu in un grande prughjettu anticu.

CI / CD

Inoltre, l'analizzatore pò esse immediatamente fattu parte di u prucessu di sviluppu cuntinuu. Per esempiu, a distribuzione PVS-Studio cuntene utilità per vede convenientemente u rapportu in u formatu chì avete bisognu, è notificazioni à i sviluppatori chì anu scrittu sezzioni problematiche di u codice. Per quelli chì anu più interessatu à lancià PVS-Studio da i sistemi CI/CD, vi cunsigliu di familiarizàvi cù u currispundente. sezione documentazione è una seria di articuli:

Ma vultemu à u prublema di un gran numaru di falsi pusitivi in ​​i primi fasi di implementazione di strumenti di analisi di codice.

Fixing u debitu tecnicu esistenti è trattà cù novi avvisi

L'analizzatori statichi cummirciali muderni permettenu di studià solu avvisi novi chì appariscenu in codice novu o cambiatu. L'implementazione di stu mecanismu varieghja, ma l'essenza hè a stessa. In l'analizzatore staticu PVS-Studio, sta funziunalità hè implementata cum'è seguita.

Per cumincià rapidamente à utilizà l'analisi statica, suggerimu chì l'utilizatori di PVS-Studio utilizanu u mecanismu per a suppressione di massa di avvisi [6]. L'idea generale hè a seguente. L'utilizatore hà lanciatu l'analizzatore è hà ricevutu assai avvisi. Siccomu un prughjettu chì hè statu in sviluppu per parechji anni hè vivu, sviluppendu è guadagnà soldi, allora u più prubabile ùn ci sarà micca assai avvirtimenti in u rapportu chì indicanu difetti critichi. In altre parolle, i bug critichi sò digià stati riparati in una manera o in l'altru utilizendu metudi più caru o grazia à i feedback di i clienti. In cunsiquenza, tuttu ciò chì l'analizzatore trova oghje pò esse cunsideratu debitu tecnicu, chì hè impracticable per pruvà à eliminà immediatamente.

Pudete dì à PVS-Studio di cunsiderà questi avvisi irrilevanti per avà (salvà u debitu tecnicu per più tardi), è ùn li mostra più. L'analizzatore crea un schedariu speciale induve salva l'infurmazioni nantu à l'errori chì ùn sò micca ancu interessanti. È avà PVS-Studio emette avvisi solu per u codice novu o cambiatu. Inoltre, tuttu questu hè implementatu in modu intelligente. Se, per esempiu, una linea viota hè aghjuntu à u principiu di u schedariu di codice fonte, allura l'analizzatore capisce chì, in fattu, nunda hà cambiatu, è cuntinueghja à esse silenziu. Stu schedariu di marcatura pò esse messu in un sistema di cuntrollu di versione. U schedariu hè grande, ma questu ùn hè micca un prublema, postu chì ùn ci hè nunda di guardà spessu.

Avà tutti i programatori vederanu avvisi ligati solu à u codice novu o cambiatu. Cusì, pudete cumincià à utilizà l'analizzatore, cum'è dicenu, da u ghjornu dopu. È pudete turnà à u debitu tecnicu dopu, è curreghja gradualmente l'errore è cunfigurà l'analizzatore.

Allora, u primu prublema cù l'implementazione di l'analizzatore in un grande prughjettu anticu hè statu risoltu. Avà scopre ciò chì fà cù u debitu tecnicu.

Correzioni di bug è refactorings

A cosa più simplice è naturali hè di mette un pocu di tempu per analizà l'avvertimenti di l'analizzatore massicciamente suppressi è gradualmente trattà cun elli. In un locu duvete riparà l'errore in u codice, in un locu duvete refactor per dì à l'analizzatore chì u codice ùn hè micca problematicu. Esempiu simplice:

if (a = b)

A maiò parte di i compilatori è l'analizzatori C++ si lamentanu di stu codice, postu chì ci hè una alta probabilità chì veramente vulianu scrive. (a == b). Ma ci hè un accordu unspoken, è questu hè di solitu nutatu in a documentazione, chì s'ellu ci sò parentesi supplementari, allora hè cunsideratu chì u programatore hà scrittu deliberatamente tali codice, è ùn ci hè bisognu di ghjurà. Per esempiu, in a documentazione PVS-Studio per i diagnostichi V559 (CWE-481) hè chjaramente scrittu chì a seguente linea serà cunsiderata curretta è sicura:

if ((a = b))

Un altru esempiu. Hè scurdatu in stu codice C++? ruttura o no?

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

L'analizzatore PVS-Studio emetterà un avvisu quì V796 (CWE-484). Questu pò esse micca un errore, in quale casu avete da dà à l'analizzatore un suggerimentu aghjunghjendu l'attributu [[fallthrough]] o per esempiu __attribute__((fallthrough)):

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

Si pò dì chì tali cambiamenti codice ùn risolve u bug. Iè, questu hè veru, ma face duie cose utili. Prima, u rapportu di l'analizzatore elimina i falsi pusitivi. Siconda, u codice diventa più comprensibile per e persone implicate in u so mantenimentu. È questu hè assai impurtante! Per questu solu, vale a pena di fà rifactori minori per fà u codice più chjaru è più faciule da mantene. Siccomu l'analizzatore ùn capisce micca s'ellu "break" hè necessariu o micca, ùn serà ancu chjaru à i so cumpagni di programatori.

In più di correzioni di bug è refactorings, pudete suppressione specificamente avvisi di analizatori ovviamente falsi. Certi diagnostichi irrilevanti ponu esse disattivati. Per esempiu, qualchissia pensa chì l'avvertimenti sò inutili V550 circa paragunà i valori float / doppiu. È certi li classificanu cum'è impurtanti è degni di studiu [7]. Quale avvisi sò cunsiderati pertinenti è quali ùn sò micca, tocca à a squadra di sviluppu di decide.

Ci sò altre manere di suppressione falsi alerti. Per esempiu, u marcatu macro hè statu mintuatu prima. Tuttu chistu hè descrittu in più detail in a documentazione. A più impurtante hè di capiscenu chì, si avvicinassi gradualmente è sistematicamente à travaglià cù falsi pusitivi, ùn ci hè nunda di male. A maiò parte di l'avvirtimenti senza interessu sparisce dopu a cunfigurazione, è solu i lochi chì necessitanu veramente un studiu attentu è alcuni cambiamenti in u codice restanu.

Inoltre, aiutemu sempre i nostri clienti à stallà PVS-Studio in casu di difficultà. Inoltre, ci sò stati casi quandu noi stessi avemu eliminatu falsi avvirtimenti è corrette errori [8]. In casu, aghju decisu di mencionà chì sta opzione per a cooperazione allargata hè ancu pussibule :).

U metudu di ratchet

Ci hè un altru approcciu interessante per migliurà gradualmente a qualità di codice eliminendu l'avvertimentu di l'analizzatore staticu. U fondu hè chì u numeru di avvirtimenti pò solu diminuite.

Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra

U numeru di avvisi emessi da l'analizzatore staticu hè registratu. A porta di qualità hè cunfigurata in tale manera chì avà pudete entre solu un codice chì ùn aumenta micca u numeru di operazioni. In u risultatu, u prucessu di riduce gradualmente u numeru di allarmi principia per aghjustà l'analizzatore è corregge l'errori.

Ancu s'è una persona vole ingannà un pocu è decide di passà a porta di qualità micca per eliminà l'avvirtimenti in u so novu codice, ma per migliurà u vechju codice di terzu, ùn hè micca scantu. Tuttu u listessu, u ratchet gira in una direzzione, è gradualmente u numeru di difetti diminuite. Ancu s'è una persona ùn vole micca riparà i so propri difetti novi, hà sempre bisognu di migliurà qualcosa in u codice vicinu. À un certu puntu, i modi faciuli di riduce u numeru di avvisi finiscinu, è vene un puntu quandu i veri bugs seranu riparati.

Sta metodulugia hè descritta in più detail in un articulu assai interessante di Ivan Ponomarev "Implementa l'analisi statica in u prucessu, piuttostu cà aduprà per truvà bug", chì vi cunsigliu di leghje à tutti quelli chì interessanu à migliurà a qualità di u codice.

L'autore di l'articulu hà ancu un rapportu nantu à questu tema: "Analisi statica cuntinuu".

cunchiusioni

Spergu chì dopu à questu articulu, i lettori seranu più accettati di strumenti di analisi statica è volenu implementà in u prucessu di sviluppu. Sì avete qualchì quistione, simu sempre pronti cunsigliu utilizatori di u nostru analizzatore staticu PVS-Studio è aiutanu cù a so implementazione.

Ci sò altri dubbii tipici nantu à se l'analisi statica pò esse veramente cunvene è utile. Aghju pruvatu à dispelà a maiò parte di sti dubbii in a publicazione "Ragioni per introducà l'analizzatore di codice staticu PVS-Studio in u prucessu di sviluppu" [9].

Grazie per a vostra attenzione è venite скачать è pruvate l'analizzatore PVS-Studio.

Ligami supplementari

  1. Andrey Karpov. Cumu possu vede rapidamente avvisi interessanti chì l'analizzatore PVS-Studio produce per u codice C è C++?
  2. Wikipedia. Teorema di Rice.
  3. Andrey Karpov, Victoria Khanieva. Utilizà l'apprendimentu automaticu in l'analisi statica di u codice fonte di u prugramma.
  4. PVS-Studio. Documentazione. Paràmetri di diagnosticu supplementari.
  5. Andrey Karpov. Caratteristiche di l'analizzatore PVS-Studio cù l'esempiu di EFL Core Libraries, 10-15% falsi pusitivi.
  6. PVS-Studio. Documentazione. Suppressione di massa di i missaghji di l'analizzatore.
  7. Ivan Andryashin. Circa cumu avemu pruvatu l'analisi statica nantu à u nostru prughjettu di un simulatore educativu di chirurgia endovascular di raghji X.
  8. Pavel Eremeev, Svyatoslav Razmyslov. Cumu a squadra PVS-Studio hà migliuratu u codice Unreal Engine.
  9. Andrey Karpov. Motivi per intruduce l'analizzatore di codice staticu PVS-Studio in u prucessu di sviluppu.

Cumu implementà un analizzatore di codice staticu in un prughjettu legatu senza demotivà a squadra

Se vulete sparte stu articulu cù un publicu anglofonu, per piacè utilizate u ligame di traduzzione: Andrey Karpov. Cumu intruduce un analizatore di codice staticu in un prughjettu legatu è micca di scuraggià a squadra.

Source: www.habr.com

Add a comment