2009-03-12 9 views
29

La nostra gestione ha recentemente parlato con alcune persone che vendono C++ static analysis tools. Ovviamente gli addetti alle vendite dicono che troveranno tonnellate di insetti, ma sono scettico.Gli strumenti di analisi del codice statico C++ ne valgono la pena?

Come funzionano tali strumenti nel mondo reale? Trovano veri bug? Aiutano i programmatori più giovani a imparare?

Ne vale la pena?

+4

John Carmack ha recentemente scritto su questo: http://altdevblogaday.com/2011/12/24/static-code-analysis/ –

+0

John Carmack. Analisi del codice statico. Nuovo collegamento: http://www.viva64.com/en/a/0087/ –

+0

@DavidNorman: eseguono tutti i file solo in base all'analisi dei file, quindi se si desidera analizzare come le funzioni interagiscono tra i file di origine, è necessario assumere diversi popoli * (dal momento che quegli strumenti non sono in grado di eseguire l'intera analisi del programma) *. – user2284570

risposta

2

Pagare la maggior parte degli strumenti di analisi statici non è probabilmente necessario quando ci sono alcuni gratuiti di buona qualità (a meno che non si abbia bisogno di funzionalità speciali o specifiche fornite da una versione commerciale). Ad esempio, vedere questa risposta che ho dato su un'altra domanda su cppcheck.

4

Li ho usati - PC-Lint, ad esempio, e hanno trovato alcune cose. In genere sono configurabili e si può dire loro "smettetela di preoccuparmi di xyz", se si determina che xyz in realtà non è un problema.

Non so che aiutano i programmatori junior a imparare molto, ma possono essere utilizzati come un meccanismo per semplificare il codice.

Ho scoperto che una seconda serie di scatti (scettici, probing for bug) per gli occhi e il test delle unità è in genere in cui ho visto che si verificano più catture.

+5

Quando ho usato PC-Lint su un progetto C++, ho attivato gli avvisi efficaci C++/Altri efficaci in C++ e rileggerei la sezione del libro quando ho violato una delle regole. Questo mi ha davvero aiutato a capire queste regole in un contesto reale. L'ho trovato molto utile. – Trent

5

Aiuta. Suggerirei di prendere una versione di prova e farla funzionare attraverso una parte del codice base che si ritiene trascurata. Questi strumenti generano molti falsi positivi. Una volta superati questi, è probabile che si verifichi un sovraccarico del buffer o due che possa salvare un sacco di dolore nel prossimo futuro. Inoltre, prova almeno due/tre varietà (e anche alcune delle cose di OpenSource).

+0

+1 per suggerire di utilizzare una versione di prova. Stavo per farlo da solo. –

4

Questi strumenti aiutano. Lint è stato un ottimo strumento per gli sviluppatori di C.

Ma un'obiezione che ho è che si tratta di processi batch eseguiti dopo aver scritto una buona quantità di codice e potenzialmente generare molti messaggi.

Penso che un approccio migliore sia quello di costruire una cosa del genere nel tuo IDE e far notare il problema mentre lo stai scrivendo in modo da poterlo correggere subito. Non lasciare che quei problemi entrino nella base del codice in primo luogo.

Questa è la differenza tra lo strumento di analisi statica di FindBug per Java e IntelliJ's Inspector. Preferisco di gran lunga il secondo.

+0

Esiste un plugin Eclipse per FindBugs. –

+0

Avete un esempio di uno strumento di analisi statica interattiva per C++? Non ne ho mai visto uno, ma sarei interessato a vederne uno. – Tom

+0

Sono uno sviluppatore di redlizards.com - creiamo Goanna, uno strumento di analisi statica C/C++ con diverse versioni per l'esecuzione con una build notturna, nonché integrato in un IDE (plug-in VS ed eclipse). Potrebbe valere la pena dare un'occhiata. –

2

Suppongo che dipenda un po 'dal tuo stile di programmazione. Se si scrive principalmente codice C (con la funzionalità occasionale del C++), questi strumenti saranno probabilmente in grado di aiutare (ad esempio gestione della memoria, sovraccarico del buffer, ...). Ma se si utilizzano funzionalità C++ più sofisticate, gli strumenti potrebbero confondersi quando si tenta di analizzare il codice sorgente (o semplicemente non troveranno molti problemi perché le strutture C++ sono solitamente più sicure da usare).

+0

Questo è in linea con la mia esperienza. Quando ho usato PC-Lint 3 o 4 anni fa, era troppo rumoroso, e anche dopo averlo fatto, si lamentava di troppe cose che non erano problemi. –

+0

Questo era in una base di codice che utilizzava caratteristiche C++ piuttosto avanzate. –

28

