Cosa fare quando hai esaurito tutte le strade per correggere un bug

13

Sono un programmatore junior (4 mesi di esperienza lavorativa fino ad ora) che lavora su un'applicazione cross platform mobile (team di 1 persona, quindi solo io stesso).

Ho un bug in questo programma / app che è piuttosto grande (30 diversi file header, anch'essi con il proprio file cpp). Ho cercato di rintracciare esattamente cosa sta succedendo con il bug & anche per risolverlo (ho anche provato ad usare alcuni hack per farlo funzionare) ma di circa una dozzina o più di soluzioni (le idee che ho di che cosa sta causando il problema) non ho trovato nulla che mi ha portato a tenere traccia esattamente di ciò che l'errore è o ha corretto il bug.

Hai qualche consiglio per un programmatore junior di alcune tecniche generali (vai a correre, stampa tutto il mio codice su carta e provalo con una penna, ecc.) che potrei usare per aiutarmi con questo bug?

Per dare un po 'più di contesto al mio insetto; coinvolge la piattaforma multipiattaforma API Mosync, quando eseguo una sequenza specifica di azioni, la schermata corrente non ridisegna (e appare) che lo schermo visualizzato in precedenza sta ancora ricevendo il puntatore / premi tasto eventi & non lo schermo corrente.

Sequenza specifica:
- Schermata del menu visualizzata - fare clic su "Mostra il pulsante degli ordini precedenti"
- Schermata Ordini precedenti visualizzata - fai clic su "Carica file" quindi fai clic sul pulsante del menu & apri la schermata di consegna
- Schermata di consegna visualizzata - fare clic sul pulsante del menu & apri la schermata di acquisto - Schermata acquisti visualizzata - Errore qui, l'input a questa schermata non viene visualizzato / reagito a, ElencoVista non scorre, i pulsanti non reagiscono ai clic, le celle ListView non rispondono ai clic

Prenderò il consiglio a bordo, il bug è riproducibile al 100% seguendo sempre gli stessi passi, anche se è ancora molto difficile capire come vengono trasmessi gli eventi puntatore e amp; a quale schermo è dovuto questo fatto che fa parte dell'API che non posso raggiungere (o non so come).

Inoltre mi piacerebbe avere un paio di occhi diversi sul mio lavoro & fai notare il bug, ma come ho detto sono una squadra di 1, il mio capo mi dirige, è proprietario della compagnia & ha le idee per un'app ma non conosce c ++ o nessuna lingua recente (cobal? Penso che sia tutto). Qualche consiglio su come ottenere un secondo paio di occhi senza violare / mostrare il codice / la proprietà intellettuale dell'azienda?

... e non lasciare questo stage retribuito non è un'opzione, il contratto dice che se me ne vado prima dei 6 mesi di un contratto da 12 mesi, forse pagherò il 30% del mio stipendio annuale

    
posta user14321 22.05.2011 - 07:31
fonte

10 risposte

19

Se puoi riprodurre il problema il 100% delle volte, imposta un punto di interruzione sull'ultimo passaggio (il prima possibile). Se passi attraverso l'intero stack di chiamate, sono abbastanza sicuro che otterrai qualche valore inaspettato da qualche parte o qualcosa che dovrebbe essere chiamato ma non lo è.

Modifica:

E se sei seduto alla fine del tuo ingegno, cerca di correggere il bug e postare qui sperando di ricevere alcuni consigli luminosi, allontanati . Vai a schiarirti la testa e tornare più tardi (preferibilmente domani o dopo il fine settimana). Ci sono state molte volte in cui ho passato un'intera giornata a cercare una soluzione per un particolare problema solo per andarmene, tornare il giorno dopo con una mente lucida e trovarlo entro dieci minuti.

    
risposta data 22.05.2011 - 08:04
fonte
10

Il debugging riguarda più l'isolamento e la comprensione esatta del problema (rispetto all'applicazione di una correzione)

Una cosa da fare attenzione quando si esegue il debug è se si inizia a vedere che si stanno saltando dopo teorie diverse, poiché spesso si impiegano più tempo e non eliminano sistematicamente possibili problemi.

