Analisi statica - dall'introduzione all'integrazione

Stanco di infinite revisioni del codice o debugging, a volte pensi a come semplificarti la vita. E dopo aver cercato un po’, o incappandoci per sbaglio, potrete vedere la frase magica: “Analisi statica”. Vediamo di cosa si tratta e come può interagire con il tuo progetto.

Analisi statica - dall'introduzione all'integrazione
In effetti, se scrivi in ​​​​un linguaggio moderno, senza nemmeno rendertene conto, lo fai passare attraverso un analizzatore statico. Il fatto è che qualsiasi compilatore moderno fornisce, anche se in misura minima, una serie di avvertimenti sui potenziali problemi nel codice. Ad esempio, durante la compilazione del codice C++ in Visual Studio potresti vedere quanto segue:

Analisi statica - dall'introduzione all'integrazione
In questo output vediamo che la variabile var non è mai stato utilizzato da nessuna parte nella funzione. Quindi, in realtà, hai quasi sempre utilizzato un semplice analizzatore di codice statico. Tuttavia, a differenza degli analizzatori professionali come Coverity, Klocwork o PVS-Studio, gli avvisi forniti dal compilatore possono indicare solo una piccola gamma di problemi.

Se non sai con certezza cos'è l'analisi statica e come implementarla, leggi questo articoloper saperne di più su questa metodologia.

Perché hai bisogno dell'analisi statica?

In poche parole: accelerazione e semplificazione.

L'analisi statica consente di trovare molti problemi diversi nel codice: dall'uso errato dei costrutti linguistici agli errori di battitura. Ad esempio, invece di

auto x = obj.x;
auto y = obj.y;
auto z = obj.z;

Hai scritto il seguente codice:

auto x = obj.x;
auto y = obj.y;
auto z = obj.x;

Come puoi vedere, c'è un errore di battitura nell'ultima riga. Ad esempio, PVS-Studio emette il seguente avviso:

V537 Valuta la possibilità di verificare la correttezza dell'utilizzo dell'elemento "y".

Se vuoi mettere le mani su questo errore, prova un esempio già pronto in Compiler Explorer: *клик*.

E come capisci, non è sempre possibile prestare attenzione a tali sezioni di codice immediatamente e, per questo motivo, puoi sederti a eseguire il debug per un'ora buona, chiedendoti perché tutto funziona in modo così strano.

Tuttavia, questo è chiaramente un errore. Cosa succederebbe se lo sviluppatore scrivesse un codice non ottimale perché ha dimenticato alcune sottigliezze del linguaggio? O addirittura consentito nel codice comportamento indefinito? Sfortunatamente, questi casi sono del tutto comuni e la maggior parte del tempo viene spesa per eseguire il debug di codice specificamente funzionante che contiene errori di battitura, errori tipici o comportamenti indefiniti.

È per queste situazioni che è apparsa l'analisi statica. Si tratta di un assistente per lo sviluppatore che segnalerà vari problemi nel codice e spiegherà nella documentazione perché non è necessario scrivere in questo modo, cosa può portare e come risolverlo. Ecco un esempio di come potrebbe apparire: *клик*.

Puoi trovare errori più interessanti che l'analizzatore può rilevare negli articoli:

Ora che hai letto questo materiale e sei convinto dei vantaggi dell'analisi statica, potresti provarla. Ma da dove cominciare? Come integrare un nuovo strumento nel tuo progetto attuale? E come presentargli la squadra? Di seguito troverai le risposte a queste domande.

Nota. L'analisi statica non sostituisce né annulla una cosa così utile come le revisioni del codice. Integra questo processo, aiutando a notare e correggere in anticipo errori di battitura, imprecisioni e progetti pericolosi. È molto più produttivo concentrarsi sulle revisioni del codice sugli algoritmi e sulla chiarezza del codice, piuttosto che cercare una parentesi fuori posto o leggere noiose funzioni di confronto.

0. Conoscere lo strumento

