Cosa fare quando hai esaurito tutti i viali per correggere un bug


13

Sono un programmatore junior (finora 4 mesi di esperienza professionale) lavorando su un'applicazione mobile multipiattaforma (team di 1 persona - quindi sono solo io).

Ho un bug in questo programma / app che è piuttosto grande (30 diversi file di intestazione, ognuno con il proprio file cpp). Ho cercato di rintracciare esattamente cosa sta succedendo con il bug e anche di risolverlo (ho anche provato a usare alcuni hack per farlo funzionare) ma di circa una dozzina o più soluzioni (idee che ho su ciò che sta causando il problema ) Non ho trovato nulla che mi abbia portato a tracciare esattamente qual è il bug o risolto il bug.

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

Per dare un po 'più contesto al mio bug; coinvolge l'API Mosync multipiattaforma, quando eseguo una specifica sequenza di azioni, la schermata corrente non viene ridisegnata (e sembra) che la schermata precedentemente visualizzata stia ancora ricevendo gli eventi puntatore / tasto e non la schermata corrente.

Sequenza specifica:
- Schermata del menu visualizzata - fare clic su "Mostra il pulsante degli ordini precedenti"
- Schermata degli ordini precedenti visualizzata - Fare clic su "Carica file", quindi fare clic sul pulsante del menu e aprire Schermata di
consegna - Schermata di consegna visualizzata - Fare clic sul pulsante del menu e aprire Schermata di
acquisto - Schermata di acquisto visualizzata - Errore qui, l'ingresso in questa schermata non viene visualizzato / reagito, ListViews 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 gli stessi passaggi ogni volta, anche se è ancora molto difficile capire come vengono trasmessi gli eventi del puntatore e su quale schermata a causa del fatto che è una parte dell'API che non posso raggiungere (o non sapere come).

Inoltre mi piacerebbe avere un paio di occhi diversi che vanno oltre il mio lavoro e sottolineano il bug, ma come ho detto che sono una squadra di 1, il mio capo mi dirige, possiede la società e ha le idee per un'app ma non conosco c ++ o nessuna delle lingue recenti (cobal? Penso che sia tutto). Qualche consiglio su come ottenere un secondo paio di occhi senza violare / mostrare il codice / proprietà intellettuale dell'azienda?

... e non lasciare questo tirocinio retribuito non è un'opzione, il contratto dice che se lascio prima dei 6 mesi di un contratto 12 mesi potrei forse pagare il 30% del mio stipendio annuale


6
È riproducibile al 100%?

5
La semplice risposta è coinvolgere i tuoi colleghi . Come squadra lo risolverai in pochi istanti.
Fattie,

2
@Joe - non sempre. Ad esempio, bug nel comportamento collettivo di più sottosistemi interagenti complessi, in cui sono stati costruiti diversi sottosistemi con viste sottilmente incompatibili dei loro ruoli, risultanti da ambiguità non ovvie nelle specifiche - in genere pochissime persone hanno la conoscenza dettagliata di più sottosistemi e delle loro interazioni per essere in grado di diagnosticare questi problemi. A volte devi far parlare tutte le squadre e quando due persone iniziano a chiamarsi cretini, c'è la possibilità che stiano discutendo di qualcosa di periferico legato alle ipotesi incompatibili.
Steve314,

Ho unito i tuoi account. Puoi utilizzare il tuo Yahoo OpenID per accedere. Sto anche modificando la tua domanda per includere le informazioni che hai pubblicato come risposta.
Adam Lear

btw. Oltre alla mia risposta di seguito, ho letto su Wikipedia che Mosync non viene più mantenuto?
Brad Thomas,

Risposte:


19

Se riesci a riprodurre il problema il 100% delle volte, imposta un punto di interruzione sull'ultimo passaggio (il più presto possibile). Se percorri l'intero stack di chiamate, sono abbastanza sicuro che arriverai a dei valori imprevisti da qualche parte, o qualcosa che dovrebbe essere chiamato ma non lo è.

Modificare:

E se sei seduto alla fine del tuo ingegno cercando di correggere il bug e pubblicando qui sperando che tu possa ottenere qualche consiglio luminoso, vai via . Svuota la testa e torna più tardi (preferibilmente domani o dopo il fine settimana). Ci sono state molte volte in cui ho passato un'intera giornata alla ricerca di una soluzione a un problema specifico solo per andarmene, tornare il giorno successivo con la testa libera e trovarlo entro dieci minuti.


4
e se per qualsiasi motivo non è possibile utilizzare un debugger, inserire alcune informazioni di traccia attorno al bit di codice che si ritiene non riesca a registrare le chiamate delle funzioni in un file di testo.

3
+1 per "Allontanati". Ci vuole molta esperienza per sapere quando andarsene sarà probabilmente più produttivo che risolvere il problema. La tua situazione sembra un buon posto per iniziare a raccogliere quell'esperienza specifica.
Mike Sherrill "Cat Recall",

Se il tuo software ha bisogno di un punto di interruzione per individuare l'errore, anche il tuo cervello ne ha bisogno. Ciò consente di risparmiare più tempo che forzare te stesso e non allontanarti.
setzamora,

Ho trovato funzioni di registrazione che registrano valori che potrebbero essere rilevanti sono spesso un modo migliore per rintracciare questo genere di cose. Formatta le linee di registro con colonne pulite in modo che eventuali modifiche risaltino alla tua vista. Chiamare questa funzione di registrazione frequentemente con un ID di provenienza. È possibile esaminare il file di registro molto più rapidamente di quanto non sia possibile eseguire il monitoraggio delle variabili.
Loren Pechtel,

10

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

Una cosa a cui prestare attenzione quando si esegue il debug è se si inizia a vedere che si sta saltando dopo diverse teorie in quanto spesso questo richiede molto più tempo e non elimina sistematicamente possibili problemi.

Di solito il modo migliore per eseguire il debug di questo tipo di situazioni è l'approccio sistematico noioso, suddividendo il sistema in piccoli pezzi e facendo lavorare ogni pezzo in isolamento e continuando ad aggiungere ogni elemento di complessità uno per uno fino a quando non si rompe. Quindi hai isolato il problema esatto. In questo modo può sembrare un po 'noioso e un po' più di lavoro iniziale ma rimuove le variabili e mantiene sano il cervello mentre si tenta di eseguire il debug di un software complesso.


5

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

  1. Renditi conto che è solo un codice, e da qualche parte c'è un bug (non è solo magia nera) che PUOI correggere.
  2. Fare una pausa.
  3. Scorri il codice molto lentamente, analizzando ogni passaggio e assicurandoti di comprenderlo e cosa sta facendo, non sorvolando nulla.
  4. Prendi un secondo paio di occhi per vedere il problema.
  5. Vai a dormire e dimenticalo fino a domani (schiarisci la testa), vieni con una nuova prospettiva).
  6. Stampa il tuo codice e analizza ogni riga, prendendo appunti a margine, comprendendo tutte le implicazioni di ogni riga
  7. Se non si tratta di un bug critico, ma sta causando errori che l'utente non deve conoscere, ho (vergognosamente, ma onestamente) intrappolato il bug e l' ho ingoiato ! Se non è pericoloso e non riesci a trovare la causa, a volte devi solo intercettare e non far sapere all'utente che è successo. Riguarda il ROI per il cliente e talvolta non ne vale la pena.
  8. Di 'al bug verbalmente che lo caccerai e lo ucciderai. A volte scapperà. :-)

+1 perché non è magia nera!
Guy Sirton,

Con tutte le dipendenze complesse che prendiamo oggi nel nostro codice, è magia nera. Ma puoi
farcela

3

Di solito ho questo approccio quando risolvo i bug.

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

A questo punto di solito è chiaro cosa è successo da quando ho imparato così tanto nel processo di concentrazione sul problema, quindi so cosa fare. Oppure ho una domanda piuttosto mirata che posso porre in un forum.

Quindi provo a risolvere il problema e utilizzo il passaggio che hai creato nel passaggio uno per verificare se il bug è stato corretto.


3