Di solito il modo migliore per eseguire il debug di questi tipi di situazioni è l'approccio sistematico noioso, suddividendo il tuo sistema in piccoli pezzi e facendo in modo che ogni pezzo lavori separatamente e continui ad aggiungere ogni elemento di complessità uno alla volta fino a quando non si rompe. Quindi hai isolato il problema esatto. In questo modo può sembrare un po 'noioso e un lavoro più in anticipo, ma rimuove le variabili e mantiene il cervello sano durante il tentativo di eseguire il debug di un software complesso.

    
risposta data 22.05.2011 - 07:38
fonte
5

Queste sono solo alcune delle cose che ho fatto in passato, ovviamente non funzioneranno tutte in ogni situazione:

  1. Ti rendi conto che è solo un codice, e da qualche parte c'è un bug (non è solo magia nera) che tu CAN risolvi.
  2. Fai una pausa.
  3. Leggi il codice molto lentamente, analizzando ogni passaggio e assicurandoti di capirlo e di cosa sta facendo, senza sorvolare su nulla.
  4. Prendi un secondo paio di occhi per vedere il problema.
  5. Vai a dormire e dimenticatene fino a domani (schiarisci la testa), vieni con una nuova prospettiva).
  6. Stampa il tuo codice e analizza ogni riga, annotando i margini, capendo ogni implicazione di ogni riga
  7. Se non è un bug critico, ma sta causando errori che l'utente non ha bisogno di sapere, ho (vergognosamente, ma onestamente) intrappolato il bug, e ingoiato ! Se non è pericoloso, e non riesci a trovarne la causa, a volte lo intrappoli e non fai sapere all'utente che qualcosa è successo. Riguarda il ROI per il cliente e talvolta non ne vale la pena.
  8. Informa verbalmente l'insetto che stai andando a scovarlo e ucciderlo. A volte scapperà. : -)
risposta data 22.05.2011 - 12:41
fonte
3

Di solito ho questo approccio quando risolvo i bug.

  1. Crea un bel passo per passo per riprodurre il bug
  2. Semplifica la procedura passo passo
  3. Dove si trova il bug nel codice? Ti piace quali funzioni sono coinvolte?
  4. Quale percorso sceglie il codice quando si verifica il bug, il callchain.
  5. Concentrati sulla posizione, quando è ok quando non lo è. Quindi ripeti molto finché non hai trovato esattamente il punto in cui si è verificato l'errore.
  6. Perché succede?

A questo punto di solito è chiaro cosa è successo da quando imparo così tanto nel processo di concentrazione sul problema, quindi so cosa fare. O ho una domanda abbastanza focalizzata che posso chiedere in un forum.

Quindi provo a risolvere il problema e ad usare il passo per passo che hai creato nel primo passaggio per verificare se il bug è stato corretto.

    
risposta data 22.05.2011 - 08:55
fonte
3

Tutti i precedenti consigli sono eccellenti, e gran parte di essi è finalizzato a verificare ipotesi sull'errore / bug e poi a seguire un processo di debug per individuare l'errore (a volte esaminando l'ambiente attorno al bug e qualche volta direttamente nel codice).

Questo approccio non sempre funziona, indipendentemente dalla tua anzianità o competenza. A volte hai solo bisogno di un altro paio di occhi sul problema. Trova qualcuno che riveda il problema o esegua il debugging della sessione con te: spesso solo conversare attraverso il codice ti porterà all'errore.

    
risposta data 22.05.2011 - 17:55
fonte
1

Come altri hanno detto 1) essere in grado di riprodurlo in modo affidabile e 2) fare un passo avanti in un debugger fino al punto in cui accade.

Se non riesco a farlo, per qualsiasi ragione, ho altri due metodi che richiedono entrambi di avere una versione diversa del codice che non mostra il bug.

  1. Eseguire entrambe le versioni del codice affiancate sotto i debugger. Passali finché il cattivo non fa qualcosa di diverso da quello buono.

  2. In alternativa esegui le versioni buone e cattive del codice. Hai un diff o qualche altro elenco delle differenze tra le versioni. Quindi modificare in modo incrementale il codice di entrambe le versioni per renderlo più simile all'altro. Se il cattivo diventa buono, o il buono diventa cattivo, io torno dal cambiamento e apporto un piccolo cambiamento. In questo modo sono a casa sull'errore. Penso che sia "andare da entrambi i lati del problema e lavorare verso il centro". Questo metodo non richiede un debugger.