Tutto inizia con una versione di prova. In effetti, è difficile decidere di implementare qualcosa nel processo di sviluppo se non hai mai visto lo strumento dal vivo prima. Pertanto, la prima cosa da fare è scaricare versione di prova.

Cosa imparerai in questa fase:

  • Quali sono le modalità per interagire con l'analizzatore;
  • L'analizzatore è compatibile con il vostro ambiente di sviluppo?
  • Quali problemi ci sono attualmente nei tuoi progetti?

Dopo aver installato tutto ciò di cui hai bisogno, la prima cosa da fare è eseguire un'analisi dell'intero progetto (Windows, Linux, macOS). Nel caso di PVS-Studio in Visual Studio vedrai un'immagine simile (cliccabile):

Analisi statica - dall'introduzione all'integrazione
Il fatto è che gli analizzatori statici di solito emettono un numero enorme di avvisi per progetti con una base di codice di grandi dimensioni. Non è necessario risolverli tutti, poiché il tuo progetto sta già funzionando, il che significa che questi problemi non sono critici. Tuttavia, tu puoi guardare gli avvisi più interessanti e correggerli se necessario. Per fare ciò, è necessario filtrare l'output e lasciare solo i messaggi più affidabili. Nel plugin PVS-Studio per Visual Studio, ciò avviene filtrando per livelli di errore e categorie. Per un risultato più accurato, lasciare solo Alta и Generale (anche cliccabile):

Analisi statica - dall'introduzione all'integrazione
In effetti, 178 avvisi sono molto più facili da visualizzare rispetto a diverse migliaia...

Nelle schede Medio и Basso Spesso sono presenti avvisi validi, ma queste categorie includono quelle diagnostiche che hanno meno precisione (affidabilità). Ulteriori informazioni sui livelli di avviso e sulle opzioni per lavorare in Windows possono essere trovate qui: *клик*.

Vale la pena aver esaminato con successo gli errori più interessanti (e averli corretti con successo). eliminare gli avvisi rimanenti. Ciò è necessario affinché i nuovi avvertimenti non si perdano tra quelli vecchi. Inoltre, un analizzatore statico è un assistente per il programmatore e non un elenco di bug. 🙂

1. Automatizzazione

Dopo aver preso confidenza, è il momento di configurare i plugin e integrarli nella CI. Questa operazione deve essere eseguita prima che i programmatori inizino a utilizzare l'analizzatore statico. Il fatto è che il programmatore potrebbe dimenticare di abilitare l'analisi o non volerlo fare affatto. Per fare ciò, è necessario eseguire un controllo finale di tutto in modo che il codice non testato non possa entrare nel ramo di sviluppo generale.

Cosa imparerai in questa fase:

  • Quali opzioni di automazione fornisce lo strumento;
  • L'analizzatore è compatibile con il vostro sistema di assemblaggio?

Poiché la documentazione perfetta non esiste, a volte è necessario scriverla sostegno. Questo è normale e siamo felici di aiutarti. 🙂

Passiamo ora ai servizi di integrazione continua (CI). Qualsiasi analizzatore può essere implementato al loro interno senza seri problemi. Per fare ciò, è necessario creare una fase separata nella pipeline, che di solito si trova dopo la compilazione e i test unitari. Questo viene fatto utilizzando varie utilità della console. Ad esempio, PVS-Studio fornisce le seguenti utilità:

Per integrare l'analisi nella CI, è necessario fare tre cose:

  • Installare l'analizzatore;
  • Eseguire l'analisi;
  • Fornire risultati.

Ad esempio, per installare PVS-Studio su Linux (base Debian), è necessario eseguire i seguenti comandi:

wget -q -O - https://files.viva64.com/etc/pubkey.txt 
    | sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list 
  https://files.viva64.com/etc/viva64.list
  
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio

Sui sistemi che eseguono Windows, non è possibile installare l'analizzatore dal gestore pacchetti, ma è possibile distribuire l'analizzatore dalla riga di comando:

PVS-Studio_setup.exe /verysilent /suppressmsgboxes 
/norestart /nocloseapplications

