Come si esegue il debug di un'applicazione complessa? [chiuso]

1

Ho un'applicazione che restituisce l'output sbagliato, quando viene eseguito con una particolare scelta di input. Non sono stato in grado di avvicinarmi a una diagnosi della colpa, nonostante abbia trascorso circa un giorno e mezzo. Se viene eseguito con l'input A, ottiene l'output corretto, se ha l'input B l'output dovrebbe essere lo stesso ma non è corretto. L'input B passa attraverso alcuni processi leggermente diversi per l'input A, nel tentativo di ottimizzarlo, sebbene la maggior parte dei passaggi siano in comune.

Sto cercando di confrontare l'invocazione del programma fianco a fianco con i due input. È un modo difficile di eseguire il debug in quanto si hanno due finestre di applicazioni, due finestre di Visual Studio, ed è facile confondersi.

Il software è circa 1 milione di righe di codice, e parte del codice è diabolicamente complicata. Ha molti loop e loop nidificati che vengono eseguiti per un sacco di iterazioni, con variabili molto complesse. Memorizza nella cache molti dati, quindi quando trovi che i valori in una modalità sono diversi dall'altra devi calcolare se le differenze sono significative e quindi è difficile intercettare dove i programmi divergono poiché i valori sono già stati calcolati e devi continuare a riavviare i programmi e tornare indietro.

Capisco che non ci sia un proiettile d'argento qui ma mi sono chiesto se qualcuno avesse qualche consiglio?

    
posta Paul Richards 10.03.2015 - 15:20
fonte

3 risposte

5

La risposta è semplice, l'esecuzione è complessa.

Fondamentalmente quello che stai cercando di fare è identificare il punto in cui si verifica la varianza, cioè il punto in cui il risultato effettivo inizia ad allontanarsi dal risultato previsto (e se questo suona come qualcosa che potrebbe apparire attraverso test codificati ("unità" e su) quindi non è del tutto sorprendente). Allo stesso modo è necessario identificare il punto in cui la varianza si interrompe, ad esempio dove si uniscono i percorsi in modo tale che si abbia un risultato che cambia costantemente di nuovo. Dopo aver identificato questi punti, puoi lavorare per restringere ulteriormente le possibili posizioni per gli "errori".

Il metodo della forza bruta consiste nell'aggiungere istruzioni di debug / trace, punti di interruzione e ispezione e quindi nell'esecuzione del codice.

Migliora questo in due modi:

  • Innanzitutto riducendo la quantità di codice che devi eseguire - ci sono diversi modi. (Come suggerito, questo significa isolare / separare il codice problematico.)
  • Secondo avvolgendo le cose nei test (che è probabilmente il migliore dei vari mezzi se possibile)

Purtroppo nulla di tutto ciò è immediato o necessariamente rapido.

    
risposta data 11.03.2015 - 17:40
fonte
3

Its a difficult way to debug as you have two application windows, two visual studio windows, and its easy to get mixed up.

Davvero? Hai due monitor. Metti una variante su uno schermo e l'altra sull'altro. Se non hai due monitor, allora benvenuto nel 21 ° secolo. Sono come $ 100.

I understand there is no silver bullet here but I just wondered if anyone had any tips?

Quindi sembra che tu abbia un codice troppo complesso (leggi: mal progettato / implementato). E sembra che non ci siano test unitari.

Idealmente, vorrei cercare di semplificare il codice base. Passa in dipendenze per allentare l'accoppiamento. Rompi le grandi funzioni in quelle più piccole. Tagliare gli effetti collaterali. Ci sono pile di buone pratiche per farlo, ma dato che è "come scrivere un buon codice" - non ho intenzione di approfondirlo. E davvero, non dovresti semplificare la base di codice fino a quando non avrai risolto il problema.

I test unitari aiuteranno comunque. Possono isolare il bug e aiutarti a eseguire il debug solo su quella parte isolata piuttosto che sull'intera app complessa. Forniscono chiare coppie input / expected-output. Impediscono agli utenti successivi di rompere le cose. E ti metteranno sotto pressione per scrivere un buon codice riutilizzabile. Certo, potrebbe essere impossibile fare buoni test di unità se il tuo codice è eccessivamente complesso.

    
risposta data 10.03.2015 - 15:36
fonte
0

Non ho molta esperienza con Visual Studio, ma in molti IDE puoi tenere un Watcher su una variabile e scorrere il codice tenendo d'occhio il suo valore. Ecco la documentazione MSDN su una funzionalità che sembra essere equivalente a ciò che ricordo da altri IDE .

Input B goes through some slightly different processes to Input A, in an attempt to optimise it, although most of the steps are in common

Mi sembra che dovresti inserire un grosso punto di interruzione di grasso nel passaggio 1 dei primi processi "leggermente diversi" e quindi passare da quel punto in poi durante il debug dell'input B. (Confrontare il suo valore con il valore di input A in il passaggio precedente, cioè prima che iniziassero quei processi "leggermente diversi", in modo da essere sicuri che l'elaborazione fino a quel momento fosse la stessa.)

Un altro consiglio piuttosto soggettivo: se passare attraverso così tante linee di codice è davvero dispendioso in termini di tempo, è possibile utilizzare un approccio di "ricerca binaria" una volta che si conosce quale serie di linee di codice sono coinvolte (probabilmente dalla riga 1 del elaborazione "leggermente diversa" fino all'ultima riga). Metti un breakpoint nel mezzo di quell'intervallo; controllare se A e B sono diversi; se lo sono, metti un breakpoint nel mezzo dell'intervallo prima di quella linea; se non lo sono, metti un breakpoint nel mezzo dell'intervallo dopo quella linea. Se non si conoscono le linee di codice coinvolte, passare dal punto in cui l'elaborazione è diversa è l'unica opzione possibile.

    
risposta data 12.03.2015 - 13:28
fonte

Leggi altre domande sui tag