Tutti i precedenti consigli sono eccellenti e gran parte di essi sono volti a verificare ipotesi sull'errore / errore e quindi a seguire un processo di debug per individuare l'errore (a volte esaminando l'ambiente attorno all'errore e a volte direttamente nel codice).

Questo approccio non funzionerà sempre, indipendentemente dalla dipendenza dalla tua anzianità o competenza. A volte hai solo bisogno di un'altra serie di occhi sul problema. Trova qualcuno con cui riesaminare il problema o eseguire il debug della sessione con te, spesso solo parlare attraverso il codice ti porterà all'errore.


Sono d'accordo, che ha spesso funzionato per me.
Mike Dunlavey,

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 posso farlo, per qualsiasi motivo, ho altri due metodi che richiedono entrambi di avere una versione diversa del codice che non presenta l'errore.

  1. Esegui entrambe le versioni del codice fianco a fianco nei debugger. Falli avanti finché il cattivo non fa qualcosa di diverso da quello buono.

  2. Alternare l'esecuzione delle versioni buone e cattive del codice. Avere un diff o qualche altro elenco delle differenze tra le versioni. Quindi modificare in modo incrementale il codice di entrambe le versioni per adattarlo meglio all'altra. Se quello cattivo diventa buono, o quello buono diventa cattivo, torno indietro dal cambiamento e faccio un cambiamento più piccolo. In questo modo sono a casa sul bug. Lo considero come "arrivare da entrambi i lati del problema e lavorare verso il centro". Questo metodo non richiede un debugger.

Se il problema è difficile da riprodurre, quindi ho bisogno di tante informazioni come posso ottenere, come ad esempio un dump dello stack, quando non accade. Quindi mi assicuro di poter ottenere quei dati diagnostici, attendere che si verifichi il problema e spero di avere abbastanza informazioni per trovarli.


1

Se ti è stato assegnato di svolgere il lavoro a portata di mano 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 dei passaggi / metodi che hai seguito per rintracciare il bug, fino a che punto sei andato avanti con esso, perché hai rinunciato a ogni metodo e cosa hai imparato in ogni tentativo. Inoltre, riassumi ciò che hai appreso sul progetto finora.

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

Ma, se ti schiarisci la testa, torni dopo il fine settimana, potresti riuscire a risolverlo in pochissimo tempo, senza l'aiuto di nessuno. Succede tutto il tempo.


"Se ti venisse assegnato di svolgere il lavoro come programmatore junior, c'è almeno una persona che credeva di essere in grado di gestirlo da solo." Se lavorassi, tutti gli sviluppatori dovrebbero chiedere aiuto se, dopo aver fatto il loro homeowrk, non hanno una soluzione, si chiama lavoro di squadra.
mattnz,

@mattnz Tutto ciò che suggerisco è, prima di chiedere aiuto, fare una documentazione degli sforzi fatti finora e fare in modo che tutte le opzioni conosciute siano esaurite. Non so come chiamarlo, ma non ho mai contestato ciò che riferisci al lavoro di squadra.
vpit3833,

Volevo sottolineare il "... capace di gestirlo tutto da solo", mi sottintendeva che eri da solo. Sono contento di sapere che l'ho interpretato un po 'più forte di quanto volevi.
mattnz,

0

Dobbiamo sapere quanto sia difficile riprodurlo, poiché il metodo è abbastanza diverso. Per un difetto riprodotto in modo affidabile, automatizzare la causa del difetto. Utilizzare debugger e tracce di debug (le tracce hanno il minimo impatto sui difetti del tipo di race condition). Diventa metodico. Un passo alla volta, ogni passaggio fornisce ulteriori informazioni, anche se sta confermando ciò che già sai. Se ottieni un risultato a sorpresa, fermati, capiscilo al 100% prima di procedere. È dolorosamente lento, ma ti dà sempre il risultato finale se gli dai abbastanza tempo.

Se non riesci a riordinarlo, 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? (Did / Impossibile ripordinare). Negli affari, alla fine è una decisione 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 risolvere e, soprattutto, chiedi a qualcun altro di sederti accanto a te e aiutarti.


0