Puoi leggere ulteriori informazioni sulla distribuzione di PVS-Studio su sistemi che eseguono Windows *qui*.

Dopo l'installazione, è necessario eseguire direttamente l'analisi. Tuttavia, si consiglia di farlo solo dopo aver superato la compilazione e i test. Questo perché l'analisi statica richiede in genere il doppio del tempo rispetto alla compilazione.

Poiché il metodo di avvio dipende dalla piattaforma e dalle funzionalità del progetto, mostrerò come esempio l'opzione per C++ (Linux):

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log
plog-converter -t errorfile PVS-Studio.log --cerr -w

Il primo comando eseguirà l'analisi e il secondo busteconverte il report in formato testo, lo visualizza sullo schermo e restituisce un codice di ritorno diverso da 0 se sono presenti avvisi. Un meccanismo come questo può essere convenientemente utilizzato per bloccare una build quando sono presenti messaggi di errore. Tuttavia, puoi sempre rimuovere il flag -w e non bloccare un assembly che contiene avvisi.

Nota. Il formato del testo è scomodo. Viene fornito semplicemente a titolo di esempio. Presta attenzione a un formato di report più interessante: FullHtml. Ti permette di navigare attraverso il codice.

Puoi leggere ulteriori informazioni sull'impostazione dell'analisi su CI nell'articolo "PVS-Studio e integrazione continua" (Windows) o "Come configurare PVS-Studio in Travis CI" (Linux).

Ok, hai configurato l'analizzatore sul server di compilazione. Ora, se qualcuno ha caricato codice non testato, la fase di verifica fallirà e sarai in grado di rilevare il problema, tuttavia, questo non è del tutto conveniente, poiché è più efficiente controllare il progetto non dopo che i rami sono stati uniti, ma prima di esso, nella fase di pull request.

In generale, impostare un'analisi pull request non è molto diverso dal consueto lancio di un'analisi su CI. Fatta eccezione per la necessità di ottenere un elenco dei file modificati. Questi di solito possono essere ottenuti interrogando le differenze tra i rami usando git:

git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list

Ora devi passare questo elenco di file all'analizzatore come input. Ad esempio, in PVS-Studio questo viene implementato utilizzando il flag -S:

pvs-studio-analyzer analyze -j8 
                            -o PVS-Studio.log 
                            -S .pvs-pr.list

Puoi scoprire di più sull'analisi delle richieste pull *qui*. Anche se il tuo CI non è presente nell'elenco dei servizi menzionati nell'articolo, troverai utile la sezione generale dedicata alla teoria di questo tipo di analisi.

Impostando l'analisi delle richieste pull, è possibile bloccare i commit contenenti avvisi, creando così un limite che il codice non testato non può oltrepassare.

Tutto ciò è certamente positivo, ma mi piacerebbe poter vedere tutti gli avvisi in un unico posto. Non solo dall'analizzatore statico, ma anche dagli unit test o dall'analizzatore dinamico. A questo scopo esistono diversi servizi e plugin. PVS-Studio, ad esempio, ha plugin per l'integrazione in SonarQube.

2. Integrazione sulle macchine degli sviluppatori

Ora è il momento di installare e configurare l'analizzatore per l'uso quotidiano nello sviluppo. A questo punto hai già acquisito familiarità con la maggior parte dei metodi di lavoro, quindi questa può essere definita la parte più semplice.

Come opzione più semplice, gli sviluppatori possono installare da soli l'analizzatore necessario. Tuttavia, ciò richiederà molto tempo e li distrarrà dallo sviluppo, quindi puoi automatizzare questo processo utilizzando un programma di installazione e i flag necessari. Per PVS-Studio ce ne sono diversi flag per l'installazione automatizzata. Tuttavia ci sono sempre dei gestori di pacchetti, ad esempio Chocolatey (Windows), Homebrew (macOS) o decine di opzioni per Linux.

Quindi dovrai installare i plugin necessari, ad esempio per Di Visual Studio, IDEA, Professionisti ecc.

