Analisi statica – dalla conoscenza all'integrazione

Stanco di revisioni di codice interminabili o di debug, a volte ti chiedi come semplificarti la vita. Dando un'occhiata in giro, puoi imbattersi nella magia del termine: "Analisi Statica". Vediamo di cosa si tratta e come può interagire con il tuo progetto.

Analisi statica – dalla conoscenza all'integrazione
In effetti, se scrivi in un linguaggio moderno, anche senza saperlo, hai già passato il tuo codice attraverso un analizzatore statico. Ogni compilatore moderno fornisce, anche se in modo minimale, un insieme di avvisi su potenziali problemi nel codice. Ad esempio, compilando codice C++ in Visual Studio potresti vedere quanto segue:

Analisi statica – dalla conoscenza all'integrazione
In questo output vediamo che la variabile var non è stata utilizzata da nessuna parte nella funzione. Quindi, in realtà, hai quasi sempre utilizzato un semplice analizzatore statico di codice. Tuttavia, a differenza degli analizzatori professionali, come Coverity, Klocwork o PVS-Studio, gli avvisi forniti dal compilatore possono segnalare solo un numero limitato di problemi.

Se non sei sicuro di cosa sia l'analisi statica e come implementarla, leggi questo articolo, per approfondire questa metodologie.

Perché è necessario un'analisi statica?

In poche parole: accelerare e semplificare.

L'analisi statica consente di trovare numerosi problemi nel codice: dal cattivo utilizzo delle strutture del linguaggio fino a 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, nell'ultima riga c'è un errore di battitura. Ad esempio, PVS-Studio emette il seguente avviso:

V537 Considera di rivedere la correttezza dell'uso dell'elemento 'y'.

Se vuoi testare questo errore manualmente, prova l'esempio su Compiler Explorer: *clicca*.

E come puoi capire, non sempre è possibile prestare attenzione a segni simili nel codice immediatamente e per questo si può rimanere bloccati nella debug per un bel po', domandandosi perché tutto funzioni in modo così strano.

Tuttavia, questo è un errore evidente. E se lo sviluppatore ha scritto codice non ottimale perché ha dimenticato un qualche dettaglio del linguaggio? Oppure ha addirittura introdotto nel codice un comportamento indefinito? К сожалению, подобные случаи совершенно обыденны и львиная часть времени тратится на то, чтобы отладить специфично работающий код, который содержит опечатки, типичные ошибки или undefined behavior.

È proprio per queste situazioni che è nato l'analisi statica. Si tratta di un'assistente per gli sviluppatori che segnala diverse problematiche nel codice, spiegando nella documentazione perché non si dovrebbe scrivere in quel modo, quali conseguenze potrebbero derivarne e come porvi rimedio. Ecco un esempio di come potrebbe apparire: *clicca*.

Puoi trovare ulteriori interessanti errori che l'analizzatore può scoprire negli articoli:

Ora, dopo aver letto questo materiale e esserti convinto dei vantaggi dell'analisi statica, potresti volere provare a metterla in pratica. Ma da dove iniziare? Come integrare un nuovo strumento nel progetto attuale? E come far conoscere il tutto al team? Troverai le risposte a queste domande qui sotto.

Nota. L'analisi statica non sostituisce né annulla l'utilità delle revisioni del codice. Essa integra questo processo, aiutando a individuare e correggere in anticipo errori tipografici, imprecisioni e costrutti pericolosi. È molto più produttivo concentrarsi durante le revisioni del codice sugli algoritmi e sulla chiarezza del codice, piuttosto che cercare una parentesi messa male o leggere funzioni di confronto noiose.

0. Introduzione allo strumento

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

Cosa imparerai in questo passaggio:

  • Quali sono i metodi di interazione con l'analizzatore;
  • Se l'analizzatore è compatibile con il tuo ambiente di sviluppo;
  • Quali problemi ci sono attualmente nei tuoi progetti.

Dopo aver installato tutto il necessario, la prima cosa da fare è avviare l'analisi dell'intero progetto (Windows, Linux, macOS). Nel caso di PVS-Studio in Visual Studio vedrai un'immagine simile (cliccabile):

Analisi statica – dalla conoscenza all'integrazione
Il fatto è che solitamente per i progetti con una grande base di codice, gli analizzatori statici producono un'enorme quantità di avvisi. Non è necessario correggerli tutti, poiché il tuo progetto è già funzionante, il che significa che questi problemi non sono critici. Tuttavia, puoi dare un'occhiata ai avvisi più interessanti e correggerli se necessario. Per fare ciò, è necessario filtrare l'output e mantenere solo i messaggi più affidabili. Nel plugin PVS-Studio per Visual Studio, questo avviene filtrando per livelli e categorie di errori. Per un output più accurato, mantenere attivate solo Alto e Generale (cliccabile anche):