Se il problema è difficile da riprodurre, allora ho bisogno di quante più informazioni posso ottenere, come un dump dello stack, quando fa . Quindi mi assicuro di poter ottenere quei dati diagnostici, attendere che il problema si verifichi e spero di avere abbastanza informazioni per trovarlo.

    
risposta data 22.05.2011 - 17:29
fonte
1

Se ti è stato assegnato il lavoro da svolgere come programmatore junior, c'è almeno una persona che ha creduto di essere in grado di gestirlo da solo.

Quindi, prima di chiedere aiuto ai tuoi superiori, scrivi su un foglio di carta, l'elenco di passaggi / metodi che hai preso nel tracciare il bug, quanto hai proseguito, perché hai abbandonato ogni metodo e cosa hai imparato in ogni tentativo. Inoltre, riassumi ciò che hai imparato sul progetto fino ad ora.

È probabile che, quando finisci di scrivere questo, ciò che può essere fatto dovrebbe diventare palesemente ovvio. Se lo fa, devi semplicemente seguire ciò che si è rivelato per riprodurre il bug e, provare a risolverlo. In caso contrario, hai una base sulla quale puoi parlare con i tuoi superiori. Se chiedi il loro aiuto senza mostrare ciò che hai fatto, potrebbero avere un'impressione negativa su di te.

Ma se ti schiarisci la testa, torna dopo il fine settimana, potresti essere in grado di risolverlo in poco tempo, senza l'aiuto di nessuno. Succede, sempre.

    
risposta data 23.05.2011 - 01:33
fonte
0

Abbiamo bisogno di sapere quanto è difficile da riprodurre, in quanto il metodo è molto diverso. Per un difetto riprodotto in modo affidabile, automatizzare la causa del difetto. Usa i debugger e le tracce di debug (le tracce hanno meno impatto sui difetti del tipo race condition). Diventa metodico. Un passo alla volta, ogni passaggio fornisce più informazioni, anche se sta confermando ciò che già sai. Se ottieni un risultato a sorpresa, fermati, comprendi il 100% prima di andare avanti. È dolorosamente lento, ma ti porta sempre al risultato finale se gli dai abbastanza tempo.

Se non riesci a ripubblicarlo, allora hai un problema, come confermi di averlo risolto. Inserisci il codice di debug e lascialo lì. Alla fine, chiediti, è "Chiuso: DNR" è un'opzione valida? (Ho / non posso ripetere). Nel mondo degli affari, alla fine è una decisione di costi / benefici.

Non dare per scontato che le tue librerie siano corrette, conferma che lo sono.

Fai una pausa, sii pragmatico riguardo al costo rispetto alla necessità di correggere e, soprattutto, chiedi a qualcun altro di sederti accanto a te e di aiutarti.

    
risposta data 23.05.2011 - 03:44
fonte
0

Un sacco di buone risposte qui. Alcuni altri consigli:

Le UI vivono raramente in isolamento. Costruisci un programma di test con il set minimo di funzionalità necessarie per riprodurre il bug. Se l'interfaccia utente è ben progettata, dovresti essere in grado di disaccoppiare i componenti dell'interfaccia utente che stanno fallendo, e eseguirli separatamente in un programma di test. Puoi ancora riprodurre il problema? In tal caso, il problema è probabile nella struttura o nel framework dell'interfaccia utente. Controlla la struttura dell'interfaccia utente, in particolare fai attenzione agli elementi invisibili. Cerca di capire esattamente cosa succede quando fai clic su quel ListView e non risponde: quali gestori di eventi vengono richiamati? Tenete a mente che possono esistere bug nel framework UI stesso - non saltare a questa conclusione, ma non escluderla a titolo definitivo. Un test rapido consiste nell'aggiornare la versione di Mosync e controllare se i sintomi si rispettano.

In caso contrario: cosa rimane nel programma di test? Comprendi tutti i componenti di ciò che rimane, in particolare qualsiasi thread in esecuzione. Qualcosa che fa manutenzione del database in background? Un file spooler di qualche tipo? Codice di monitoraggio del comportamento dell'utente NSA? L'interfaccia utente funziona con alcuni di questi componenti (forse dietro le quinte)? Da quali operazioni in background dipende l'IU?

