2009-04-08 12 views
5

Qual è il tuo modo standard di eseguire il debug di un problema? Questa potrebbe sembrare una domanda abbastanza ampia con alcuni di voi che rispondono "Dipende dal problema", ma penso che molti di noi eseguano il debug di istinto e non abbiano effettivamente provato a formulare il nostro processo. Ecco perché diciamo "dipende".Metodi standard di debug

Ero un po 'costretto a comunicare il mio processo di recente perché alcuni sviluppatori e io stavamo lavorando allo stesso problema e stavamo eseguendo il debug in modi completamente diversi. Volevo che capissero cosa stavo cercando di fare e viceversa.

Dopo alcune riflessioni mi sono reso conto che il mio modo di eseguire il debug è in realtà abbastanza monotono. Prima cercherò di essere in grado di replicare in modo affidabile il problema (soprattutto sul mio computer locale). Quindi attraverso una serie di eliminazioni (e questo è dove penso che sia dipendente dal problema) cercare di identificare il problema.

Gli altri ragazzi stavano cercando di farlo in un modo completamente diverso.

Quindi, mi chiedo cosa ha funzionato per voi ragazzi là fuori? E cosa diresti che il tuo processo è di debug se dovessi formalizzarlo a parole?

A proposito, non abbiamo ancora scoperto il nostro problema =)

+1

Il tuo problema è con il modulo di sincronizzazione, è necessario utilizzare più XML - anche la conversione in JSON è completamente sbagliata. Infine, i tuoi calzini sono dietro al divano –

+0

Sì, mi stavo chiedendo dove fossero =) – Fung

risposta

7

Il mio approccio varia in base alla mia familiarità con il sistema in questione. Tipicamente faccio qualcosa del tipo:

  1. Replicare l'errore, se possibile.
  2. Esaminare lo stato di errore per determinare la causa immediata dell'errore.
  3. Se ho familiarità con il sistema, potrei avere una buona ipotesi su root cause. In caso contrario, comincio a tracciare meccanicamente i dati attraverso il software mentre sfido le ipotesi di base fatte dal software.
  4. Se il problema sembra avere un trigger coerente, è possibile che passi manualmente attraverso il codice con un debugger mentre sfidi le ipotesi implicite che il codice produce.

Tracciare la causa principale è, ovviamente, dove le cose possono diventare pelose. Questo è dove avere una discarica (o meglio, un processo vivo, rotto) può essere davvero inestimabile.

Penso che il punto chiave nel mio processo di debug stia sfidando le pre-concezioni e le ipotesi. Il numero di volte in cui ho trovato un bug in quel componente che io o un collega dovremmo giuro funziona bene è enorme.

I miei amici e colleghi più intuitivi mi hanno detto che sono abbastanza pedante quando mi guardano fare il debug o mi chiedono di aiutarli a capire qualcosa. :)

+0

+1 per preconcetti e ipotesi sfidanti. – Fung

3

Quando mi trovo di fronte un bug che non riesco a sembrare calcolare fuori, mi piace fare un modello del problema. Crea una copia della sezione del codice problema e inizia a rimuovere le funzionalità da esso, una alla volta. Esegui un test unitario contro il codice dopo ogni rimozione. Attraverso questo processo la tua volontà rimuoverà la funzionalità con il bug (e quindi, localizzerà il bug), o avrai isolato il bug in una parte fondamentale del codice che contiene l'essenza del problema. E una volta capito l'essenza del problema, è molto più facile da risolvere.

1

Sono anche un grande fan dell'utilizzo del processo di eliminazione. Escludere le variabili semplifica enormemente l'attività di debug.Spesso è la prima cosa che dovrebbe essere fatta.

Un'altra tecnica davvero efficace è quella di tornare all'ultima versione funzionante, se possibile, e riprovare. Questo può essere estremamente potente perché ti dà una solida base per procedere con maggiore attenzione. Una variazione su questo è di portare il codice a un punto in cui funziona, con meno funzionalità, rispetto a non lavorare con più funzionalità.

Ovviamente, è molto importante non solo provare le cose. Questo aumenta la tua disperazione perché non funziona mai. Preferirei fare 50 run per raccogliere informazioni sull'errore piuttosto che scatenare una folle oscillazione e sperare che funzioni.

2

