Come eseguire il debug del codice più efficacemente? [chiuso]

33

I bug che si insinuano nel codice possono essere minimizzati, ma non completamente eliminati come è scritto - i programmatori sono, anche se molti sarebbero in disaccordo , solo umani.

Quando rileviamo un errore nel nostro codice, cosa possiamo fare per estirparlo? Come dovremmo affrontarlo per utilizzare al meglio il nostro tempo prezioso e permetterci di dedicare meno tempo a cercare di trovarlo e più tempo a programmare? Inoltre, cosa dovremmo evitare durante il debug?

Nota che non stiamo parlando di prevenire bug; stiamo parlando di cosa fare quando vengono visualizzati i bug do . Questo è un campo molto ampio, lo so, e potrebbe dipendere in gran parte dal linguaggio, dalla piattaforma e dagli strumenti. Se è così, continua a racchiudere risposte come mentalità e metodi generali.

    
posta gablin 09.10.2010 - 18:48
fonte

8 risposte

37

La mentalità e l'attitudine al debugging è forse la parte più importante, perché determina in che misura l'errore viene corretto e cosa imparerai da esso - semmai.

Classici sullo sviluppo di software come The Pragmatic Programmer e Code Complete fondamentalmente sostengono lo stesso approccio: ogni errore è un'opportunità per imparare, quasi sempre su te stesso (perché solo i principianti incolpano prima il compilatore / computer).

Quindi consideralo un mistero che sarà interessante da decifrare. E cracking che il mistero dovrebbe essere fatto sistematicamente, esprimendo le nostre ipotesi (a noi stessi o agli altri) e poi testando le nostre ipotesi, una per una, se necessario, usando ogni strumento a nostra disposizione, specialmente i debugger e le strutture di test automatizzate. Quindi, dopo che il mistero è stato risolto, puoi fare ancora meglio esaminando tutto il codice per errori simili che potresti aver fatto; e scrivi un test automatico per assicurarti che l'errore non si ripresenti inconsapevolmente di nuovo.

Un'ultima nota - preferisco chiamare errori "errori" e non "bug" - Dijkstra ha rimproverato i suoi colleghi per aver usato quest'ultimo termine perché è disonesto, sostenendo l'idea che le fatine pernici e volubili hanno piantato bug nei nostri programmi mentre non stavamo guardando, invece di essere lì a causa del nostro pensiero (sciatto): link

We could, for instance, begin with cleaning up our language by no longer calling a bug a bug but by calling it an error. It is much more honest because it squarely puts the blame where it belongs, viz. with the programmer who made the error. The animistic metaphor of the bug that maliciously sneaked in while the programmer was not looking is intellectually dishonest as it disguises that the error is the programmer's own creation. The nice thing of this simple change of vocabulary is that it has such a profound effect: while, before, a program with only one bug used to be "almost correct", afterwards a program with an error is just "wrong" (because in error).

    
risposta data 09.10.2010 - 20:58
fonte
16
  1. Scrivi test. I test non sono solo ottimi per prevenire i bug (nella mia esperienza, TDD fatto bene elimina quasi tutti i bug insignificanti e stupidi), ma aiuta molto anche nel debugging. I test impongono che il tuo design sia piuttosto modulare, il che rende molto più semplice isolare e replicare il problema. Inoltre, controlli l'ambiente, quindi ci saranno molte meno sorprese. Inoltre, una volta ottenuto un caso di test in errore, puoi essere ragionevolmente sicuro di aver inchiodato il motivo reale del comportamento che ti dà fastidio.

  2. Scopri come utilizzare un debugger. Le dichiarazioni di print possono funzionare abbastanza bene ad un certo livello, ma un debugger per la maggior parte del tempo è molto utile (e una volta che sai come usarlo, è molto più comodo delle dichiarazioni print ).

  3. Parla di qualcuno sul tuo problema, anche se è solo un paperino di gomma . Costringersi a esprimere il problema su cui stai lavorando in parole fa davvero miracoli.

  4. Datti un limite di tempo. Se ad esempio dopo 45 minuti senti di non andare da nessuna parte, passa ad altri compiti per un po 'di tempo. Quando tornerai al tuo bug, spero di riuscire a vedere altre possibili soluzioni che non avresti considerato prima.

risposta data 09.10.2010 - 19:22
fonte
3

Penso che anche la riproduzione di un bug sia importante. Tutti i casi che riproducono il bug possono essere elencati e quindi puoi assicurarti che la tua correzione di bug riguardi tutti quei casi.

    
risposta data 09.10.2010 - 19:52
fonte
3

C'è un eccellente libro che ho letto su questo argomento chiamato Perché i programmi falliscono , che delinea varie strategie per trovare bug che vanno dall'applicazione del metodo scientifico per isolare e risolvere un bug, fino al delta del debugging. L'altra parte interessante di questo libro è che elimina il termine "bug". L'approccio di Zeller è:

(1) Un programmatore crea un difetto nel codice. (2) Il difetto causa un'infezione (3) L'infezione si propaga (4) L'infezione causa un errore.

