2011-08-22 6 views
5

Attualmente mi trovo di fronte a uno dei bug più malvagi che abbia mai affrontato in un grande e complesso progetto su cui sta lavorando la mia squadra. Stiamo usando C++ come linguaggio di programmazione e attualmente Visual Studio per lo sviluppo, sebbene il prodotto finale sia destinato a funzionare su più piattaforme.Descrivere e trovare un bug corrotto dallo stato che causa arresti apparentemente casuali

Il bug:

C'è un bug nel nostro sistema che fa scattare gli arresti in punti apparentemente casuali di esecuzione. Le cause di crash di solito sono violazioni degli accessi in lettura degli indirizzi che cambiano ogni volta che il programma viene eseguito. A volte otteniamo anche errori di danneggiamento dell'heap. Gli stack di chiamate ci portano a punti variabili nel nostro codebase e raramente a qualche libreria esterna (Lua nel nostro caso), dove il bug chiaramente non mente.

Sembra che questo bug si sia sviluppato negli ultimi 4 mesi. Quel periodo di tempo fa, all'incirca, alcuni membri del mio team hanno visto il programma di frontend in crash in modi e luoghi molto simili a quello che succede ora.

Alcuni dettagli:

La nostra base di codice è di circa 800K linee di puro C++ (commenti escluse) grande, ed è stato sviluppato nel corso di 3 anni. Il progetto attuale pesa circa 300K. Abbiamo usato test unitari eccessivi e altri modi per eliminare i bug prima che accadessero, come asserzioni, puntatori intelligenti e così via prima.

Gli altri e ho cercato di trovare questo bug (s) per oltre 2 settimane. Sta diventando più di un incubo per me. In un progetto così complesso, anche il buon vecchio debug di printf sembra fallire di fronte alla complessità che ora ha.

Le mie domande

  • Che tipo di bug siamo di fronte qui? C'è anche un nome per questo? Questo tipo di bug si verifica più o meno spesso in altri progetti di grandi dimensioni?

  • Cosa possiamo fare per trovarlo ed eliminarlo dopo aver trascorso 2 settimane di debug infruttuoso utilizzando varie utilità, su varie piattaforme e con varie impostazioni di compilazione?

(La mia domanda precedente era chiuso, quindi sto cercando di formulare meglio e con più dettagli questa volta, link: https://stackoverflow.com/questions/7154645/how-is-this-kind-of-bug-called)

+0

Arf, i bug sporadici sono i peggiori. È ora di imparare a utilizzare gli strumenti di debug. –

risposta

8

I sintomi che descrivi sono tipici di danneggiamento di heap (non tutte le corruzioni di heap sono segnalate come tali con un messaggio di errore!). Dovrai controllare la durata di tutti gli oggetti nel tuo programma; assicurati di non liberare le cose due volte o di usarle dopo averle liberate e assicurati di non sovraccaricare i buffer. Si consiglia di cogliere questa opportunità per utilizzare cose come std::smart_ptr (o boost::smart_ptr) per automatizzare parti della gestione dell'heap.

Se si utilizza Linux o Mac OS, provare a eseguire il programma in valgrind - rileverà molti errori di danneggiamento dello stack e dello stack. Su Windows, utilizzare application verifier; può aiutare a rendere gli errori più vicini al punto in cui si sono verificati.

Se si utilizzano i thread, è possibile che una condizione di competizione che porta alla distruzione dell'heap. Controlla anche i tuoi meccanismi di blocco.

Se è possibile riprodurre facilmente questo bug e disporre di un sistema di controllo del codice sorgente, considerare una bisezione per determinare esattamente quando è stata introdotta. Cioè, esegui una ricerca binaria sulla tua cronologia del codice sorgente per trovare il primo commit con il bug. Git ha uno strumento per farlo automaticamente - git-bisect - puoi importare una copia del tuo repository in git per eseguire questo strumento se non stai già utilizzando git.

Inoltre, vedere se è possibile disabilitare alcune parti del programma (evitare che il codice in questione venga chiamato) nel tentativo di restringere il problema. Si noti che questo potrebbe avere falsi positivi - se si disabilita il modulo X e si interrompe, potrebbe significare che il modulo X sta corrompendo l'heap, o potrebbe significare che il modulo W ha corrotto l'heap e il modulo X capita di essere bravo a notarlo .

+1

Ottimi punti. Sebbene si noti che bisecare bug sporadici è * molto * difficile. – Owen

+0

@Owen, da qui il "se si può facilmente riprodurre" ...:/ – bdonlan

+0

Ah vero mancato. – Owen

0

Semplicemente complementare all'eccellente risposta di Bdonlan: poiché stai sviluppando il codice per Windows e stai lavorando con grandi progetti, ti consiglio vivamente di acquistare il libro "Advanced Windows Debugging" e di familiarizzare con WinDbg, AppVerifier e altri strumenti simili. Ne varrà la pena l'investimento. Nel libro un intero capitolo è dedicato alla corruzione dell'heap che è (come già detto nella risposta precedente) molto probabilmente il problema che stai affrontando.

Problemi correlati