Di solito inizio partendo da un'ipotesi basata sulle informazioni che ho a portata di mano. Una volta fatto, lavoro per dimostrare che è corretto. Se risulta essere sbagliato, inizio con un'ipotesi diversa.

La maggior parte dei problemi di sincronizzazione multithreading viene risolta facilmente con questo approccio.

Inoltre è necessario avere una buona conoscenza del debugger che si sta utilizzando e delle sue caratteristiche. Lavoro su applicazioni Windows e ho trovato windbg estremamente utile per trovare bug.

+1

Trovo che questo funzioni solo per sviluppatori esperti. Quando i neofiti cercano di farlo sembra più come sparare a caso e sperare di colpirne uno. Credo soprattutto perché manca l'esperienza per iniziare con l'ipotesi più plausibile. Quindi davvero non consiglio questo per i nuovi assunti. – Fung

2

Ridurre il bug nella sua forma più semplice porta spesso a una maggiore comprensione del problema e aggiunge il vantaggio di essere in grado di coinvolgere gli altri se necessario.

Impostare uno scenario di riproduzione rapido per consentire un utilizzo efficiente del proprio tempo per testare qualsiasi ipotesi che si è scelto.

Creazione di strumenti per scaricare rapidamente l'ambiente per i confronti.

Creazione e riproduzione del bug con la registrazione attivata al livello massimo.

Esaminando i registri di sistema per qualsiasi cosa che allarma.

Guardare le date dei file e le marche temporali per avere un'idea se il problema potrebbe essere una recente introduzione.

Guardare attraverso il repository di origine per attività recenti nei moduli pertinenti.

Applicare il ragionamento deduttivo e applicare i principi Ockham's Razor.

Essere disposti a fare un passo indietro e prendere una pausa dal problema.

+0

I bug più crudeli sono quelli che espongono un difetto di progettazione fondamentale. Quelli mi fanno piangere. –

1

Ho scelto quelli sul Web o un libro che non riesco a ricordare (è può sono stati CodingHorror ...)

Debug 101:

  • riprodurre
  • progressivamente ristretto campo
  • Evitare debugger
  • Change Solo una cosa alla volta

metodi psicologici:

  • legno indiani
  • non speculano
  • Non essere troppo pronti a biasimare gli strumenti
  • capire sia problema e la soluzione
  • Take a Break
  • consideri cause multiple

Metodi di prevenzione degli errori:

  • Monit o proprie abitudini Fault Injection
  • Introdurre debug Aids precoce
  • allentato accoppiamento e Information Hiding
  • scrivere un test di regressione per prevenire una nuova insorgenza

metodi tecnici:

  • inerte Trace Dichiarazioni
  • Consultare i file di registro dei prodotti di terzi
  • Cerca nel web per l'analisi dello stack
  • Introdurre Design By Contract
  • tabula rasa
  • Bugs intermittenti
  • Explot Localility
  • Introdurre Dummy Implementazioni e sottoclassi
  • Riconversione/Ricollega
  • Probe Condizioni al contorno e casi speciali
  • Verifica dipendenze versione (terze parti)
  • Controllare il codice che ha cambiato recentemente
  • non si fidano il messaggio di errore
  • grafiche Bugs
+0

In realtà trovo questa risposta abbastanza utile. Non capisco perché è stato contrassegnato -1. – Hexagon

+0

Buona risposta. Fatto +1. Lo chiamiamo "debugging anatra di gomma" da queste parti per evitare sfumature razziste che potrebbero costarti voti negativi. – catbadger

0

Il mio metodo di debugging è diverso, probabilmente perché sto ancora principiante.

Quando incontro un errore logico, sembra che finisca per aggiungere più variabili per vedere quali valori vanno dove e poi vado e eseguo il debug line by line nel pezzo di codice che causa un problema.

0

Replicare il problema e generare un set di dati ripetibile è sicuramente il primo e più importante passo verso il debug.

Se riesco a identificare un errore ripetibile, in genere cercherò di isolare i componenti coinvolti finché non avrò individuato il problema. Frequentemente passerò un po 'di tempo a escludere i casi, così posso affermare in modo definitivo: Il problema non è nel componente X (o nel processo Y, ecc.).

4

