2009-11-04 6 views
5

Sono in una situazione in cui mi viene richiesto di fare almeno qualche sforzo per rimuovere il codice mai usato dal mio codice sorgente. La preferenza generale è usare uno strumento di analisi del codice statico. Abbiamo avuto molta fortuna con questo in altri progetti, ma la gente che ho sentito sono per lo più sviluppatori C/C++ che lavorano sul codice di livello del dispositivo.Quanto bene funziona l'analisi del codice statico con Spring e altre astrazioni?

Sono uno sviluppatore web che lavora su un sistema Java EE. Lo strumento preferito per l'analisi è Coverity Prevent, anche se potrei probabilmente sostenere qualcos'altro se potessi dimostrare che era più appropriato alla tecnologia con cui stiamo sviluppando.

Mi trovo dubbioso: qual è l'efficacia dell'analisi del codice statico per il codice morto, quando si esegue un sistema con molte astrazioni? Ad esempio, utilizziamo l'iniezione delle dipendenze di Spring e JSF. In entrambi i casi, non esiste un modo semplice per tracciare le chiamate di funzione dal front end al back end e creare un'immagine completa di ciò che viene chiamato e cosa no.

Sono molto preoccupato per il fatto che i falsi positivi su un controllo di codice morto superino in primo luogo il valore dell'esecuzione dello strumento.

Qual è l'esperienza con questo scenario? Sei riuscito a ottenere valore da uno strumento di analisi del codice statico quando la tua architettura utilizzava molte astrazioni? C'era qualcosa che dovevi fare per farlo funzionare con un minimo di falsi positivi?

+0

Questo sembra più un tipo di domanda wiki della comunità. –

risposta

4

Ho lavorato in precedenza a Coverity, sul prodotto di analisi statica Java.

Questo particolare compito di trovare il codice guasto può essere perfetto per un analizzatore statico. In particolare per i metodi dead, ovvero per un metodo che non può essere chiamato in fase di runtime, il tasso di falsi positivi sarà molto elevato senza molta sintonizzazione da parte dell'utente per informare l'analizzatore statico su tutti i punti di ingresso dinamici.

Per codice guasto in un metodo, se l'analizzatore dispone di tale capacità, i risultati dovrebbero essere piuttosto buoni, in quanto l'analisi non fornirà alcuna ipotesi sui dati di input. Anche assumendo tutti gli input possibili, è possibile trovare un codice morto in cui la logica correlata impedisce che vengano presi alcuni rami.

0

L'analisi del codice statico in ogni caso deve essere eseguita solo se si comprende completamente il processo di analisi e il codice. Il problema è semplicemente che è solo approssimativo e offre ipotesi. Né una soluzione, né un controllo accurato per le vulnerabilità. Devi riuscire a determinare i falsi positivi con altri metodi di prova.

Il valore di un analizzatore di codice statico non è una revisione del codice. Per eliminare il codice morto, utilizzerei la copertura del codice per il profilo. - Nel tuo caso - hai citato molte astrazioni ... Penso che l'analisi statica del codice non sia abbastanza.

+1

Questo sembra un consiglio terribilmente severo. Quindi nessuno dovrebbe usare Findbug a meno che non comprenda i limiti di un'analisi del flusso di dati? Il prodotto di Coverity è off-limits fino a quando non hai letto i dettagli dell'interpretazione astratta? Se ti piacciono i risultati, seguici. Non è necessario capire esattamente come viene eseguita l'analisi. –

+0

Ma questo è esattamente ciò che intendevo: nessuno dovrebbe usare FindBugs, PMD o qualsiasi cosa relativa all'analisi del codice statico a meno che non abbia familiarità con l'analisi del flusso di dati. Altrimenti le persone tendono a cercare di evitare il rilevamento, ma producono comunque gli stessi bug. Solo i programmatori molto sofisticati possono utilizzare l'analisi del codice statico in modo efficiente per eliminare le vulnerabilità nel codice. Il prodotto che trova il problema non scrive una patch, né è a conoscenza del modello. – wishi

2

È possibile utilizzare gli strumenti di copertura del test (analisi dinamica) per determinare quale codice del proprio sistema è utilizzato; il complemento è un codice che potrebbe essere morto (non è stato eseguito!) e necessita di ispezione (ad esempio, ci possono essere alcuni falsi positivi). Più esercizio offri al tuo sistema, più basso è il tasso di falsi positivi.

Uno strumento di copertura di prova Java in grado di raccogliere questi dati per voi può essere trovato here.

Se si desidera ridurre al minimo i falsi positivi, è possibile considerare di eseguire lo strumento di analisi statica e la copertura del test e di prendere l'intersezione.

In generale, il rilevamento del codice morto X richiede di dimostrare che non esiste alcuna condizione in base alla quale viene richiamato X. E 'difficile (teoricamente impossibile) di fronte a una macchina di Turing e IF dichiarazioni della forma

if (Turing(..)) then call X(); 

che è il motivo per cui strumenti di analisi statica hanno alti tassi di falsi positivi per questo.

In molti casi, tuttavia, il "codice morto" è in realtà solo un codice che semplicemente non ha modo di invocarlo ("codice deactive" nel linguaggio FAA). Cioè, mentre X è definito, non ci sono semplicemente invocazioni di X (o accessi, se X è un elemento di dati) in qualsiasi parte del sistema, direttamente o indirettamente. Questi sono più facili da rilevare per gli strumenti di analisi statica con la complicazione complicata in Java del caricamento e della riflessione della classe dinamica (che rendono impossibile il problema dell'analisi del codice di disattivazione di fronte a classi sconosciute ma caricabili).

Ignorando queste complicazioni, è possibile trovare strumenti di analisi statici che rilevano il codice disattivato in grandi sistemi Java e segnalarlo. Tale strumento deve elaborare l'intero sistema Java contemporaneamente perché altrimenti potrebbe esistere un riferimento nel modulo non incluso nell'analisi. Abbiamo creato un "deactive" code detector and remover in grado di fornire nuovamente il codice sorgente con tutto il codice disattivato rimosso automaticamente, oltre a riportare ciò che non ha referenze. Si ispeziona il report e si decide se si desidera utilizzare il codice ripulito o aggiungere un accesso a un'entità apparentemente inutilizzata.

+0

Le teorie sull'impossibilità dei programmi sono eccessive quando si tratta di strumenti di analisi statica. Il problema dell'arresto è un grosso problema, come riferito dal metodo Turing(), ma si applica all'ottimizzazione dei compilatori e nessuno dubita dell'utilità di un compilatore ottimizzante. Gli strumenti di analisi devono fornire prove per l'utente e gli utenti non crederanno a una complessa catena di prove. Questo lascia il relativamente banale, ma ciò è interessante dal momento che uno strumento può trovare problemi che sono ampiamente disparati nella base di codice, che sarebbe molto difficile da individuare per un umano, ma è abbastanza facile da verificare per un essere umano. –

+0

Non sto criticando gli strumenti di analisi statica (li ho anche io!), Solo osservando quella teoria che garantisce che non possono produrre la risposta giusta in tutte le circostanze. Concordo sul fatto che la risposta corretta è utilizzare gli strumenti di analisi statica perché sono molto più utili in generale a gestire la complessità rispetto alle persone, ma per verificare le risposte. "Fidarsi ma verificare". –

1

Lavorando all'analisi statica, non sono a conoscenza di alcuno strumento di analisi statica che funzioni effettivamente con le astrazioni. Molto probabilmente dovrai scrivere un modulo che si agganci all'analisi del processo e ragioni sul modo in cui usi le astrazioni.

E dubito che la presenza di codice morto costi più di questo.