2011-01-19 11 views
20

Scenario:Come eseguire il debug di uno StackOverflowException in .NET

Sono appena stato su un rullo e implementato un mucchio di codice, ma quando eseguo io ottenere gettato uno StackOverflowException? StackOverflowException non ha uno stacktrace quindi sono bloccato. So perché potrebbe verificarsi un overflow dello stack, ma per risolverlo devo sapere dove si trova root.

Tutto quello che sto ricevendo è: un'eccezione non gestita di tipo 'System.StackOverflowException' avvenuto nel tag-tu sei-it.dll

Opzioni:

  1. scansione attraverso tutte le cambia e prova a individuare il problema. (potrebbe essere lento)
  2. Utilizzare un debugger e scorrere fino a trovare il problema. (probabilmente meglio di 1.)
  3. Utilizzare un profilo e cercare i metodi più chiamati.
  4. ?

PS:

Questa è una situazione ipotetica (anche se non troppo comune) e quindi non è disponibile codice.

+0

Stampare lo stacktrace? VS tende a soffocare quando si confronta con un'eccezione di stackoverflow. – leppie

+0

Codice che causa questo è pubblicato nel link in questione http://stackoverflow.com/questions/39004357/how-to-fix-stackoverflowexception-in-net – Andrus

risposta

12

Questo è quasi sempre dovuto alla ricorsione. O un metodo che si chiama, o un metodo che chiama un metodo che lo richiama e così via.

per trovarlo:

  • AGGIORNATO: Non mi rendevo conto, ma a quanto pare non è possibile ottenere l'analisi dello stack per un StackOverflowException (immagino qualcosa a che fare con il non essere in grado di prendere uno , o). Tuttavia ci sono modi per ottenere una discarica as mentioned here.
  • ReSharper mostrerà i metodi che si chiamano (mette un piccolo cerchio verde nella barra laterale per le chiamate ricorsive) anche se non catturerà la ricorsione in cui sono coinvolti due o più metodi.
  • Utilizzare uno strumento come ANTS Profiler per vedere quali metodi vengono chiamati più volte.
  • Tieni d'occhio gli eventi che generano un codice che potrebbe richiedere lo stesso evento, provocando un loop.

Di tanto in tanto si otterrà errori di battitura in questo modo, anche:

private string name; 

public string Name 
{ 
    get { return Name; } // Ooops! This is recursive, all because of a typo... 
} 

che è una ragione per cui io personalmente ora preferisco usare le proprietà automatiche.

+3

1. Non si ottiene uno stacktrace con un'eccezione SO. 2. La ricorsione è probabilmente il colpevole e il resharper potrebbe aiutare, ma poi non sempre aiuta a trovare loop circolari a causa di altri costrutti. 3. Un profilo sembra una buona opzione. – Christo

+0

http://stackoverflow.com/questions/39004357/how-to-fix-stackoverflowexception-in-net/ mostra che questo non è causato dalla ricorsione. Come eseguire il debug di SOexception in questo caso? Questa risposta presuppone che ciò sia causato dalla ricorsione. – Andrus

-1

Trova metodi che chiamano se stessi (o un metodo chiama un altro e viceversa) e li ispezionano. La ricorsione è di solito il principale sospetto quando ricevi SO eccezioni.

+1

So perché si verificano. Il problema li sta rintracciando. Stai solo affermando l'opzione 1. – Christo

1

Al metodo che è il "punto di ingresso" per l'operazione che non riesce, inserire un punto di interruzione. Passa attraverso il codice e osserva le occorrenze della stessa sequenza di chiamate di metodo che si ripetono ripetutamente in uno stesso schema, in modo che lo stack di chiamate diventi sempre più profondo.

Non appena si nota, inserire un punto di interruzione nella posizione corrente, ovunque si trovi. Continua l'esecuzione (F5 in Visual Studio): se sei sulla strada giusta, il debugger si fermerà molto rapidamente nella stessa posizione e lo stack delle chiamate sarà ancora più profondo.

Ora si dispone di un frame di stack "attivo" che è possibile esaminare, al fine di capire come garantire che questa ricorsione si risolva correttamente.

+0

Come il suggerimento di Borja. – Christo

+0

Altro modo (ordina le risposte per "Più vecchio") –

+0

;-) Jip, suppongo che il mio ordinamento sia sbagliato. Ho votato inizialmente anche il tuo, nel caso in cui avessi sbagliato l'ordine. – Christo

5

È possibile eseguire il programma in modalità di debug e metterlo in pausa. Nell'attuale callstack puoi vedere che ci sono un metodo o un gruppo di metodi che appaiono più volte, questi sono i metodi problematici. Metti un punto di rottura su questo metodo e guarda come si chiama tutto il tempo.

+0

È vero, aggiungerò il passaggio attraverso il debug come un'altra opzione. – Christo

+0

Grazie!Ho solo occasionalmente errori grossolani e quindi non ho l'abitudine di usare lo Stack chiamate. Ero * sicuro * che non avevo un problema di ricorsione ma, ovviamente, avevo un problema di ricorsione in una posizione inaspettata e il fissaggio era facile una volta che mi fermavo cercando di intuire cosa non andava. :-) – clweeks

5

Vai debug, eccezioni e selezionare la casella di controllo gettato al «Eccezioni Common Language Runtime. Ora quando si causa l'eccezione StackOverflow, il debugger si fermerà (eventualmente) e mostrerà lo stack delle chiamate.

+2

Sei sicuro che funzioni sulle eccezioni di overflow dello stack? Sono un po 'speciali nel modo in cui vengono gestiti. –

+1

Lo fa. L'ho fatto. – Joshua

+2

Forse vale la pena sottolineare che è necessario guardare la finestra Stack di chiamate di Visual Studio, non lo StackTrace di eccezione che non verrà impostato (probabilmente perché una volta che lo stack è pieno, non può fare nulla che necessiti di ulteriore utilizzo dello stack). – Appetere

0

Se si dispone del codice e si è in grado di eseguire il programma da Visual Studio, è necessario interrompere il debugger (se sono abilitate le eccezioni per la prima volta) quando incontra System.StackOverflowException. Da lì puoi esaminare lo stack delle chiamate e vedere quali chiamate stanno facendo esplodere lo stack. enter image description here

Ho confermato che questo funziona per Visual Studio 2010 e Visual C# 2010 Express.

0

Personalmente, mi piace restringere il più possibile ad una certa sezione di codice. Ad esempio, ne ho appena avuto uno. La cosa strana era che succedeva solo sulla macchina che non potevo eseguire direttamente il debug.

ho avuto due thread in esecuzione in parallelo, così mi sono fermato una esecuzione (o si potrebbe unparallelize esso).

Poi ho passato le mie funzioni e ha aggiunto come la stampa funzioni, come ad esempio: Proprio come funzione inizia:

Console.WriteLine("<Enter method: {0}", DebuggingHelper.GetCurrentMethod()); 

Poco prima funzione ritorna:

Console.WriteLine(">Exit method: {0}", DebuggingHelper.GetCurrentMethod()); 

Dove GetCurrentMethod è definita come :

-

Quindi lo eseguo, forse non aggiungo a tutte le funzioni, ma abbastanza da restringere il punto in cui si trova il codice. Quindi all'interno di quella sezione, aggiungi altro.

È anche possibile aggiungere il punto di controllo mentre esegue determinati metodi.

Quindi eseguire di nuovo, ciò che troverete è che si verifichi l'eccezione StackOverflow tra tali dichiarazioni. Continua a restringere finché non lo trovi.

Abbastanza semplicemente e veloce per trovare dove sta accadendo in questo modo.

Problemi correlati