Prendere in considerazione il libro "Debugging" di David J Agans. Il sottotitolo è "Le 9 regole indispensabili per trovare anche i problemi software e hardware più elusivi". La sua lista di debug regole - disponibile in una forma poster al sito web (e non c'è un link per il libro, anche) è:

  • capire il sistema
  • farla fallire
  • Uscire da pensare e di guardare
  • Divide et impera
  • cambiare una cosa alla volta
  • Tenere una traccia di verifica
  • Controllare la spina
  • avere una visione fresca
  • Se non risolvere il problema, non è fisso

L'ultimo punto è particolarmente rilevante nel settore del software.

+1

questo è un brillante sommario. – JohnBob

0

Prima di provare a replicare l'errore, senza essere in grado di replicare l'errore è praticamente impossibile in un programma non banale per indovinare il problema.

Quindi, se possibile, suddividere il codice in un progetto autonomo separato. Ci sono diversi motivi per questo: se il progetto originale è grande, è piuttosto difficile eseguire il debug in secondo piano, eliminando o evidenziando qualsiasi ipotesi sul codice.

Normalmente ho sempre un'altra copia di VS aperto che utilizzo per le parti di debug nei mini progetti e per testare routine che successivamente aggiungo al progetto principale.

Dopo aver riprodotto l'errore nel modulo separato, la battaglia è quasi vinta.

A volte non è facile scomporre un pezzo di codice, quindi in quei casi utilizzo metodi diversi a seconda della complessità del problema. Nella maggior parte dei casi le ipotesi sui dati sembrano venire e mordermi, quindi cerco di aggiungere molte affermazioni nel codice per assicurarmi che le mie supposizioni siano corrette. Sto anche disabilitando il codice usando #ifdef fino a quando l'errore non scompare. Eliminando le dipendenze dagli altri moduli, ecc., Sorta di volteggiare lentamente nell'insetto come un avvoltoio.

Penso di non avere un modo cosciente di farlo, varia molto ma il principio generale è per eliminare il rumore intorno al problema fino a quando non è abbastanza ovvio di cosa si tratta. Spero di non sembrare troppo confuso :)

1

Trovo che il momento migliore per "eseguire il debug" è mentre scrivi il codice. In altre parole, sii difensivo. Controlla i valori di ritorno, assumi liberamente, usa una sorta di meccanismo di registrazione affidabile e registra tutto.

Per rispondere più direttamente alla domanda, il modo più efficiente per eseguire il debug dei problemi è leggere il codice. Avere un registro ti aiuta a trovare il codice pertinente da leggere rapidamente.Nessun registro? Passa il tempo a inserirla. Potrebbe non sembrare che stai trovando il bug, e potresti non esserlo. La registrazione potrebbe aiutarti a trovare un altro bug, e alla fine, una volta che hai passato abbastanza codice, lo troverai .... più veloce dell'impostazione dei debugger e cercando di riprodurre il problema, single stepping, ecc.

Durante il debug cerco di pensare a quali potrebbero essere i possibili problemi. Ho trovato un sistema di classificazione abbastanza arbitrario, ma funziona per me: tutti i bug rientrano in una delle quattro categorie. Tieni presente che sto parlando di problemi di runtime, non di compilatori o errori di linker. Le quattro categorie sono:

  • allocazione dinamica della memoria
  • overflow dello stack
  • non inizializzata variabile
  • logica bug

Queste categorie sono stati più utili a me con C e C++, ma io aspetto che si applichino piuttosto bene altrove. La categoria degli errori logici è ampia (ad esempio, inserendo un valore < b quando la cosa corretta era < = b) e può includere elementi come il mancato sincronismo dell'accesso tra i thread.

Sapere cosa sto cercando (una di queste quattro cose) aiuta molto a trovarlo. Trovare bug sembra sempre molto più difficile che risolverli.

dell'attuale meccanismo per il debug sono più spesso:

  1. devo un test automatico che illustra il problema?
    • caso contrario, aggiungere un test che non riesce
  2. Modificare il codice in modo che il test viene superato
  3. assicurarsi che tutte le altre prove ancora passano
  4. controllo nel cambiamento

Nessun test automatico nel tuo ambiente? Non c'è tempo come il presente per configurarlo. Troppo difficile organizzare le cose in modo da poter testare singoli pezzi del tuo programma? Prenditi il ​​tempo per farlo. Potrebbe essere necessario "troppo tempo" per correggere questo bug particolare, ma prima inizierai, più velocemente andrà tutto il resto. Di nuovo, potresti non aggiustare il particolare bug che stai cercando, ma scommetto che trovi e aggiusta gli altri lungo la strada.

Problemi correlati