Come posso affrontare la correzione di un bug non riproducibile / che si verifica in modo casuale?


11

Abbiamo un sito web multilingue in cui un bug è stato scoperto alcuni giorni fa. Stava visualizzando i dati di altre lingue in altre lingue e inoltre era selezionata la combinazione di dati come la lingua inglese, ma mostrava anche i dati di altre lingue nella pagina e viceversa. Lo sta facendo di rado ma è presente nel sito web. Anche passare attraverso il codice non aiuta perché questo non si verifica sempre.

Qualche suggerimento per trovare il problema in modo tempestivo? Chiedo strategie qui.


4
iniziare a sondare il codice per individuare situazioni che consentano il verificarsi di questo errore (invece di farlo diversamente)
Imran Omar Bukhsh

Risposte:


20

Il primo passo è cercare di caratterizzare ciò che può causare questo tipo di problema. Poiché ciò è correlato alla selezione della lingua corretta per le sezioni del codice, iniziare considerando quanto segue:

  • Come viene rilevata la lingua? Si basa sulle informazioni della richiesta HTTP? Si basa sulle informazioni sulla sessione? Oppure sui campi del database? In sostanza, questo può essere un problema legato al modo in cui l'app seleziona la lingua per ogni sezione?
  • Come viene visualizzata la lingua? Stai eseguendo il pull da un file delle proprietà o da un database? È possibile che il riferimento alla lingua corretta si perda in qualche modo? La lingua mista che vedi è sempre quella predefinita per il sito?
  • Esiste una correlazione con l'ambiente client? Questo è legato al primo proiettile, ma va un po 'oltre. Ho avuto strani problemi di rendering a causa dei proxy di cache a valle. In genere questi tipi di problemi sono un'intera pagina che è obsoleta o serve la pagina di una persona ad altri utenti (che era imbarazzante).
  • Stai utilizzando un valore Locale thread? Se una richiesta viene gestita da più di un thread, il valore locale del thread avrà informazioni diverse in base al thread che sta funzionando in quel momento. In un ambiente web server, non puoi presumere che il thread su cui hai iniziato l'elaborazione sia lo stesso thread su cui completi l'elaborazione - a meno che non faccia parte delle specifiche per la tua piattaforma. Gli autori di server hanno scoperto che se riutilizzano un piccolo pool di thread e lavorano in multiplex su di essi in blocchi, possono gestire più richieste contemporaneamente. Anche se si dispone di un thread dall'inizio alla fine di una richiesta, il server potrebbe eseguire contemporaneamente il multiplexing di altre richieste su quel thread. Invece di locali del thread, considera di associare quel valore agli attributi di richiesta o sessione.