Analisi statica – dalla conoscenza all'integrazione
Infatti, rivedere 178 avvisi è decisamente più semplice che migliaia…

Nelle schede Medium e Basso spesso si trovano buoni avvisi, tuttavia in queste categorie sono inclusi anche quei diagnosticamenti che hanno una minore precisione (affidabilità). Maggiori dettagli sui livelli di avvisi e sulle modalità di funzionamento su Windows possono essere consultati qui: *clicca*.

Dopo aver esaminato con successo gli errori più interessanti (e averli corretti con successo), è utile sopprimere gli avvisi rimanenti. Questo è necessario affinché i nuovi avvisi non si perdano tra i vecchi. Inoltre, l'analizzatore statico è un assistente per il programmatore, non un elenco di bug. 🙂

1. Automazione

Dopo il primo incontro, è il momento di configurare i plugin e integrarli nel CI. Questo deve essere fatto prima che gli sviluppatori inizino a utilizzare l'analizzatore statico. Infatti, il programmatore potrebbe dimenticare di attivare l'analisi o semplicemente non volerlo fare. È necessario eseguire un'ultima verifica per garantire che il codice non controllato non possa entrare nel ramo di sviluppo principale.

Cosa imparerai in questa fase:

  • Quali opzioni di automazione offre lo strumento;
  • Se l'analizzatore è compatibile con il tuo sistema di build.

Poiché la documentazione perfetta non esiste, a volte è necessario scrivere a assistenza. È normale, e siamo felici di aiutarti. 🙂

Ora passiamo ai servizi di integrazione continua (CI). Qualunque analizzatore può essere implementato in essi senza problemi significativi. È necessario creare una fase separata nel pipeline, che di solito si trova dopo la compilazione e i test unitari. Questo si fa utilizzando diverse utilità da console. Ad esempio, PVS-Studio fornisce le seguenti utilità:

Per integrare l'analisi nel CI è necessario seguire tre passaggi:

  • Installare l'analizzatore;
  • Eseguire l'analisi;
  • Consegna dei risultati.

