Come eseguire il debug del codice nel modo più efficace? [chiuso]


33

I bug che si insinuano nel codice possono essere minimizzati, ma non completamente eliminati come è scritto - i programmatori sono, sebbene molti non sarebbero d' accordo , solo umani.

Quando rileviamo un errore nel nostro codice, cosa possiamo fare per eliminarlo? Come dovremmo affrontarlo per sfruttare al meglio il nostro tempo prezioso e consentirci di dedicare meno tempo alla ricerca di esso e più tempo alla programmazione? Inoltre, cosa dovremmo evitare durante il debug?

Nota qui che non stiamo parlando di prevenire i bug; stiamo parlando di cosa fare quando i bug non appaiono. Questo è un campo ampio, lo so, e può dipendere fortemente da linguaggio, piattaforma e strumenti. In tal caso, continua a comprendere risposte come mentalità e metodi generali.


La domanda collegata è stata rimossa.

1
Penso che l'approccio sia in realtà semplice. Se lo hai sviluppato da solo, sai tutto al riguardo. È anche possibile correggere il bug senza eseguire il debug. Con questo in mente, il modo migliore è usare il tuo tempo nel programmare qualcos'altro, fino a quando qualcuno che ne sa molto può rispondere alla tua domanda su come risolverlo; o, lascialo riposare, codifica altre cose, fino a quando non ti viene in mente l'idea di risolverlo, così non perderai tempo né energia. Suppongo che la tua domanda riguardi la gestione dei team aziendali.
Aquarius Power il

Penso Raid. Spray per uccisione di insetti. È una domanda filosofica? I libri sono fatti dalla semplice preponderanza ...
ejbytes

Risposte:


38

La mentalità e l'atteggiamento verso il debug è forse la parte più importante, perché determina l'efficacia con cui risolverai l'errore e cosa imparerai da esso - se non altro.

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

Quindi trattalo come un mistero che sarà interessante da decifrare. E spezzare quel mistero dovrebbe essere fatto sistematicamente, esprimendo i nostri presupposti (a noi stessi o agli altri) e quindi testando i nostri presupposti, uno per uno, se necessario, utilizzando tutti gli strumenti a nostra disposizione, in particolare i debugger e i framework di test automatizzati. Quindi, dopo che il mistero è stato risolto, puoi fare ancora meglio cercando in tutto il tuo codice gli errori simili che potresti aver commesso; e scrivere un test automatizzato per garantire che l'errore non si verifichi nuovamente inconsapevolmente.

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 fate dannose e volubili hanno piantato bug nei nostri programmi mentre eravamo guardare, invece di essere lì a causa del nostro pensiero (sciatto): http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1036.html

Potremmo, ad esempio, iniziare con la pulizia della nostra lingua non chiamando più un bug ma chiamandolo un errore. È molto più onesto perché mette esattamente la colpa a cui appartiene, vale a dire. con il programmatore che ha commesso l'errore. La metafora animistica del bug che si insinuava maliziosamente mentre il programmatore non stava guardando è intellettualmente disonesta in quanto nasconde che l'errore è la creazione stessa del programmatore. La cosa bella di questo semplice cambio di vocabolario è che ha un effetto così profondo: mentre, prima, un programma con un solo bug era "quasi corretto", dopo un programma con un errore è semplicemente "sbagliato" (perché in errore).


7
In realtà mi piace il termine "errore" piuttosto che "bug", non perché attribuisca la colpa a "il programmatore che ha commesso l'errore", ma perché chiarisce che potrebbe non essere stato il programmatore in colpa. Per me, "bug" implica un errore nel codice; mentre "errore" implica errore da qualche parte . Forse nel codice, forse nella configurazione dell'ambiente, forse nei requisiti. Mi fa impazzire quando il mio capo ha un "elenco di bug" in cui metà dei problemi sono i cambiamenti dei requisiti. Chiamalo un elenco di attività, ferchrissakes!
Carson63000,