Ora, una volta che hai caratterizzato le possibilità di ciò che può andare storto, è tempo di assicurarti di avere i dati necessari per provare e scoprire cosa è andato storto.

  • Utilizzare la registrazione abbondante nelle aree problematiche. Questo è un posto dove uno strumento come Log4J o Log4Net può davvero brillare. Quel framework di registrazione, e altri simili, ti consente di attivare la registrazione per determinate categorie, mantenendo il rumore per tutto il resto, tutto modificando un file di configurazione. Si desidera introdurre nuove dichiarazioni di registrazione per capire se ciò che si sospetta potrebbe essere il problema. Assicurati inoltre che i tuoi log di accesso HTTP abbiano tutte le informazioni che desideri su ogni richiesta (cookie, parametri dell'intestazione http, ecc.)
  • Tentativo di simulare il problema. Dato che ciò accade sporadicamente, com'è il carico sul server nel momento in cui si verifica? Vieni colpito da una serie di richieste simultanee da un mix di lingue? In tal caso, provare a simulare quel tipo di carico nel proprio ambiente di test. Uno strumento simile a JMeter potrebbe essere quello che ti serve. Dovrai anche essere in grado di falsificare gli indirizzi IP per i tuoi falsi client. Ricorda che gli indirizzi IP sono suddivisi in modo da poter capire in quale paese / regione l'IP si basa sui primi due segmenti dell'indirizzo.
  • Il problema sarà altrettanto sporadico nel tuo ambiente di test, ma man mano che ti restringi nella tua vera causa, puoi distorcere i risultati per farlo accadere più spesso di quanto non faccia in natura. Inoltre, è possibile rivedere più facilmente i file di registro e provare a imparare da essi.
  • È un processo iterativo, quindi sii paziente. Bisogna indurre il tipo di carico che si pensa sarà riprodurre il bug, controllare i registri, e perfezionare i test sulla base di ciò che si trova. L'importante è identificare il problema , quindi resisti alla tentazione di apportare alcune semplici correzioni che potrebbero solo far accadere il problema reale meno spesso.

Infine, una volta ridotto il problema al punto in cui sai come riprodurlo e cosa lo causa, scrivi il più piccolo test automatico possibile per forzare il problema nel codice. Se hai ridotto il problema a una classe o se una coppia di classi non funziona correttamente insieme, riproducilo a quel livello. Non dovresti generare 100 thread per farlo, fai solo il test più piccolo che può causare il problema al 100% delle volte.

Ora puoi risolverlo ed essere ragionevolmente fiducioso che non tornerà a morderti di nuovo.


10

Il bug non è irreproducibile. Non hai ancora scoperto come riprodurlo ancora.

Nessun bug è casuale a meno che non si stia generando un'eccezione in base al valore restituito di un'istruzione Random ().

So che può sembrare una semantica, ma è rassicurante mentalmente dirlo a te stesso.

È molto difficile e frustrante scoprire come riproporre un bug che si verifica solo a causa di condizioni di gara complesse o simili.

Per quanto riguarda come trovarlo, accenderei / aggiungerei alcuni log all'applicazione in luoghi che potrebbero darti maggiori informazioni.

Quindi comunica alle persone che visualizzano il bug (se sono sviluppatori, QA, utenti finali) di segnalare non appena lo vedono con il tempo che è accaduto e quindi consulta i tuoi registri. Chiedi loro altre informazioni e il bug può verificarsi solo a causa dell'interazione di diversi sistemi o di una condizione di competizione

Spero che sarai in grado di trovare un vantaggio.


anche le chiamate Random () non sono realmente casuali a meno che non siano derivate da un generatore di rumore bianco hardware. Sono psue-casuali, il che significa che i numeri sono matematicamente distribuiti in un ordine il più casuale possibile. Ma se inizi dallo stesso valore "seed", otterrai sempre la stessa risposta.
Berin Loritsch,

1
@Berin: lo so.
Gilles,

+1 per "non hai ancora scoperto come riprodurlo ancora." Tutti i bug hanno una causa principale, altrimenti non si verificano.
Mike S,

1
Non deve essere un Random (), le cose che dipendono dal tempo, specialmente quelle che implicano un accesso improprio a una risorsa condivisa possono essere molto difficili da riprodurre.
Loren Pechtel,

2
@Gilles: Tranne che potrebbero non essere deterministici su qualsiasi cosa tu possa ragionevolmente misurare. (Diciamo, esattamente quando qualche altra attività ha rilasciato la sua fascia oraria.)
Loren Pechtel,

5

Puoi provare a trovare posizioni nel tuo codice in cui puoi riconoscere che si è verificato il problema (parametri incoerenti in un metodo per esempio), aggiungere i controlli al tuo codice e consentire loro di aggiungere ulteriori informazioni al registro di debug (come una traccia dello stack, oggetti aggiunto alla sessione, ecc.)

In questo modo con un po 'di fortuna è possibile acquisire informazioni sulle occorrenze e dedurre la via del ritorno al problema.


2

L'automazione dovrebbe aiutare, se sono gli stessi passaggi a riprodurre che a volte falliscono, automatizzalo e mettilo in un ciclo. Esegui 50.000 volte ed è molto probabile che accada.


L'evento non è casuale, sembra casuale. In questo modo potrebbe apparire, ma ti darà pochissime informazioni sul perché è apparso.
Josh K,

1
@Josh - Se non è in grado di riprodurlo, questo potrebbe essere un buon modo per farlo e ottenere una traccia dello stack con simboli di debug, per esempio. Immagino che sia un grande primo passo - vederlo in prima persona
Kieren Johnstone l'

Stai assumendo che ci sia uno stack e che sia ottenibile. Non ci ha fornito alcuna informazione tecnica sull'applicazione o quanto sia accessibile per il debug in questo tipo di carico. Non si tratta di una strategia di debug , ma di colpirla con un martello cercando di cogliere il momento esatto in cui si rompe.
Josh K,

@Josh - la mia esperienza nel mondo reale mi dice che la cosa più preziosa nell'indagare / correggere un bug è vederlo in prima persona. Che si tratti di qualcosa con i tempi che puoi vedere, una traccia dello stack, qualcosa nei registri o qualsiasi altra cosa. Laddove possibile, avere problemi apparentemente casuali verificati in un ciclo mi ha portato lì molto rapidamente. Se hai un'idea diversa, pubblicala come risposta per l'amor di Dio: questo è un metodo valido e una risposta valida.
Kieren Johnstone,

Non sono d'accordo e credo che la risposta di Berin sia il modo corretto di risolvere questo problema.
Josh K,

1

prova a trovare schemi per individuare le condizioni che causano questo problema manifestarsi. Ciò dovrebbe indirizzarti verso le sezioni del codice che non funzionano (o si comportano in modo incoerente).


No merda ..............
theringostarrs

0

Riesci a rilevare quando si verifica il problema ? In tal caso, è possibile scaricare in modo affidabile informazioni sullo stato del sistema in quel momento?

Se la risposta a entrambe queste domande è sì, strumentalizza il tuo codice per registrare quante più informazioni possibile quando si verifica effettivamente l'errore, quindi attendi.

Questo non è un sostituto di ciò che altri hanno suggerito (dovrai ancora ragionare su come il codice può entrare nello stato che stai vedendo), ma finché non riesci a riprodurre il bug a piacimento, è una buona idea non perdere le occasioni in cui appare.

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.