Come evitare le insidie dell'analisi statica

16

Lavoro in un'azienda che segnerà 11 su Joel Test, almeno sulla carta.

In pratica, tuttavia, niente funziona abbastanza bene come previsto, e il progetto è stato su DEFCON 1 per sei mesi. Ora, la maggior parte dei miei colleghi è felice di poter tornare a casa alle 18:00 di domenica.

Una delle pratiche apparentemente buone che mi ha colpito come non funziona è l'uso di strumenti di analisi statica. Il progetto tiene traccia sia degli avvisi gcc -Wall che di uno strumento "C / C ++" proprietario e molto costoso.

Gli avvisi di Gcc fanno più spesso che puntare a bug reali (se la maggior parte del tempo inoffensivi).

Gli strumenti proprietari, tuttavia, elencano cose come i cast impliciti e la dimensione di una stringa letterale. Anche i cast impliciti sono nella lista nera sul loro stylebook.

La pratica standard è che le persone sono costrette a far tacere ogni singolo avvertimento. Nota che questo esclude gli avvisi che sono prevalentemente falsi positivi, non è questo il problema.

Il risultato è:

  1. Le persone aggiungono cast di tipo ad ogni rvalue e ad ogni argomento nascondendo le disallineamenti di tipo problematico reale nel processo.
  2. Le persone si presentano con un bug, o usano una caratteristica linguistica problematica diversa (strlen invece di sizeof, strncpy invece di strcpy, ecc.)
  3. Gli avvisi sono disattivati.
  4. I rapporti sui bug iniziano a rollare.

Il punto principale è che il codice originale era funzionante e scritto da persone che stavano giocando al sicuro con le loro abilità linguistiche mentre le correzioni non lo erano.

Ora, non penso davvero che questa compagnia possa essere salvata. Tuttavia, vorrei sapere se c'è un modo migliore, preferibilmente funzionante, per utilizzare gli strumenti "pro" o se dovrei semplicemente evitare di usarli del tutto nel caso in cui io sia colui che prende la decisione in il futuro.

Una soluzione che non presuppone che tutti i programmatori siano dei geni che non possono sbagliare. Perché bene, se lo sono, quindi non è necessario utilizzare gli strumenti in primo luogo.

    
posta qpr 28.07.2012 - 01:35
fonte

7 risposte

17

In practice, however, nothing works quite as well as expected, and the project has been on DEFCON 1 for half a year. Now, most of my peers are happy if they can go back home at 6pm - on Sunday.

Questa è sicuramente una buona parte del tuo problema. Un ingegnere del software non può lavorare in modo produttivo per più di 40 ore settimanali. Se superi questo, arrechi seri danni alla tua capacità di lavorare - fino al punto in cui persino 80 ore / settimana di lavoro apportano scarso valore al progetto, ea volte i progetti possono persino regredire perché il team introduce più errori di quanti possano risolvere. Se hai fatto 60 ore alla settimana o più per un anno e mezzo, allora tutta la tua squadra ha bisogno di una lunga pausa e di tornare a 40 ore settimanali. Non puoi risolvere qualsiasi cosa con una forza lavoro che difficilmente può colpire la tastiera perché è così oberata di lavoro.

The proprietary tools, however, list things such as implicit casts and sizeof'ing a string literal. Implicit casts are also blacklisted on their stylebook.

Devi davvero abbandonare completamente lo strumento o riconfigurarlo / sostituirlo. L'avviso su tutti i cast impliciti è troppo per chiunque.

    
risposta data 28.07.2012 - 02:47
fonte
13

I'm working at a company that would score 11 on Joel Test - at least on paper.

Questo test è leggermente rilevante per le aziende di software. Non capisco l'hype su di esso. Puoi segnare 12 e avere ancora programmatori di merda al 100%. Le persone contano molto più degli strumenti.

The proprietary tools, however, list things such as implicit casts and sizeof'ing a string literal. Implicit casts are also blacklisted on their stylebook. The standard practice is that people is pressed to make every single warning shut up. Note that this does exclude warnings that are predominantly false positives, this is not the problem.

Questo è il problema più grande con tutti gli analizzatori statici: troppi falsi positivi. Il modo solo per gestirlo è quello di imparare in dettaglio perché lo strumento è stato impostato per fornire un avviso per un determinato problema. Solo in questo modo puoi formulare ipotesi valide sul fatto che un avviso sia falso o meno.