Se vuoi migliorare le tue capacità di debug, consiglio vivamente questo libro.

Nella mia esperienza personale, ho trovato molti bug nella nostra applicazione, ma la gestione semplicemente ci spinge in avanti per ottenere nuove funzionalità. Ho sentito spesso "Abbiamo trovato questo bug da soli e il cliente non l'ha ancora notato, quindi lasciatelo fino a quando non lo fanno". Penso che essere reattivo contrario a proattivo nel correggere i bug sia una pessima idea come quando arriva il momento di mettere effettivamente una correzione, hai altri problemi che devono essere risolti e più funzioni che la gestione vuole fuori dalla porta al più presto, così sarai catturato in un circolo vizioso che può portare a una grande quantità di stress e bruciare e, infine, un sistema di difetti di guida.

Anche la comunicazione è un altro fattore quando vengono rilevati errori. Inviare un'e-mail o documentarla sul bug tracker va bene e bene, ma nella mia esperienza personale, altri sviluppatori trovano un bug simile e piuttosto che riutilizzare la soluzione che hai messo per sistemare il codice (come hanno dimenticato tutto su di esso ), aggiungono le loro versioni, quindi hai 5 diverse soluzioni nel tuo codice e sembra più gonfio e confuso come risultato. Quindi, quando correggi un bug, assicurati che alcune persone esaminino la correzione e ti forniscano un feedback nel caso in cui abbiano risolto qualcosa di simile e trovato una buona strategia per affrontarlo.

limist ha menzionato il libro The Pragmatic Programmer che contiene materiale interessante sulla correzione dei bug. Usando l'esempio che ho fornito nel paragrafo precedente, darei un'occhiata a questo: Software Entrophy , dove si usa l'analogia di una vedova spezzata. Se compaiono due finestre rotte, la tua squadra potrebbe diventare apatica nei confronti di risolverla, a meno che tu non prenda una posizione proattiva.

    
risposta data 04.09.2011 - 01:24
fonte
3

Bug, errore, problema, difetto - qualunque cosa tu voglia chiamarlo, non fa molta differenza. Mi limiterò al problema poiché è quello a cui sono abituato.

  1. Scopri qual è la percezione del problema: traduci da "Bob non è ancora nel sistema" di un cliente "Quando provo a creare un record utente per Bob, fallisce con un'eccezione chiave duplicata, sebbene Bob non sia ci sono già dentro
  2. Scopri se è davvero un problema o solo un fraintendimento (in effetti, Bob non è lì, non c'è nessuno chiamato bob, e insert dovrebbe funzionare).
  3. Cerca di ottenere passi minimi affidabili che puoi seguire per riprodurre il problema - qualcosa come "Dato un sistema con un record utente" Bruce ", quando viene inserito un record utente" Bob ", allora si verifica un'eccezione"
  4. Questo è il tuo test - se possibile, mettilo in un'imbracatura di test automatizzata che puoi eseguire ancora e ancora, questo sarà inestimabile durante il debug. Puoi anche farne parte della tua suite di test per assicurarti che quel particolare problema non riappaia più tardi.
  5. Scarica il tuo debugger e inizia a mettere i punti di interruzione - scopri il percorso del codice quando esegui il test e identifica ciò che è sbagliato. Mentre lo fai, puoi anche affinare il tuo test rendendolo il più stretto possibile - idealmente un test unitario.
  6. Risolvi il problema - verifica i passaggi di prova.
  7. Verifica anche il problema originale come descritto dal cliente (molto importante - potresti aver corretto un sottoinsieme del problema). Verifica di non aver introdotto regressioni in altri aspetti del programma.

Se hai familiarità con il codice o se il problema o la correzione è ovvio, puoi saltare alcuni di questi passaggi.

How should we approach it to make most effective use of our valuable time and enable us to spend less time trying to find it and more time coding?

Sono contraria a questo, poiché implica che scrivere un nuovo codice sia una mossa importante rispetto a un programma di lavoro di alta qualità. Non c'è niente di sbagliato nell'essere il più efficace possibile nel risolvere i problemi, ma un programma non necessariamente migliora semplicemente aggiungendo altro codice ad esso.

    
risposta data 22.01.2014 - 03:40
fonte
3

Mi piacciono molte delle altre risposte, ma qui ci sono alcuni suggerimenti su cosa fare PRIMA di fare qualsiasi cosa. Ti farà risparmiare tempo prezioso.

  1. Determina se c'è davvero un bug. Un bug è SEMPRE una differenza tra comportamento del sistema e requisiti; il tester dovrebbe essere in grado di articolare il comportamento previsto e reale. Se non è in grado di fornire supporto per il comportamento previsto, non vi è alcun obbligo e non vi è alcun problema, solo l'opinione di qualcuno. Rimandalo indietro

  2. Considera la possibilità che il comportamento previsto sia sbagliato. Ciò potrebbe essere dovuto a un'errata interpretazione del requisito. Potrebbe anche essere dovuto a un difetto del requisito stesso (un delta tra un requisito dettagliato e un requisito aziendale). Puoi anche rispedirli.

  3. Isolare il problema. Solo l'esperienza ti insegnerà il modo più veloce per farlo: alcune persone possono quasi farlo con il loro intestino. Un approccio di base è quello di variare una cosa mantenendo tutte le altre cose costanti (il problema si verifica in altri ambienti? Con altri browser? In una regione di test diversa? In diversi momenti della giornata?) Un altro approccio è quello di esaminare i dump dello stack o messaggi di errore-- a volte puoi dire solo dal modo in cui è formattato quale componente del sistema ha generato l'errore originale (ad esempio se è in tedesco puoi dare la colpa a quella terza con cui lavori a Berlino).

  4. Se lo si è ristretto a due sistemi che collaborano, ispezionare i messaggi tra i due sistemi tramite monitor di traffico o file di registro e determinare quale sistema si sta comportando in base alle specifiche e quale non lo è. Se ci sono più di due sistemi nello scenario, puoi eseguire controlli a coppie e lavorare come "in basso" nello stack di applicazioni.

  5. Il motivo per cui l'isolamento del problema è così importante è che il problema potrebbe non essere dovuto a un difetto nel codice di cui si ha il controllo (ad esempio, sistemi di terze parti o l'ambiente) e si desidera portare tale parte in prendere il più rapidamente possibile. Questo è sia per salvare il lavoro che per ottenere immediatamente il punto in modo che la risoluzione possa essere raggiunta nel più breve tempo possibile. Non vuoi lavorare su un problema per dieci giorni solo per scoprire che si tratta davvero di un problema con il servizio web di qualcun altro.

  6. Se hai determinato che esiste davvero un difetto e che è realmente nel codice che controlli, puoi isolare ulteriormente il problema cercando l'ultima build "nota" e controllando i log di controllo del codice sorgente per le modifiche che potrebbe aver causato il problema. Questo può far risparmiare molto tempo.

  7. Se non riesci a capirlo dal controllo del codice sorgente, ora è il momento di collegare il tuo debugger e scorrere il codice per capirlo. Probabilmente ora hai una buona idea del problema.