Ad esempio, per installare PVS-Studio su Linux (basato su 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

Nei sistemi basati su Windows non è possibile installare l'analizzatore tramite il gestore di pacchetti, ma è possibile eseguire l'analizzatore tramite la riga di comando:

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

Per ulteriori informazioni su come implementare PVS-Studio nei sistemi Windows, è possibile leggere *qui*.

Dopo l'installazione, è necessario avviare l'analisi. Tuttavia, si consiglia di farlo solo dopo che la compilazione e i test sono stati completati. Questo è dovuto al fatto che l'analisi statica richiede generalmente il doppio del tempo rispetto alla compilazione.

Poiché il modo di avvio dipende dalla piattaforma e dalle specifiche del progetto, mostrerò un esempio 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, mentre il secondo converte il rapporto in formato testo, lo visualizzerà a schermo e restituirà un codice di uscita diverso da 0 in caso di avvisi. Un meccanismo simile è utile per bloccare la build in presenza di messaggi di errore. Tuttavia, puoi sempre rimuovere il flag -w e non bloccare la build contenente avvisi.

Nota. Il formato testo è scomodo. È fornito solo come esempio. Nota un formato di rapporto più interessante: FullHtml. Esso consente di navigare nel codice.

Puoi leggere di più sulla configurazione dell'analisi su CI nell'articolo "PVS-Studio e Continuous Integration" (Windows) o "Come configurare PVS-Studio in Travis CI" (Linux).

Bene, hai configurato il funzionamento dell'analizzatore sul server di build. Ora, se qualcuno ha caricato codice non verificato, il passo di verifica fallirà e potrai scoprire il problema, anche se non è molto conveniente, poiché è più efficace controllare il progetto non dopo la fusione dei branch, ma prima, durante la fase della pull request.

In generale, la configurazione dell'analisi delle pull request non differisce molto dall'esecuzione di un'analisi normale su CI, tranne per la necessità di ottenere un elenco dei file modificati. Di solito, questi possono essere ottenuti richiedendo la differenza tra i rami tramite git:

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

Ora è necessario passare questo elenco di file all'analizzatore. Ad esempio, in PVS-Studio ciò è realizzato tramite un flag -S:

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

Per saperne di più sull'analisi delle pull request, puoi consultare *qui*. Anche se il tuo CI non è nell'elenco dei servizi indicati nell'articolo, ti sarà utile la sezione generale dedicata alla teoria di questo tipo di analisi.

Configurando l'analisi delle pull request, potrai bloccare i commit contenenti avvisi, creando così un confine che il codice non verificato non potrà oltrepassare.

Tutto ciò è sicuramente positivo, tuttavia sarebbe utile poter visualizzare tutti gli avvisi in un unico posto. Non solo da parte dell'analizzatore statico, ma anche da unit test o da analizzatori dinamici. A questo scopo esistono diversi servizi e plugin. PVS-Studio, ad esempio, ha un plugin per l'integrazione con SonarQube.

2. Integrazione sui computer degli sviluppatori

È giunto il momento di installare e configurare l'analizzatore per l'uso quotidiano durante lo sviluppo. A questo punto, hai già familiarizzato con la maggior parte dei metodi di lavoro, quindi possiamo considerare questa la parte più semplice.

Come soluzione più semplice, gli sviluppatori possono installare autonomamente l'analizzatore necessario. Tuttavia, questo richiederà molto tempo e li allontanerà dallo sviluppo. Puoi quindi automatizzare questo processo utilizzando l'installer e i flag necessari. Per PVS-Studio ci sono diversi flag per l'installazione automatizzata. Tuttavia, ci sono sempre gestori di pacchetti, come Chocolatey (Windows), Homebrew (macOS) o decine di opzioni per Linux.

Dopodiché, sarà necessario installare i plugin richiesti, ad esempio per Visual Studio, IDEA, Rider ecc.

3. Uso quotidiano

A questo punto è il momento di dire poche parole sui modi per accelerare il funzionamento dell'analizzatore durante l'uso quotidiano. L'analisi completa di un intero progetto richiede molto tempo, ma quanto spesso cambiamo il codice di tutto il progetto contemporaneamente? È raro che ci sia una refattorizzazione così ampia da interessare immediatamente l'intera base di codice. Il numero di file modificati contemporaneamente raramente supera la decina, quindi ha senso analizzarli. In situazioni simili esiste la modalità di analisi incrementale. Ma non spaventatevi, non è un altro strumento. È una modalità speciale che permette di analizzare solo i file modificati e le loro dipendenze, il che avviene automaticamente dopo la compilazione, se si lavora in un IDE con il plugin installato.

Nel caso in cui l'analizzatore rilevi problemi nel codice recentemente modificato, vi informerà autonomamente. Ad esempio, PVS-Studio vi avviserà con una notifica:

Analisi statica – dalla conoscenza all'integrazione
Non è sufficiente dire agli sviluppatori di utilizzare lo strumento. È necessario spiegare loro cosa sia e come si utilizzi. Ad esempio, ci sono articoli sul rapido avvio di PVS-Studio, ma tutorial simili possono essere trovati per qualsiasi altro strumento che preferite:

Articoli simili forniscono tutte le informazioni necessarie per un utilizzo quotidiano e non richiedono molto tempo. 🙂

Anche durante la fase iniziale di familiarizzazione con lo strumento, abbiamo disattivato molti avvisi durante uno dei primi avvii. Purtroppo, gli analizzatori statici non sono perfetti e ogni tanto generano falsi positivi. Di solito, disattivarli è semplice; ad esempio, nel plugin PVS-Studio per Visual Studio è sufficiente premere un pulsante:

Analisi statica – dalla conoscenza all'integrazione
Tuttavia, non è necessario solo ignorarli. Ad esempio, puoi segnalare un problema al supporto. Se un falso positivo è correggibile, nelle future aggiornamenti potresti notare che, col tempo, i falsi positivi specifici per il tuo codice diminuireanno sempre di più.

Dopo l'integrazione

Siamo giunti alla fine di tutti i passaggi per integrare l'analisi statica nel processo di sviluppo. Sebbene sia fondamentale configurare correttamente tali strumenti nel CI, il luogo principale in cui attivarlo è il computer dello sviluppatore. Infatti, l'analizzatore statico non è un giudice che ti dice da lontano che il tuo codice è inaccettabile. Al contrario, è un assistente che ti avverte se sei stanco e ti ricorda se hai dimenticato qualcosa.

In verità, senza un uso regolare, l'analisi statica probabilmente non semplificherà significativamente lo sviluppo. La sua principale utilità per gli sviluppatori risiede non tanto nella ricerca di sezioni di codice complesse e controverse, quanto nella loro individuazione precoce. Concordate che scoprire un problema quando le modifiche sono già in fase di test non è solo fastidioso, ma anche molto lungo? L'analisi statica, se utilizzata regolarmente, esamina ogni variazione direttamente sul vostro computer e segnala i punti sospetti durante il lavoro sul codice.

E se voi o i vostri colleghi non siete ancora sicuri se implementare un analizzatore, vi propongo di leggere ora l'articolo "Motivi per implementare un analizzatore di codice statico PVS-Studio nel processo di sviluppo". In esso vengono esaminati i timori comuni degli sviluppatori riguardo al fatto che l'analisi statica sottrarrà tempo e così via.

Analisi statica – dalla conoscenza all'integrazione

Se desideri condividere questo articolo con un pubblico anglofono, ti prego di utilizzare il link alla traduzione: Maxim Zvyagintsev. Analisi Statica: Dall'Inizio all'Integrazione.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster