Come evitare le insidie ​​dell'analisi statica


17

Sto lavorando in un'azienda che otterrebbe 11 punti su Joel Test - almeno sulla carta.

In pratica, tuttavia, nulla funziona esattamente come previsto e il progetto è stato su DEFCON 1 da sei mesi. Ora, la maggior parte dei miei colleghi è felice se possono tornare a casa alle 18:00 - domenica.

Una delle pratiche apparentemente buone che mi hanno colpito perché non funzionante è l'uso di strumenti di analisi statica. Il progetto tiene traccia di entrambi gli avvisi di gcc -Wall e di uno strumento proprietario e molto costoso "C / C ++" .

Gli avvisi Gcc fanno spesso riferimento a bug reali (se la maggior parte delle volte inoffensivi).

Gli strumenti proprietari, tuttavia, elencano cose come i cast impliciti e le dimensioni di una stringa letterale. I cast impliciti sono anche nella lista nera sul loro libro di stile.

La pratica standard è che le persone sono sotto pressione per far tacere ogni singolo avvertimento. Si noti che ciò esclude avvertenze che sono prevalentemente falsi positivi, questo non è il problema.

Il risultato è:

  1. Le persone aggiungono cast di tipi ad ogni valore e ad ogni argomento nascondendo vere e proprie discrepanze di tipo problematico nel processo.
  2. Le persone si presentano con un bug o usano una diversa funzionalità linguistica problematica (strlen invece di sizeof, strncpy invece di strcpy, ecc.)
  3. Gli avvisi sono messi a tacere.
  4. Le segnalazioni di bug iniziano a scorrere.

Il punto principale è che il codice originale stava funzionando e scritto da persone che stavano giocando in modo sicuro nelle loro abilità linguistiche mentre le correzioni non lo erano.

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

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


1
Nota a margine: il GCC oltre a «-Wall» ha anche l'opzione «-Wextra» e ancora più avvertimenti che non sono inclusi per qualche motivo in entrambe le metaopzioni. Consulta i documenti per ulteriori informazioni. In generale ogni opzione ha una menzione se abilitata da una metaoption. Quindi, per trovare tutto ciò che non è abilitato, potresti voler evidenziare in tutti i documenti sia le parole «-Wall» che «-Wextra», e vedresti che non è ancora stato usato.
Ciao Angelo

Aggiungo anche che mi chiedo che il GCC non includa molto di «-Wextra» in «-Wall». Credetemi, alcune di queste bandiere sono molto utili ; almeno questi avvertimenti mi liberano da un'ora di debug.
Ciao Angelo

1
Sono sorpreso che nessuno abbia menzionato recensioni di codice nelle risposte. Per me, le persone che cercano di intrufolarsi in alcuni schifosi hack sarebbero state bloccate dalle recensioni del codice ...
coloranti

Risposte:


16

In pratica, tuttavia, nulla funziona esattamente come previsto e il progetto è stato su DEFCON 1 da sei mesi. Ora, la maggior parte dei miei colleghi è felice se possono tornare a casa alle 18:00 - domenica.

Questa è sicuramente una buona parte del tuo problema. Un ingegnere del software non può lavorare in modo produttivo per più di 40 ore alla settimana. Se vai oltre, fai un grave danno alla tua capacità di lavorare, al punto in cui anche lavorare 80 ore alla settimana porta molto poco valore al progetto e, a volte, i progetti possono persino regredire perché il team introduce più errori di possono aggiustare. Se hai fatto 60 ore / settimana o più per sei mesi, tutta la tua squadra ha bisogno di una buona pausa e tornare a 40 ore / settimana. Non puoi risolvere nulla con una forza lavoro che difficilmente è in grado di colpire la tastiera perché sono così sovraccarichi di lavoro.

Gli strumenti proprietari, tuttavia, elencano cose come i cast impliciti e le dimensioni di una stringa letterale. I cast impliciti sono anche nella lista nera sul loro libro di stile.

È necessario semplicemente abbandonare completamente lo strumento o riconfigurarlo / sostituirlo. Avvertire su ogni cast implicito è di gran lunga troppo difficile da gestire per chiunque.


Potresti fornire un riferimento a una ricerca sul limite di circa 40 ore settimanali?

11
qui e qui , solo per cominciare. È estremamente ben documentato che non è possibile svolgere più di 40 ore settimanali di lavoro produttivo. Un semplice Google ti troverà risme di articoli.
DeadMG

5
Due piccole correzioni importanti ma IMHO: il limite di 40 ore / settimana è un valore medio approssimativo e la regola si applica solo per periodi di tempo prolungati. È OK per una squadra dedicare ore extra prima di una scadenza importante, per poi riprendersi in seguito (magari anche prendendo dei giorni liberi). Inoltre, il limite varia tra le persone e nel tempo: alcuni possono lavorare 43 ore alla settimana senza problemi, altri solo 35 e uno è più produttivo in alcune settimane rispetto ad altri. Tuttavia, fare straordinari straordinari per più di un paio di settimane di seguito causerà davvero seri problemi.
Péter Török,

13

Sto lavorando in un'azienda che otterrebbe 11 punti su Joel Test - almeno sulla carta.

Quel test è solo leggermente rilevante per le società di software. Non capisco l'hype a riguardo. Puoi segnare 12 e avere ancora programmatori di schifezze al 100%. Le persone contano molto più degli strumenti.

Gli strumenti proprietari, tuttavia, elencano cose come i cast impliciti e le dimensioni di una stringa letterale. I cast impliciti sono anche nella lista nera sul loro libro di stile. La pratica standard è che le persone sono sotto pressione per far tacere ogni singolo avvertimento. Si noti che ciò esclude avvertenze che sono prevalentemente falsi positivi, questo non è il problema.

Questo è il problema più grande con tutti gli analizzatori statici: troppi falsi positivi. L' unico modo per gestirlo è apprendere in dettaglio perché lo strumento è stato impostato per dare un avviso per un determinato problema. Solo allora puoi fare ipotesi qualificate sul fatto che un avviso sia falso o meno.

Per il cast specifico di dattiloscritti impliciti, è lì a causa di alcuni bug molto comuni, sottili e pericolosi nel linguaggio C, causati dalle due regole (moroniche) di promozione del tipo implicito in C. Sono formalmente conosciute come regole di promozione di interi e le solite conversioni aritmetiche . Penso che meno di uno su dieci programmatori C professionisti in grado di 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 alla spiegazione di queste pericolose regole di conversione implicita, quindi 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 presenti sul mercato.

Consiglio a qualsiasi programmatore C di leggere quel capitolo MISRA-C, o almeno di Google le due regole di promozione che ho citato e di leggere il più possibile su di loro. Puoi ignorare l'analizzatore statico solo quando sai tutto quello che c'è da sapere su queste regole.

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

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

Non c'è modo semplice per aggirarlo. Il vero problema non è in realtà lo strumento, ma l'oscuro linguaggio C. A prima vista può sembrare un linguaggio semplice, ma ci sono molti meccanismi illogici e strani tra le righe. E ci sono anche centinaia di casi di comportamento non definito / non specificato / impl.specifico nella lingua. Molti di loro devi imparare ed evitare.

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


Ho fatto il test con un pizzico di sale dall'inizio, ma non è uno strumento per testare i programmatori ma uno strumento per testare i datori di lavoro. Immagino che potresti includere colleghi come "i migliori strumenti che il denaro può pagare". E prendo la tua risposta per buttare via gli strumenti SA e assumere e / o addestrare meglio. Il primo punto sembra essere il comune denominatore.

@qpr Non mette alla prova neanche il datore di lavoro, ma solo la volontà del datore di lavoro di spendere soldi per lo sviluppo del software. Cose come la procedura di reclutamento, obiettivi aziendali, conoscenza del mercato ecc. Non sono menzionate. Penso che la maggior parte delle società "bolla IT" segnerebbe 12 su quel test, con un management che non sa nemmeno quali prodotti sono in fase di sviluppo o se esiste un mercato per loro.

4

Non è chiaro se si stia 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 i bug. Forse sarebbe stato meglio concentrarsi maggiormente sui test unitari e sugli strumenti dinamici ... come i controllori di memoria.

È una cattiva idea fare affidamento su uno strumento che genera molti falsi positivi, soprattutto se non è possibile eliminare tali falsi positivi. Incoraggia i programmatori stanchi / oberati di lavoro (o pigri) a fare "correzioni" per far sparire gli avvisi. Se non riesci a sopprimere selettivamente i falsi positivi (ad es. Con commenti) o ad adattare il set di regole, allora hai bisogno di uno strumento migliore. O almeno, dovresti usarlo solo con parsimonia.

Sembra che tu abbia un problema con le persone che sono incuranti e / o fanno errori a causa del superlavoro. Forse avresti dovuto dedicare più tempo / sforzo alle revisioni del codice. Questo indirizza direttamente la tua osservazione che i programmatori non sono geni.

Infine, sembra che potresti aver sofferto entro scadenze non realistiche, risorse povere di risorse e / o requisiti di spostamento. Questo è un problema di gestione e deve essere affrontato a quel livello ... oppure c'è un rischio significativamente elevato di fallimento del progetto e danni a lungo termine alla produttività e al morale del personale.


3

Oltre all'eccellente risposta di user29079, vorrei aggiungere un'altra carenza 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 sta succedendo qualcosa di sospetto. Questo, come concetto, va benissimo: più avvertimenti hai attivato, più cose sospette che scopri.

Ciò che è assolutamente sbagliato , è l'idea che ogni singolo oggetto di pesce debba essere risolto a tutti i costi, modificando il codice . Questo è ciò che ha causato il problema che l'OP sta descrivendo: i tentativi falliti di far precipitare via gli avvisi alterando il codice che funziona perfettamente.

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

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

Un'ottima soluzione a questo dilemma apparentemente impossibile è quella di essere in grado di sopprimere selettivamente un determinato avvertimento su una base di dichiarazione, in modo da poterlo sopprimere proprio lì dove vogliamo indicare che sappiamo davvero cosa stiamo facendo, senza dover modificare qualsiasi codice.

Java ha una buona soluzione a questo, con l' @SuppressWarnings( "" )annotazione. Se stai effettuando, per esempio, una cosiddetta conversione non controllata in java, il compilatore emette un avviso per portarlo alla tua attenzione, lo esamini, stabilisci che questo è uno di quei casi in cui sai cosa stai facendo, quindi precedi l'affermazione offensiva con @SuppressWarnings( "unchecked" )un'annotazione che influisce solo sull'affermazione che la segue immediatamente e procedi con la tua vita.

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

In java è anche possibile aggiungere un prefisso ai singoli parametri per le funzioni @SuppressWarnings(), in modo da disabilitare un avviso 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 dichiarazioni e alcuni compilatori che hanno implementato i propri meccanismi proprietari lo hanno fatto in modo accorto, ad esempio le #pragma warning (nnn:N)direttive di Microsoft C. Il problema con queste direttive è che sono necessarie due righe di direttive per sopprimere un avviso per una singola istruzione e lasciare tale avviso abilitato per le istruzioni che seguono. Pertanto, è improbabile che i programmatori C prendano l'abitudine di sopprimere un avviso sulla base di una singola istruzione, anche quando sanno che questo particolare avviso su questa particolare affermazione va bene.


(*) qualcuno potrebbe obiettare che se lo permetti, allora tutti i programmatori in casa sopprimeranno gli avvisi senza pensarci; la risposta è 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.


In altre parole, mentre si altera la fonte per rimuovere ogni ultimo avvertimento è la chiave della buona pratica, non lo è la modifica del codice compilabile , poiché elimina il codice semplice che è semplicemente corretto senza motivo. Buona distinzione.
Nathan Tuggy,

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 correttamente il team e a definire obiettivi ragionevoli.

Se il software che il tuo team sta scrivendo è qualcosa di fondamentale da cui dipendono le vite umane, gli strumenti di analisi statica sono importanti e utili. Poiché il "costo" di un bug, misurato in denaro (ignorando quanto cinico) sia elevato, sono necessari strumenti speciali per il lavoro. Esistono linee guida sia per il C che per il C ++ per utilizzare in modo sicuro le funzionalità del linguaggio (leggi cosa evitare e quanto fare per evitarlo).
Tuttavia, in una situazione del genere far lavorare i dipendenti domenica è una pessima idea, inoltre, dal contesto che hai fornito, estrapolo che il lavoro sciatto non è raro. Quindi, in questo caso, il problema è molto gravegrande e il tuo management sta cercando di risolverlo usando strumenti "migliori". Sfortunatamente, non è così che funzionano le cose. Se sono anche vicino alla correzione, suggerirei 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 delle prospettive legali.

Se, d'altra parte, il tuo team sta scrivendo qualcosa di molto meno critico, gli strumenti di 'analisi statica' con un alto tasso di falsi positivi ti rallenteranno e, come hai notato, le persone di solito reagiscono a questo trovare il massimo locale nella loro efficacia, in questo caso semplicemente imbrogliare gli avvertimenti, invece di cercare di risolvere il motivo sottostante. Quindi, nella tua situazione, l'utilizzo di questi strumenti può effettivamente deteriorare la qualità del codice sorgente e dovrebbero essere generalmente evitati.

Se hai bisogno di gestire un team di software che sta scrivendo un codice C o C ++, direi innanzitutto quali sono gli obiettivi principali del progetto. Se la scrittura di codice privo di bug è della massima importanza (ad esempio, la nuova fantastica app social per iOS e Android non si adatta a questo), quindi utilizzare l'analisi statica, forse persino andare fino alle specifiche formali e alla verifica formale. Ma in questo caso, scegliere programmatori validi 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 bravi programmatori semplicemente rifiuteranno di farlo regolarmente, a meno che non sappiano di meglio (e se sono bravi, è probabile che loro fanno).

Bottom point: 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) in quanto una (cattiva) gestione potrebbe voler forzarti.


1

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

L'uso di questi tipi di strumenti nelle fasi avanzate del processo di sviluppo è di solito un segno di cattive scelte di progettazione nelle prime fasi del processo.

Nei software non critici, questi tipi di strumenti sono utili per:
-assicurare la gestione, farli sentire utili (abbiamo fatto qualcosa, abbiamo speso molti soldi per sistemare il software). Fornisce loro azioni che sono facili da compiere nelle loro relazioni powerpoint).
-Mantieni occupati gli sviluppatori "tossici". Consenti loro di configurare lo strumento e analizzare i risultati dello strumento, in modo da avere il tempo di correggere i loro cattivi bug.
-imporre le regole di codifica. In tal caso, deve essere utilizzato dal primo giorno. Ma un buon strumento di revisione del codice può 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".


1

Sto lavorando in un'azienda che otterrebbe 11 punti su Joel Test - almeno sulla carta.

La convalida mediante Joel Test non è una misura di buone pratiche; L'invalidazione del Joel Test è tuttavia una misura di pratiche errate / mancanti. In altre parole, può essere visto come necessario, ma non sufficiente.

Ora, la maggior parte dei miei colleghi è felice se possono tornare a casa alle 18:00 - domenica.

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

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

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

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

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

I cast impliciti sono anche nella lista nera sul loro libro di stile.

Sembra un problema di competenza gestionale, non un problema di analisi statica.

Il risultato è:

Le persone aggiungono cast di tipi ad ogni valore e ad ogni argomento nascondendo vere e proprie discrepanze di tipo problematico nel processo.

Le persone si presentano con un bug o usano una diversa funzionalità linguistica problematica (strlen invece di sizeof, strncpy invece di strcpy, ecc.)

Gli avvisi sono messi a tacere.

Le segnalazioni di bug iniziano a scorrere.

Tutti questi sono modi per far apparire bene i report periodici, non modi per risolvere i problemi nel codice (sembra che tu abbia ancora un problema di competenza di gestione).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.