2
+1 per "ogni errore è un'opportunità per imparare, quasi sempre su di te (perché solo i principianti danno la colpa al compilatore / al computer)"
Md Mahbubur Rahman

Sei a conoscenza della storia del termine "bug", giusto? Voglio dire, come usato nello sviluppo di software. Naturalmente, non abbiamo questo problema oggi, ma in realtà un bug è volato nell'hardware di un computer inosservato dal programmatore e ha causato un problema. Per timore che qualcuno pensi di correggermi, so che Edison ha usato questo termine molto prima dell'incidente della falena, motivo per cui ho usato la parola "storia", non "origine". Vedi computerworld.com/article/2515435/app-development/… e en.wikipedia.org/wiki/Software_bug#Etymology
threed

@threed Naturalmente. Ma per un bel po 'di tempo, gli insetti non hanno causato la stragrande maggioranza degli errori del software.
limita il

16
  1. Scrivi test. Il test non è solo ottimo per prevenire i bug (nella mia esperienza, TDD fatto correttamente elimina quasi tutti i bug banali e stupidi), ma aiuta anche molto nel debugging. I test costringono il tuo progetto ad essere 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 che si verifica un caso di test fallito, si può essere ragionevolmente sicuri di aver inchiodato la vera ragione del comportamento che ti dà fastidio.

  2. Scopri come usare un debugger. printle dichiarazioni possono funzionare ragionevolmente bene ad un certo livello, ma il debugger per lo più è molto utile (e una volta che sai come usarlo, è molto più comodo delle printdichiarazioni).

  3. Parla di qualcuno del tuo problema, anche se è solo un papero di gomma . Costringersi ad esprimere il problema su cui si sta lavorando a parole fa davvero miracoli.

  4. Concediti un limite di tempo. Se, ad esempio, dopo 45 minuti senti di non andare da nessuna parte, passa ad altre attività per qualche tempo. Quando torni al tuo bug, si spera che tu possa vedere altre possibili soluzioni che non avresti considerato prima.


2
+1 per "Costringersi ad esprimere il problema su cui si sta lavorando a parole fa davvero miracoli".
Md Mahbubur Rahman

E per aggiungere a (1), quasi tutti i bug che vedi nel codice implicano che c'è un bug - o almeno un'omissione - nella suite di test. Risolvete entrambi allo stesso tempo e non solo dimostrate di aver risolto il problema a portata di mano, ma siete anche sicuri che non venga reintrodotto.
Julia Hayward,

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 correzione del bug copra tutti quei casi.


3

C'è un libro eccellente che ho letto su questo argomento chiamato Why Programs Fail , che delinea varie strategie per trovare bug che vanno dall'applicazione del metodo scientifico per isolare e risolvere un bug, al delugging del debug. 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 provoca un'infezione (3) L'infezione si propaga (4) L'infezione provoca un fallimento.

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

Nella mia esperienza personale, ho trovato molti bug nella nostra applicazione, ma il management semplicemente ci spinge in avanti per ottenere nuove funzionalità. Ho sentito spesso "Abbiamo trovato questo bug da soli e il client non lo ha ancora notato, quindi lascialo fino a quando non lo fanno". Penso che essere reattivi al contrario di proattivi nel correggere i bug sia una pessima idea, poiché quando arriva il momento di risolvere il problema, hai altri problemi che devono essere risolti e più funzioni di gestione vogliono uscire al più presto, quindi rimani sorpreso in un circolo vizioso che può portare a una grande quantità di stress, a esaurirsi e, infine, a un sistema guidato da difetti.

La comunicazione è anche un altro fattore quando vengono rilevati dei bug. Inviare un'e-mail o documentarla sul bug tracker va bene e va bene, ma nella mia esperienza, altri sviluppatori trovano un bug simile e invece di riutilizzare la soluzione che hai messo per correggere il codice (poiché si sono dimenticati di tutto ), aggiungono le loro versioni, quindi hai 5 diverse soluzioni nel tuo codice e di conseguenza sembra più gonfio e confuso. Quindi, quando correggi un bug, assicurati che alcune persone lo esaminino e ti diano un feedback nel caso in cui abbiano risolto qualcosa di simile e abbiano trovato una buona strategia per affrontarlo.