3. Uso quotidiano

A questo punto è il momento di spendere qualche parola sui modi per velocizzare l’analizzatore durante l’uso quotidiano. Un'analisi completa dell'intero progetto richiede molto tempo, ma quanto spesso modifichiamo il codice dell'intero progetto contemporaneamente? Non esiste quasi nessun refactoring così grande da influenzare immediatamente l'intera base di codice. Il numero di file modificati contemporaneamente raramente supera una dozzina, quindi ha senso analizzarli. Perché una situazione del genere esiste modalità di analisi incrementale. Non allarmarti, questo non è un altro strumento. Questa è una modalità speciale che ti consente di analizzare solo i file modificati e le loro dipendenze, e questo avviene automaticamente dopo la creazione se stai lavorando in un IDE con il plugin installato.

Se l'analizzatore rileva problemi nel codice modificato di recente, lo segnalerà in modo indipendente. Ad esempio, PVS-Studio ti informerà di questo tramite un avviso:

Analisi statica - dall'introduzione all'integrazione
Naturalmente, dire agli sviluppatori di utilizzare lo strumento non è sufficiente. Dobbiamo in qualche modo dire loro cos'è e come è. Qui, ad esempio, ci sono articoli su un avvio rapido per PVS-Studio, ma puoi trovare tutorial simili per qualsiasi strumento tu preferisca:

Tali articoli forniscono tutte le informazioni necessarie per l'uso quotidiano e non richiedono molto tempo. 🙂

Già durante la fase di conoscenza dello strumento abbiamo eliminato molti avvisi durante uno dei primi lanci. Sfortunatamente, gli analizzatori statici non sono perfetti, quindi di tanto in tanto danno falsi positivi. Di solito è facile eliminarli; ad esempio, nel plugin PVS-Studio per Visual Studio devi solo fare clic su un pulsante:

Analisi statica - dall'introduzione all'integrazione
Tuttavia, puoi fare di più che limitarti a sopprimerli. Ad esempio, puoi segnalare un problema al supporto. Se il falso positivo può essere corretto, negli aggiornamenti futuri potrai notare che ogni volta ci sono sempre meno falsi positivi specifici per la tua base di codice.

Dopo l'integrazione

Quindi abbiamo attraversato tutte le fasi dell'integrazione dell'analisi statica nel processo di sviluppo. Nonostante l’importanza di impostare tali strumenti su CI, il luogo più importante in cui eseguirli è il computer dello sviluppatore. Dopotutto, un analizzatore statico non è un giudice che dice da qualche parte lontano da te che il codice non va bene. Al contrario, è un assistente che ti dice se sei stanco e ti ricorda se hai dimenticato qualcosa.

È vero, senza un uso regolare, è improbabile che l'analisi statica semplifichi in modo significativo lo sviluppo. Dopotutto, il suo principale vantaggio per uno sviluppatore non risiede tanto nella ricerca di sezioni di codice complesse e controverse, ma nel loro rilevamento tempestivo. Concordo sul fatto che scoprire un problema dopo che le modifiche sono state inviate per il test non è solo spiacevole, ma richiede anche molto tempo. L'analisi statica, se utilizzata regolarmente, esamina ogni modifica direttamente sul tuo computer e segnala i luoghi sospetti mentre lavori sul codice.

E se tu o i tuoi colleghi non siete ancora sicuri se valga la pena implementare l'analizzatore, allora vi suggerisco di iniziare subito a leggere l'articolo "Motivi per introdurre l'analizzatore di codice statico PVS-Studio nel processo di sviluppo". Affronta le preoccupazioni tipiche degli sviluppatori secondo cui l'analisi statica richiederà il loro tempo e così via.

Analisi statica - dall'introduzione all'integrazione

Se desideri condividere questo articolo con un pubblico di lingua inglese, utilizza il link di traduzione: Maxim Zvyagintsev. Analisi statica: dall'inizio all'integrazione.

Fonte: habr.com

Aggiungi un commento