L'analisi del codice statico vale quasi sempre la pena. Il problema con una base di codice esistente è che probabilmente segnalerà troppi errori per renderlo utile fuori dalla scatola.

Una volta ho lavorato a un progetto che aveva più di 100.000 avvisi dal compilatore ... non ha senso eseguire gli strumenti Lint su quel codice base.

Utilizzare strumenti Lint "giusto" significa acquistare in un processo migliore (che è una buona cosa). Uno dei migliori lavori che ho avuto è stato lavorare in un laboratorio di ricerca in cui non è stato possibile controllare il codice con avvertenze.

Quindi, sì, gli strumenti ne valgono la pena ... a lungo termine. A breve termine, fai in modo che gli avvisi del compilatore siano al massimo e vedi cosa segnala. Se il codice è "pulito", ora è il momento di guardare gli strumenti di sfilacciamento. Se il codice ha molti avvertimenti ... definisci le priorità e risolvile. Una volta che il codice non ha nessuno (o almeno pochissimi) avvisi, guarda gli strumenti di Lint.

Quindi, gli strumenti Lint non aiuteranno una base di codice scadente, ma una volta che avete una buona base di codice può aiutarvi a mantenerla buona.

Edit:

Nel caso del prodotto 100.000 + avvertimento, è stato suddiviso in circa 60 progetti di Visual Studio. Dato che ogni progetto aveva tutti gli avvertimenti rimossi, era stato modificato in modo che gli avvertimenti fossero errori, che impedivano l'aggiunta di nuovi avvertimenti ai progetti che erano stati ripuliti (o piuttosto lasciava che il mio collega gridasse con rancore a qualsiasi sviluppatore che faceva il check-in codice senza compilarlo per primo :-)

+2

Recentemente stavo lavorando a un nuovo prodotto hardware/software presso la mia azienda, ho avuto la fortuna di convincere il responsabile della modifica degli errori del compilatore.Il cambiamento di avvertimenti-errore costrinse tutti a sbarazzarsi di questi avvertimenti. –

+0

Questo cambiamento del compilatore è stato il migliore che ho avuto modo di cambiare il nostro "stile di codifica" e "processi" senza dover inviare un mandato di posta elettronica a tutti. –

+0

Penso che uno dei miei giorni più felici sia stato il controllo del cambiamento in 60 progetti con/W4 su di essi :-) – TofuBeer

1

L'analisi statica che trova bug reali è valsa la pena indipendentemente dal fatto che sia C++ o meno. Alcuni tendono ad essere piuttosto rumorosi, ma se riescono a catturare bug sottili come i confronti firmati/non firmati che causano ottimizzazioni che infrangono il codice o gli accessi agli array fuori limite, ne vale sicuramente la pena.

4

Probabilmente avrete a che fare con una buona quantità di falsi positivi, in particolare se il vostro codice base è grande.

La maggior parte degli strumenti di analisi statica funzionano utilizzando "analisi intra-procedurali", il che significa che considerano ogni procedura separatamente, al contrario di "analisi dell'intero programma" che considera l'intero programma.

Generalmente utilizzano l'analisi "intra-procedurale" perché "l'analisi dell'intero programma" deve considerare molti percorsi attraverso un programma che in realtà non si verificherà mai nella pratica, e quindi può spesso generare risultati falsamente positivi.

L'analisi intra-procedurale elimina tali problemi semplicemente concentrandosi su una singola procedura. Per funzionare, tuttavia, di solito è necessario introdurre un "linguaggio di annotazione" che si usa per descrivere i metadati per gli argomenti della procedura, i tipi di ritorno e i campi dell'oggetto. Per C++ queste cose sono solitamente implementate tramite macro con cui decorare le cose. Le annotazioni quindi descrivono cose come "questo campo non è mai nullo", "questo buffer di stringa è protetto da questo valore intero", "questo campo è accessibile solo dal thread etichettato 'background'", ecc.

L'analisi lo strumento prenderà quindi le annotazioni fornite e verificherà che il codice che hai scritto sia effettivamente conforme alle annotazioni. Ad esempio, se si può potenzialmente passare un valore nullo a qualcosa che è contrassegnato come non nullo, verrà contrassegnato un errore.

In assenza di annotazioni, lo strumento deve assumere il peggio e pertanto segnalerà molti errori che non sono realmente errori.

Poiché sembra che non si stia già utilizzando uno strumento del genere, si dovrebbe presupporre che si debba passare molto tempo ad annotare il codice per eliminare tutti i falsi positivi che verranno inizialmente segnalati. Vorrei eseguire inizialmente lo strumento e contare il numero di errori. Questo dovrebbe darti una stima di quanto tempo hai bisogno di adottarlo nella tua base di codice.