Per il cast specifico di typecasts impliciti, è lì a causa di alcuni bug molto comuni, sottili e pericolosi nel linguaggio C, causati dalle due (morali) regole di promozione implicite del tipo in C. Sono formalmente conosciute come le regole di promozione intera e le solite conversioni aritmetiche . Penso che meno di uno su dieci di tutti i programmatori C professionisti possa spiegare cosa fanno queste due regole e cosa non fanno. Eppure queste regole sono estremamente fondamentali e applicate migliaia di volte tra le righe in qualsiasi normale programma C.

Lo standard MISRA-C ha dedicato un intero capitolo per spiegare queste pericolose regole di conversione implicite, e poi hanno aggiunto numerose regole abbastanza complesse su come evitare i bug causati dalla conversione implicita. Ciò ha avuto un certo impatto su tutti gli analizzatori statici sul mercato.

Suggerirei a qualsiasi programmatore C di leggere quel capitolo MISRA-C, o per lo meno Google le due regole di promozione che ho menzionato e di leggerne il più possibile. Puoi ignorare l'analizzatore statico solo quando sai tutto ciò che c'è da sapere su queste regole.

Now, I don't really think this company can be saved. However, I would like to know if there is a better, preferably working, way to use the "pro" tools or if I should just avoid using them altogether in case I am the one making the decision in the future.

A solution which doesn't assume all programmers are geniuses that can't err. Because well, if they are, then there is no need to use the tools in the first place.

Non esiste un modo semplice per aggirarlo. Il vero problema non è in realtà lo strumento, ma l'oscuro linguaggio C. Può sembrare una lingua facile a una breve occhiata, ma ci sono molti meccanismi illogici e strani che si verificano tra le righe. E ci sono anche centinaia di casi di comportamento indefinito / non specificato / impl.specifico nella lingua. Molti di loro devono imparare ed evitare.

Quindi devi diventare un veterano programmatore C che comprende tutti questi avvisi oscuri, o devi essere in una squadra con almeno una di queste persone. Le aziende che assumono solo un gruppo di programmatori junior senza veterani nel team non dovrebbero usare questi strumenti, né dovrebbero lavorare con lo sviluppo di software ad alta integrità.

    
risposta data 08.08.2012 - 15:54
fonte
5

Non è chiaro se stai chiedendo come risolvere il problema, o come avresti potuto evitarlo in primo luogo. Sto assumendo quest'ultimo.

Sembra che tu abbia fatto affidamento sull'analisi statica come mezzo principale per rilevare ed evitare bug. Forse sarebbe stato meglio concentrarti maggiormente sui test unitari e sugli strumenti dinamici ... come i controller di memoria.

È una cattiva idea affidarsi a uno strumento che genera molti falsi positivi, specialmente se non si riescono a eliminare quei falsi positivi. Incoraggia i programmatori stanchi / oberati di lavoro (o pigri) a fare "correzioni" per far sparire gli avvertimenti. Se non è possibile sopprimere selettivamente i falsi positivi (ad es. Con i commenti) o adattare il set di regole, è necessario uno strumento migliore. O almeno, dovresti usarlo solo con parsimonia.

Sembra che tu abbia un problema con le persone che sono negligenti e / o che commettono errori a causa del troppo lavoro. Forse avresti dovuto dedicare più tempo / impegno alle revisioni del codice. Questo affronta direttamente la tua osservazione che i programmatori non sono dei geni.

Infine, sembra che tu abbia sofferto a causa di scadenze irrealistiche, risorse di persone povere e / o requisiti mutevoli. Questo è un problema di gestione e deve essere affrontato a quel livello ... oppure esiste un rischio significativamente elevato di fallimento del progetto e danni a lungo termine alla produttività e al morale dello staff.

    
risposta data 28.07.2012 - 04:01
fonte
3

Oltre all'eccellente risposta di user29079, vorrei aggiungere un'altra lacuna del linguaggio C che si aggiunge al problema. Non ero a conoscenza di questa mancanza fino a quando non sono passato a Java.

Lo scopo di un avvertimento è di portare all'attenzione dello scrittore e dei futuri lettori del codice il fatto che ci sia qualcosa di strano in corso. Questo, come concetto, è perfetto: più avvisi hai attivato, più cose di pesce che scopri.

Che cosa è sbagliato sbagliato , è la nozione che ogni singolo piccolo pesce deve essere corretto a tutti i costi, modificando il codice . Che è ciò che ha causato il problema che l'OP sta descrivendo: i tentativi falliti di far sì che gli avvisi scompaiano alterando il codice che funziona bene.

Allo stesso tempo, non vogliamo che il nostro codice emetta centinaia di avvertimenti ogni volta che compiliamo, perché molto presto gli avvertimenti diventano privi di significato e nessuno presta più attenzione ai nuovi avvisi.

Quindi, questo sembra essere un caso di obiettivi contrastanti; una contraddizione.

Una soluzione molto buona a questo dilemma apparentemente impossibile è quella di essere in grado di sopprimere selettivamente un certo avvertimento su una dichiarazione per base di istruzioni, in modo da poterlo sopprimere proprio lì dove vogliamo indicare che sappiamo davvero cosa siamo facendo, senza dover modificare alcun codice.

Java ha una bella soluzione a questo, con l'annotazione @SuppressWarnings( "" ) . Se stai facendo, ad esempio, una cosiddetta conversione non controllata in java, il compilatore invia un avvertimento per portarlo alla tua attenzione, lo esamini, stabilisci che questo è uno di quei casi in cui sai cosa stai facendo, quindi precedi l'istruzione incriminata con un'annotazione @SuppressWarnings( "unchecked" ) che influenza solo l'istruzione che la segue immediatamente e procedi con la tua vita.

Quindi, l'avvertimento scompare, il codice rimane inalterato e l'annotazione di soppressione rimane lì, colorata in verde per evidenziazione della sintassi, per documentare il fatto che è in corso una conversione incerta, ma l'autore promette che è buono. (*) Sono tutti felici.

In java puoi persino anteporre singoli parametri alle funzioni con @SuppressWarnings() , in modo da disabilitare un avvertimento specifico che può essere emesso solo su quel parametro specifico.

Tuttavia, per quanto ne so, C non ha mai supportato alcun meccanismo standard per sopprimere selettivamente gli avvisi sulle istruzioni, e alcuni compilatori che implementavano i propri meccanismi proprietari lo facevano in modo accorto, ad esempio le direttive #pragma warning (nnn:N) di Microsoft C Il problema con queste direttive è che sono necessarie due linee di direttive per sopprimere un avviso per una singola istruzione e lasciare questo avviso abilitato per le istruzioni che seguono. Pertanto, è altamente improbabile che i programmatori C prendano l'abitudine di sopprimere un avvertimento su una singola affermazione, anche quando sanno che questo particolare avvertimento su questa particolare affermazione è ok.

(*) qualcuno potrebbe obiettare che se lo permetti, ogni programmatore della casa sopprimerà gli avvertimenti senza dare loro alcun pensiero; la risposta a questo è che puoi fare tutto il possibile per aiutare i programmatori a fare meglio il loro lavoro, ma non c'è niente che puoi fare se decidono attivamente di sabotarti.

    
risposta data 02.12.2015 - 23:20
fonte
2

Direi (senza conoscere i dettagli) che la tua azienda ha commesso errori più significativi e questo è solo il sintomo: non è riuscito a determinare correttamente il dominio del software prodotto, a gestire il squadra correttamente e definire obiettivi ragionevoli.

Se il software che il tuo team sta scrivendo è qualcosa di cruciale da cui dipendono le vite umane, gli strumenti di analisi statici sono importanti e utili. Poiché il "costo" di un bug, misurato in denaro (ignorando quanto è cinico) è elevato, ci sono strumenti speciali necessari per il lavoro. Esistono linee guida per C e C ++ per l'uso sicuro delle funzionalità linguistiche (leggi cosa evitare e quanto lontano andare evitando).
Tuttavia, in una situazione del genere che gli impiegati lavorano domenica è una pessima idea, inoltre dal contesto che hai fornito, estrapolo che il lavoro sciatto non è infrequente. Quindi, se questo è il caso, il problema è molto molto , e il tuo management sta cercando di risolverlo usando strumenti "migliori". Sfortunatamente, non è così che funzionano le cose. Se sono persino vicino a correggere, mi spingerò fino a suggerire che inizi a cercare un lavoro diverso. Il software mission-critical fatto male è qualcosa che può perseguitarti e rovinare la tua reputazione professionale, per non parlare dei potenziali clienti.

Se, d'altra parte, il tuo team sta scrivendo qualcosa che è molto meno critico, gli strumenti di "analisi statica" con un alto tasso di falsi positivi ti rallenteranno e, come hai notato, le persone reagiscono di solito a questo, trovando il massimo locale nella loro efficacia, in questo caso semplicemente ingannando gli avvertimenti, invece di cercare di risolvere il motivo sottostante. Pertanto, nella tua situazione, l'utilizzo di questi strumenti potrebbe effettivamente peggiorare la qualità del codice sorgente e in genere dovrebbe essere evitato.