Mentre leggi il codice, che dovresti impiegare molto tempo a fare, vista la difficoltà del bug, fai attenzione alle cattive pratiche che potrebbero nascondere il bug. Nello specifico, vedi qualcosa di questo?

try {
    SaveTheWorld();
} catch (std::exception& ex) { /* oh it didn't work, let's just ignore it */ }

Questa è una pratica incredibilmente povera e, come tale, è abbastanza comune (e guarda che non si è schiantato!). Assicurati di aggiornare qualsiasi codice che lo faccia almeno per registrarlo, preferibilmente rimuovi completamente la gestione delle eccezioni false. (Una regola empirica è che se non sai qual è l'eccezione, non sei preparato a gestirlo.) Se interagisce con le API in stile C, controlla i valori restituiti dal codice errore e assicurati che stai controllando le informazioni sullo stato degli errori da qualsiasi strumento con cui stai interagendo.

Visto come il tuo programma di test ora gestisce correttamente i guasti, e hai letto il log che hai prodotto in questo modo, ma ancora nulla evidenzia il bug, cerca le interfacce che puoi sondare. C'è una transazione di rete che dovrebbe accadere sotto le coperte? Se è così, colpiscilo con Wireshark. Transazione del database? Prova qualche registrazione delle query o verificando lo stato del server del database. Il file system o le condivisioni di rete vengono colpiti? Controllare i file intermedi o utilizzare un debugger per tracciare l'I / O. I / O hardware? Monitorare e sondare. Sii empirico. L'interfaccia utente potrebbe essere bloccata su alcune operazioni in background che non hai previsto.

Infine: non fatevi prendere dal panico. Mantieni la calma e tieni traccia di ciò che hai provato. Se ancora non riesci a trovarlo, dovrà diventare un "problema noto" da rintracciare in una giornata piovosa. Avrai bisogno di molto materiale per giustificare questa decisione se deve andare in quel modo.

    
risposta data 09.02.2014 - 01:11
fonte
0

Nello schema delle cose, i bug riproducibili sono (relativamente) facili! Perché? Perché puoi sempre ridurre il codice al minimo finché il bug non scompare, e poi tornare indietro per capire quale codice lo causa. Quindi questo è un metodo. È riproducibile, hai la creatura sotto il tuo controllo. Puoi prenderlo e provarlo. Puoi anche sezionarlo se lo desideri.

Il tuo primo obiettivo è capire perché il bug sta accadendo nel tuo codice. Non provare a risolverlo inizialmente. Prova a capirlo . Se provi a risolverlo senza comprenderlo, ti verrà violato e probabilmente introdurrai debito tecnico , anche se lo risolverai.

Passa attraverso il comportamento dell'app, riga per riga. Guarda i valori delle variabili. Guarda il flusso del controllo. Da dove viene il comportamento per prima cosa devia da ciò che la tua comprensione ti dice che dovrebbe essere? Capisci in che modo il sistema operativo invia eventi alla tua app? Se vieni ostacolato dal problema della "scatola nera", puoi ottenere il codice sorgente per le librerie / i framework compilati, permettendoti di passare ad un livello più profondo se necessario?

Hai un commit nel tuo sistema di controllo delle versioni che non produce questo bug? (Stai usando il controllo della versione, non è vero?) Se si dispone di un tale commit, allora si può fare una ricerca binaria sulla cronologia per scoprire esattamente dove è stato introdotto il bug.

I tuoi obiettivi dovrebbero essere (1) capire - determinare la causa e, a tal fine, provare a (2) esaminare, capire il comportamento dell'app in dettaglio (3) isolare il problema facendolo andare via e quindi esaminare e capire il delta che ti ha permesso di farlo

Ma sicuramente non stare lì per settimane se sei davvero bloccato. Devi dirlo a qualcuno anche nella tua organizzazione. Solleciti aiuto dove puoi e oltre un certo punto, è certamente tuo dovere dire al management che pensi di aver raggiunto un ostacolo al progresso. Ma sarai probabilmente in grado di risolvere questo problema se lo colpisci da una serie di angolazioni diverse, tutte incentrate sull'apprendimento e la comprensione.

    
risposta data 23.12.2016 - 15:21
fonte

Leggi altre domande sui tag