limist ha menzionato il libro, The Pragmatic Programmer, che contiene materiale interessante sulla correzione di bug. Usando l'esempio che ho dato nel paragrafo precedente, guarderei questo: Software Entrophy , in cui viene utilizzata l'analogia di una vedova spezzata. Se compaiono due finestre rotte, la tua squadra potrebbe diventare apatica per non risolverlo mai a meno che non assumi una posizione proattiva.


Ho sentito "Abbiamo trovato questo bug da soli e il client non lo ha ancora notato, quindi lascialo fino a quando non lo fanno" anche troppe volte. E dopo aver visitato il sito, spesso il cliente lo ha notato, ma non lo ha segnalato. A volte perché pensano che non abbia senso perché non sarà riparato, a volte perché stanno già cercando il rimpiazzo di un concorrente, e talvolta (giustamente o erroneamente) "beh, è ​​comunque un mucchio di merda fumante".
Julia Hayward,

@JuliaHayward - Questo è molto spesso il caso, ma nella tua situazione, i tuoi clienti potrebbero essere soddisfatti della funzionalità e non preoccuparsi troppo di ciò che accade sotto il cofano. Il problema inizia a emergere quando il client torna a chiedere funzionalità extra e devi aggiungere altri miglioramenti come rendere la tua app multilingue, mobile blah blah, inizi a guardare ciò che hai e vedere tutte le crepe nel muro.
Desolato pianeta,

Ti mostra solo che tutti i libri del mondo sulla progettazione del software, i test e la buona comunicazione e molti dei prodotti su cui lavori sono un disastro tentacolare. Nonostante sappia cosa è giusto, lo stress e le scadenze non realistiche (di fronte al tuo codice già incasinato) sono le ragioni alla base del perché il codice è nello stato in cui si trova. Non ho alcuna risposta a me stesso, sono abbastanza distinto in ufficio come una faccia lamentosa ****** mentre calcio e grido per mantenere il codice sano e il processo di sviluppo regolare, ma a volte il team non lo fa legare bene insieme.
Desolate Planet,