Se lo strumento vale o meno dipende dalla vostra organizzazione. Quali sono i tipi di bug che sei più matto? Sono buffer di sovraccarico? Sono errori di dereferenziazione o di perdita di memoria? Sono problemi di threading? Sono "oops che non abbiamo considerato questo scenario", o "non abbiamo testato una versione cinese del nostro prodotto in esecuzione su una versione lituana di Windows 98?".

Una volta individuati i problemi, è necessario sapere se ne vale la pena.

Lo strumento probabilmente aiuterà con buffer overflow, dereference nullo e bug di perdita di memoria. C'è una possibilità che possa essere d'aiuto con il threading di bug se supporta l'analisi "colorazione del filo", "effetti" o "permessi". Tuttavia, questi tipi di analisi sono piuttosto all'avanguardia e hanno ENORMI oneri notazionali, quindi arrivano con qualche spesa. Lo strumento probabilmente non aiuterà con nessun altro tipo di bug.

Quindi, dipende davvero dal tipo di software che si scrive e dal tipo di bug che si esegue più frequentemente.

+0

Una bella funzionalità di C++, tuttavia, è che le funzioni e i modelli in linea significano molto di informazioni è disponibile in un'unica TU. Pertanto, un buon strumento di analisi statica può eseguire un'analisi inter-procedurale per le funzioni che sono visibili nella TU. –

+0

Il mio punto principale è che questi strumenti hanno costi di adozione potenzialmente elevati e catturano solo bug di classe limitata. Ciò significa che non sono soluzioni "universali". Possono essere cruciali per alcuni progetti e una perdita di tempo per gli altri. Il loro utilizzo dovrebbe essere basato sulle esigenze individuali. –

3

Penso che l'analisi del codice statico valga la pena, se si utilizza lo strumento giusto. Recentemente, abbiamo provato Coverity Tool (un po 'costoso). È fantastico, ha messo in evidenza molti difetti critici, che non sono stati rilevati da filaccia o purificazione.

Inoltre, abbiamo scoperto che avremmo potuto evitare il 35% dei difetti del campo del cliente, se prima avessimo usato la copertura.

Ora, Coverity viene implementato nella mia azienda e quando mai otteniamo un TR cliente nella vecchia versione del software, stiamo eseguendo una copertura contro di esso per far emergere i possibili candelati per il guasto prima di iniziare l'analisi in un momento critico.

10

Nella mia esperienza con un paio di datori di lavoro, Coverity Prevent per C/C++ è stato decisamente utile, trovando alcuni bug anche nel codice di buoni sviluppatori e un sacco di bug nel peggiore codice degli sviluppatori. Altri hanno già affrontato aspetti tecnici, quindi mi concentrerò sulle difficoltà politiche.

In primo luogo, gli sviluppatori il cui codice necessita maggiormente dell'analisi statica, sono i meno propensi a utilizzarlo volontariamente. Quindi temo che avrai bisogno di un solido supporto alla gestione, sia nella pratica che nella teoria; altrimenti potrebbe finire come un semplice elemento di lista di controllo, per produrre metriche impressionanti senza effettivamente correggere bug. Qualsiasi strumento di analisi statica produrrà falsi positivi; probabilmente avrai bisogno di dedicare qualcuno a minimizzare il fastidio da loro, ad esempio, tracciando i difetti, dando priorità alle pedine e modificando le impostazioni. (Uno strumento commerciale dovrebbe essere estremamente bravo a non mostrare mai un falso positivo più di una volta, che da solo potrebbe valerne il prezzo.) Anche i veri difetti potrebbero generare fastidio; il mio consiglio su questo non è di preoccuparsi, per esempio, i commenti al check-in brontolano che ovviamente gli errori distruttivi sono "minori".

Il mio più grande consiglio è un corollario alla mia prima legge, sopra: Prendi prima i colpi a basso costo e guarda i bachi dolorosamente ovvi dei tuoi peggiori sviluppatori. Alcuni di questi potrebbero anche essere stati trovati dagli avvertimenti del compilatore, ma molti bug possono scivolare in queste fessure, ad es. Quando vengono soppressi dalle opzioni della riga di comando. Insetti vistosi possono essere politicamente utili, ad es., Con una Top Ten List dei difetti più divertenti, che possono concentrare le menti meravigliosamente, se usate con attenzione.

+0

Coverity esegue il file solo in base all'analisi dei file, quindi se si desidera analizzare come le funzioni interagiscono tra i file di origine, è necessario assumere più persone * (poiché tali strumenti non sono in grado di eseguire l'analisi completa del programma) *. – user2284570

2