Una volta che sai dove si trova il bug e puoi pensare a una correzione, ecco una buona procedura per risolverlo:

  1. Scrivi un test unitario che riproduce il problema e fallisce.

  2. Senza modificare il test dell'unità, fallo passare (modificando il codice dell'applicazione).

  3. Conserva il test dell'unità nella suite di test per prevenire / rilevare la regressione.

risposta data 22.01.2014 - 03:07
fonte
1

Ecco come lo faccio:

  1. usa lo stesso metodo ogni volta per trovare il problema. Ciò migliorerà il tempo di reazione agli errori.
  2. Il modo migliore è probabilmente leggere il codice. Questo perché tutte le informazioni sono disponibili nel codice. Hai solo bisogno di metodi efficaci per trovare la posizione corretta e la capacità di comprendere tutti i dettagli.
  3. il debugging è molto lento e necessario solo se i programmatori non comprendono ancora come il computer esegue istruzioni asm / non può capire stack di chiamate e cose di base
  4. Cerca di sviluppare tecniche di prova come l'utilizzo di prototipi di funzioni per ragionare sul comportamento del programma. Questo aiuterà a trovare la posizione corretta più velocemente
risposta data 04.09.2011 - 03:57
fonte
1

When we do detect an error in our code, what can we do to weed it out? How should we approach it to make most effective use of our valuable time and enable us to spend less time trying to find it and more time coding? Also, what should we avoid when debugging?

Supponendo che ti trovi in un ambiente di produzione, ecco cosa devi fare:

  1. Descrivi correttamente l'errore e identifica gli eventi che lo provocano.

  2. Determina se l'errore è un errore di codice o un errore di specifica. Ad esempio, l'inserimento di un nome di 1 lettera può essere considerato un errore per alcuni sistemi, ma un comportamento accettabile per altri sistemi. A volte un utente segnala un errore che pensa sia un problema ma l'aspettativa dell'utente per il comportamento del sistema non era parte dei requisiti.

  3. Se hai dimostrato che c'è un errore e l'errore è dovuto al codice, puoi determinare quali pezzi del codice devono essere corretti per prevenire l'errore. Esaminare anche l'effetto del comportamento sui dati correnti e sulle operazioni future del sistema (analisi dell'impatto su codice e dati).

  4. A questo punto probabilmente avrai una stima di quante risorse saranno consumate per correggere il bug. È possibile risolverlo subito o pianificare una correzione in una prossima versione del software. Ciò dipende anche dal fatto che l'utente finale sia disposto a pagare per la correzione. Dovresti anche valutare diverse opzioni disponibili per correggere l'errore. Ci possono essere più di un modo. Devi selezionare l'approccio più adatto alla situazione.

  5. Analizza i motivi che hanno causato l'apparizione di questo bug (requisiti, codifica, test, ecc.). Applica i processi che impedirebbero il verificarsi della condizione.

  6. Documenta adeguatamente l'episodio.

  7. Rilascia la correzione (o la nuova versione)

risposta data 04.09.2011 - 02:25
fonte

Leggi altre domande sui tag