3

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

  1. Capire qual è la percezione del problema: tradurre da "Bob non è ancora nel sistema" di un cliente in "Quando provo a creare un record utente per Bob, fallisce con un'eccezione chiave duplicata, sebbene Bob non sia già lì dentro'
  2. Scopri se è davvero un problema o solo un malinteso (in effetti, Bob non è lì, non c'è nessuno chiamato bob e insert dovrebbe funzionare).
  3. Cerca di ottenere i passaggi minimi affidabili che puoi seguire per riprodurre il problema, ad esempio "Dato un sistema con un record utente" Bruce ", quando viene inserito un record utente" Bob ", si verifica un'eccezione"
  4. Questo è il tuo test - se possibile, mettilo in un cablaggio di test automatizzato che puoi eseguire ancora e ancora, questo sarà prezioso durante il debug. Puoi anche far parte della tua suite di test per garantire che quel particolare problema non riappaia in seguito.
  5. Ottieni il tuo debugger e inizia a creare punti di interruzione: scopri il percorso del codice quando esegui il test e identifica cosa non va. Mentre lo fai, puoi anche affinare il test rendendolo il più stretto possibile - idealmente un test unitario.
  6. Risolvilo: verifica i passaggi del test.
  7. Verifica che anche il problema originale descritto dal cliente sia risolto (molto importante: potresti aver risolto solo 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 sono evidenti, puoi saltare alcuni di questi passaggi.

Come dovremmo affrontarlo per sfruttare al meglio il nostro tempo prezioso e consentirci di dedicare meno tempo alla ricerca di esso e più tempo alla programmazione?

Ne dubito, poiché implica che scrivere un nuovo codice è una mossa preziosa che avere 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 migliora necessariamente semplicemente aggiungendo più codice ad esso.


questa è la risposta migliore IMO
marcusshep,

3

Mi piacciono la maggior parte delle altre risposte, ma ecco alcuni suggerimenti su cosa fare PRIMA di farlo. Ti farà risparmiare tempo.

  1. Determina se esiste 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 requisito e non esiste alcun bug: solo l'opinione di qualcuno. Mandalo indietro.

  2. Considera la possibilità che il comportamento previsto sia sbagliato. Ciò potrebbe essere dovuto a un'interpretazione errata 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 parte con cui lavori a Berlino).

  4. Se è stato ridotto a due sistemi che collaborano, ispezionare i messaggi tra i due sistemi tramite il monitor del traffico o i file di registro e determinare quale sistema si sta comportando in base alle specifiche e quale no. Se nello scenario sono presenti più di due sistemi, è possibile eseguire controlli a coppie e spostarsi verso il basso nello stack dell'applicazione.

  5. Il motivo per cui isolare il problema è così critico è che il problema potrebbe non essere dovuto a un difetto del codice su cui si ha il controllo (ad esempio sistemi di terze parti o l'ambiente) e si desidera far sì che quella parte prenda il controllo il più rapidamente possibile . Ciò serve sia a risparmiare lavoro che a metterli immediatamente al punto in modo che la risoluzione possa essere raggiunta nel minor tempo possibile. Non vuoi lavorare su un problema per dieci giorni solo per scoprire che è davvero un problema con il servizio web di qualcun altro.

  6. Se si è determinato che esiste davvero un difetto ed è realmente nel codice che si controlla, è possibile isolare ulteriormente il problema cercando l'ultimo build "noto" e ispezionando i registri di controllo del codice per le modifiche che potrebbero 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. Ormai è probabile che tu abbia 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 riproduca il problema e fallisca.

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

  3. Mantenere il test unitario nella suite di test per prevenire / rilevare la regressione.


1

Ecco come lo faccio:

  1. utilizzare 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 modi efficaci per trovare la posizione corretta e la capacità di comprendere tutti i dettagli.
  3. il debug è molto lento e necessario solo se i programmatori non comprendono ancora come il computer esegue le istruzioni asm / non sono in grado di comprendere le pile di chiamate e le cose di base
  4. Prova a sviluppare tecniche di prova come l'uso di prototipi di funzioni per ragionare sul comportamento del programma. Ciò contribuirà a trovare più rapidamente la posizione corretta

1

Quando rileviamo un errore nel nostro codice, cosa possiamo fare per eliminarlo? Come dovremmo affrontarlo per sfruttare al meglio il nostro tempo prezioso e consentirci di dedicare meno tempo alla ricerca di esso e più tempo alla programmazione? Inoltre, cosa dovremmo evitare durante il debug?

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

  1. Descrivere correttamente "l'errore" e identificare gli eventi che lo causano.

  2. Determina se "errore" è un errore di codice o un errore di specifica. Ad esempio, l'immissione di un nome di 1 lettera può essere considerata un errore per alcuni sistemi ma un comportamento accettabile per altri sistemi. A volte un utente segnala un errore che ritiene essere un problema, ma le aspettative dell'utente per il comportamento del sistema non facevano parte dei requisiti.

  3. Se hai dimostrato che si è verificato un errore e l'errore è dovuto al codice, puoi determinare quali parti di codice devono essere riparate per evitare l'errore. Esaminare anche l'effetto del comportamento sui dati attuali e sulle operazioni future del sistema (analisi dell'impatto su codice e dati).

  4. A questo punto probabilmente avresti una stima di quante risorse verranno consumate per correggere il bug. È possibile risolverlo immediatamente 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. È inoltre necessario valutare diverse opzioni disponibili per correggere l'errore. Potrebbe esserci più di un modo. Devi selezionare l'approccio più adatto alla situazione.

  5. Analizzare i motivi che hanno causato la visualizzazione di questo errore (requisiti, codifica, test, ecc.). Applicare processi che impediscano il ripetersi della condizione.

  6. Documentare adeguatamente l'episodio.

  7. Rilascia la correzione (o la nuova versione)

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.