Molte buone risposte qui. Alcuni altri consigli:

Le UI raramente vivono in isolamento. Crea un programma di test con il set minimo di funzionalità richieste per riprodurre il bug. Se l'interfaccia utente è ben progettata, dovresti essere in grado di disaccoppiare i componenti dell'interfaccia utente che non funzionano e di eseguirli separatamente in un programma di test. Puoi ancora riprodurre il problema? In tal caso, il problema è probabilmente nella struttura o nella struttura 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 ListView e non risponde: quali gestori di eventi vengono richiamati? Tieni presente che potrebbero esserci dei bug nel framework dell'interfaccia utente stessa - non saltare a quella conclusione, ma non escluderlo del tutto. Un rapido test è quello di aggiornare la tua versione di Mosync e verificare se i sintomi persistono.

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

Mentre leggi il codice - cosa che dovresti dedicare molto tempo a fare, data la difficoltà del bug - fai attenzione ad alcune cattive pratiche che potrebbero oscurare il tuo bug. In particolare, vedi qualcosa del genere?

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

È una pratica incredibilmente scarsa e come tale, è abbastanza comune (ehi guarda che non si è schiantato!). Assicurati di aggiornare qualsiasi codice che lo sta facendo almeno per registrarlo - preferibilmente rimuovi completamente la gestione delle false eccezioni. (Una regola empirica è che se non si conosce quale sia l'eccezione, non si è pronti a gestirla.) Se interagisce con le API in stile C, fare attenzione ai valori restituiti del codice di errore e assicurarsi che stai verificando le informazioni sullo stato dell'errore da qualsiasi strumento con cui interagisci.

Visto che il tuo programma di test ora gestisce correttamente gli errori e hai letto il registro che hai così prodotto, ma ancora nulla evidenzia il bug, cerca interfacce che puoi sondare. Esiste una transazione di rete che dovrebbe avvenire sotto le coperte? In tal caso, colpiscilo con Wireshark. Transazione del database? Prova un po 'di registrazione delle query o controlla lo stato del server di database. Il filesystem o le condivisioni di rete vengono colpite? 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 un'operazione 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 quella decisione se deve andare in quel modo.


0

Nello schema delle cose, i bug riproducibili sono (relativamente) facili! Perché? Perché puoi sempre ridurre il codice al minimo indispensabile fino a quando il bug non scompare, e quindi tornare indietro per capire quale codice lo causa. Quindi questo è un metodo. È riproducibile, hai la creatura lì sotto il tuo controllo. Puoi colpirlo e sperimentarlo. Puoi anche dissezionarlo se vuoi.

Il tuo primo obiettivo è capire perché il bug si sta verificando nel tuo codice. Non provare a risolverlo inizialmente. Prova solo a capirlo . Se provi a risolverlo senza capirlo, stai andando in giro e probabilmente introdurrai un debito tecnico , anche se lo risolvi.

Passa attraverso il comportamento dell'app, riga per riga. Guarda i valori delle variabili. Guarda il flusso di controllo. Dove si discosta prima il comportamento da ciò che la tua comprensione ti dice che dovrebbe essere? Capisci come il sistema operativo invia eventi alla tua app? Se sei ostacolato dal problema della "scatola nera", puoi ottenere la fonte per le librerie / i framework compilati, permettendoti di passare a un livello più profondo se devi?

Hai un commit nel tuo sistema di controllo della versione che non produce questo bug? (Stai usando il controllo versione no?) Se hai un tale commit, allora puoi 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, comprendere in dettaglio il comportamento dell'app (3) isolare il problema facendolo sparire e quindi esaminare e comprendere il delta che ti ha permesso di farlo

Ma sicuramente non restare seduto lì per settimane se sei davvero bloccato. Devi dirlo anche a qualcuno nella tua organizzazione. Chiedere aiuto dove è possibile e oltre un certo punto, spetta sicuramente a te dire al management che ritieni di aver colpito un ostacolo al progresso. Ma probabilmente sarai in grado di risolverlo se lo colpisci da una serie di angolazioni diverse, tutte incentrate sull'apprendimento e la comprensione.

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.