Se tu devi gestire un team di software che sta scrivendo un codice C o C ++, direi innanzitutto quali sono gli obiettivi principali del progetto. Se scrivere codice privo di bug è della massima importanza (ad esempio, la nuova super fantastica app sociale per iOS e Android non si adatta a questo), quindi utilizzare l'analisi statica, magari arrivare anche alle specifiche formali e verifica formale. Ma se questo è il caso, scegliere i buoni programmatori e farli lavorare in un ambiente sano con un carico di lavoro adeguato e una settimana di 40 ore adeguata è molto più importante.

Le persone non possono lavorare responsabilmente se vengono trattate come schiave (e qualcuno che occupa le mie vacanze è esattamente questo) e i buoni programmatori semplicemente si rifiuteranno di farlo regolarmente, a meno che non sappiano di meglio (e se sono bravi , è probabile che lo facciano).

Punto in basso: calcola i tuoi obiettivi, quindi determina gli strumenti e il processo che utilizzi, non lasciare che gli strumenti disponibili definiscano il processo (ergo gli obiettivi) come se una (cattiva) gestione potesse forzarti.

    
risposta data 28.07.2012 - 03:19
fonte
1

Come affermato nella risposta di k.steff, gli strumenti di analisi statica per "C" sono utili se si sta costruendo software in situazioni critiche (software aereo) e devono essere utilizzati dal primo giorno (non dopo mesi di sviluppo quando un si verifica un errore riproducibile.

L'utilizzo di questi tipi di strumenti in ritardo nel processo di sviluppo è solitamente un segno di scelte progettuali sbagliate all'inizio del processo.

In un software non critico, questi tipi di strumenti sono utili per:
-reassere la gestione, farli sentire utili (abbiamo fatto qualcosa, abbiamo speso un sacco di soldi per riparare il software). Fornisce loro azioni facili da soddisfare nei loro rapporti powerpoint).
-Tenere impegnati gli sviluppatori 'tossici'. Lascia che configurino lo strumento e analizzino i risultati dello strumento, in modo da avere il tempo di correggere i loro brutti bug.
- impone regole di codifica. In tal caso deve essere utilizzato dal primo giorno. Ma un buon strumento per la revisione del codice potrebbe essere una scelta migliore.

Quindi la mia opinione è che devi evitare questo tipo di strumenti costosi e che richiedono tempo, o usarli per tenere occupate le persone "tossiche".

    
risposta data 29.07.2012 - 19:10
fonte
1

I'm working at a company that would score 11 on Joel Test - at least on paper.

La convalida del test di Joel non è una misura delle buone pratiche; Tuttavia, l'invalidazione da parte del test di Joel è una misura di pratiche errate / mancanti. In altre parole, può essere visto come necessario, ma non sufficiente.

Now, most of my peers are happy if they can go back home at 6pm - on Sunday.

Sembra che tu abbia un problema di gestione. Gli straordinari sistematici non sono una soluzione per ottenere risultati; semmai, è una soluzione per rendere le cose come che stanno funzionando e accumulando debito tecnico.

Now, I don't really think this company can be saved. However, I would like to know if there is a better, preferably working, way to use the "pro" tools or if I should just avoid using them altogether in case I am the one making the decision in the future.

Sì, esiste un modo per utilizzare l'analisi del codice statico in modo sensato.

Possono, e di solito forniscono molto valore. Devi solo ricordare che, (come gli avvertimenti del compilatore) uno strumento di analisi statico può (al massimo) fornire suggerimenti su qualcosa che non va, non su segnalazioni di bug e senza certezza.

Sembra che i tuoi responsabili delle decisioni confondano i flag di analisi statica con i difetti dell'applicazione.

Implicit casts are also blacklisted on their stylebook.

Questo sembra un problema di competenza gestionale, non un problema di analisi statica.

The result is:

People add type casts to every rvalue and to every argument hiding real problematic type mismatches in the process.

People introduce off by one bugs, or use a different problematic language feature.(strlen instead of sizeof, strncpy instead of strcpy, etc.)

The warnings are silenced.

The bug reports start rolling in.

Tutti questi sono modi per rendere buoni i report periodici, non i modi per risolvere i problemi nel codice (sembra che tu abbia ancora un problema di competenza gestionale).

    
risposta data 03.12.2015 - 14:26
fonte

Leggi altre domande sui tag