Come con tutto, la risposta dipende ... se si è l'unico sviluppatore che lavora su una stampante a maglia per la nonna, probabilmente non si vorranno acquistare strumenti di analisi statica. Se hai un progetto di dimensioni medie per software che andrà in qualcosa di importante e forse hai un programma molto fitto, potresti voler investire un po 'ora che ti farà risparmiare molto di più in seguito.

Recentemente ho scritto un rant generale su questo: http://www.redlizards.com/blog/?p=29

dovrei scrivere parte 2 non appena il tempo lo permette, ma in generale fare alcuni calcoli approssimativi se ne vale la pena per voi:

  • quanto tempo dedicato al debugging?
  • quante risorse sono associate?
  • quale percentuale avrebbe potuto essere trovata dall'analisi statica?
  • costi per la configurazione dell'utensile?
  • prezzo di acquisto?
  • pace della mente? :-)

La mia opinione personale è anche:

  • ottenere analisi statica nei primi mesi del

    • prime fasi del progetto
    • nelle prime fasi del ciclo di sviluppo
    • presto in molto presto (prima di costruire di notte e test successivi)
  • fornire allo sviluppatore la possibilità di utilizzare l'analisi statica si

    • nessuno piace sentirsi dire da ingegneri di test o di qualche strumento anonimo che cosa hanno fatto di sbagliato ieri
    • meno debug rende uno sviluppatore felice: -)
    • fornisce un buon modo di conoscere le insidie ​​(sottili) senza imbarazzo
5

Come notato da un paio di persone, se si esegue uno strumento di analisi statico pieno di noia sulla maggior parte delle applicazioni, si riceveranno molti avvisi, alcuni potrebbero essere falsi positivi o non portare a un difetto sfruttabile. È quell'esperienza che porta alla percezione che questi tipi di strumenti siano rumorosi e forse una perdita di tempo. Tuttavia, ci sono avvertenze che metteranno in luce difetti reali e potenzialmente pericolosi che possono portare a problemi di sicurezza, affidabilità o correttezza e per molti team, questi problemi sono importanti da risolvere e potrebbero essere quasi impossibili da scoprire tramite test.

Detto questo, gli strumenti di analisi statica possono essere estremamente utili, ma applicarli a una base di codice esistente richiede una piccola strategia. Ecco un paio di suggerimenti che potrebbero aiutarti.

1) Non accendere tutto in una volta, decidere un set iniziale di difetti, attivare quelle analisi e correggerle sulla base di codice.

2) Quando si affronta una classe di difetti, aiutare l'intero team di sviluppo a capire qual è il difetto, perché è importante e come codificare per difendersi da tale difetto.

3) Lavare completamente il codice base di tale classe di difetti.

4) Una volta risolta questa classe di problemi, introdurre un meccanismo per rimanere nello stato di zero issue. Fortunatamente, è molto più facile assicurarti di non reintrodurre un errore se sei su una linea di base senza errori.

0

In un precedente datore di lavoro avevamo Insure ++. Ha aiutato a individuare il comportamento casuale (uso di materiale non inizializzato) che Valgrind non è riuscito a trovare. Ma la cosa più importante: aiutava a rimuovere gli errori che non erano ancora noti come errori.

Insure ++ è buono, ma costoso, è per questo che abbiamo acquistato solo una licenza utente.

2

Questo risultato piuttosto sorprendente è stato ottenuto utilizzando Elsa e Oink.

http://www.cs.berkeley.edu/~daw/papers/fmtstr-plas07.pdf

"Large-Scale Analisi del formato di stringa di vulnerabilità in Debian Linux" di Karl Chen, David Wagner, UC Berkeley, {quarl, daw}@cs.berkeley.edu

Abstract:

I bug di stringa di formato sono una vulnerabilità di sicurezza relativamente comune e possono portare all'esecuzione di codice arbitrario. In collaborazione con altri, abbiamo progettato e implementato un sistema per eliminare le vulnerabilità delle stringhe di formato da un'intera distribuzione Linux, utilizzando inferenza di tipo più precisa, una tecnica di analisi statica in grado di trovare violazioni di contaminazione. Analizziamo con successo il 66% dei pacchetti sorgente C/C++ nella distribuzione Linux di Debian 3.1. Il nostro sistema trova gli avvertimenti per il filtraggio delle stringhe in formato 1.533. Stimiamo che l'85% di questi sono veri positivi, cioè veri bug; ignorando i duplicati dalle biblioteche, circa il 75% sono dei veri bug. Suggeriamo che la tecnologia esista per rendere estinte le vulnerabilità delle stringhe di formato nel prossimo futuro.

Categorie e descrittori degli oggetti D.4.6 [Sistemi operativi]: protezione e protezione; software invasivo; Condizioni generali: sicurezza, lingue; Parole chiave: Vulnerabilità di stringa di formato, analisi su larga scala, inferenza di tipo Qualifica

Problemi correlati