Comment déboguer un stackoverflowexception dans .NET
Scénario:
J'ai juste été sur un rouleau et mis en œuvre un tas de code, mais quand je l'execute, je reçois un ballon d'StackOverflowException? Le StackOverflowException ne dispose pas d'une stacktrace donc je suis coincé. Je sais pourquoi un débordement de pile peut se produire, mais de le corriger, j'ai besoin de savoir où il est à la racine est.
Tout ce que je reçois est: Une exception non gérée du type 'System.StackOverflowException' s'est produite dans la balise-vous " re-it.dll
Options:
- Analyse à travers tous les changements et essayer de diagnostiquer le problème. (peut être lent)
- Utiliser un débogueur et pas à travers jusqu'à ce que vous trouver le problème. (probablement mieux que le 1.)
- Utiliser un profil et de regarder pour la plupart des méthodes appelées.
- ?
PS:
C'est une situation hypothétique (mais pas trop rare) et, par conséquent, aucun code n'est disponible.
- Imprimer la stacktrace? VS a tendance à étouffer lorsqu'ils sont confrontés à un stackoverflow exception.
- Code qui provoque ce est édité en lien en question stackoverflow.com/questions/39004357/...
Vous devez vous connecter pour publier un commentaire.
WinDbg peut faire le travail, y compris même l'obtention d'un sensible (clr) de la pile.
Vous aurez besoin de obtenir WinDbg sauf si vous avez déjà installé avec Visual Studio ou Windows SDK.
Remarque: "WinDbg Aperçu" avec la nouvelle interface graphique a bien fonctionné pour moi.
Je suggère de commencer votre processus de WinDbg, mais bien sûr, vous pouvez également l'attacher à un processus en cours d'exécution si cela vous convient mieux.
Remarque: immédiatement après le démarrage du processus, le CLR n'est pas chargé, et
.loadby SOS.dll clr
sera un échec ("impossible de trouver le module 'clr'). Vous avez à attendre pour le CLR pour être chargé. Pour arrêter l'exécution une fois que cela arrive effectuer:sxe ld clr
Une fois le CLR est chargée, vous aurez à effectuer les étapes suivantes pour briser sur
SackOverflowException
(entrez dans la fenêtre de commande /line):.loadby SOS.dll clr
(pas.loadby sos clr
—ce qui peut conduire à l'extension chargé à deux reprises)!stoponexception -create System.StackOverflowException
g
(continue de débogage)déclencher la StackOverflowException /attendre que cela se produise
!clrstack
(imprime le stacktrace)De sources notables:
.
était trop... je me suis fixé:!stoponexception -create System.StackOverflowException
C'est presque toujours à cause de la récursivité. Un appel de méthode ou une méthode de l'appel d'une méthode qui appelle à nouveau et ainsi de suite.
Pour le trouver:
StackOverflowException
(je suppose que quelque chose à voir avec ne pas être capable d'attraper un, que ce soit). Cependant, il existe des moyens pour faire un dump comme mentionné ici.Parfois, vous aurez des fautes de frappe comme ça, aussi:
Qui est la raison pour laquelle, personnellement, je préfèrent désormais utiliser automatique propriétés.
Aller de Débogage, d'exceptions et de vérifier l'jetés case à cocher 'Common Language Runtime Exceptions". Maintenant, quand vous la cause de la stackoverflow exception, le débogueur s'arrête (éventuellement) et de vous montrer la pile d'appel.
Vous pouvez exécuter le programme en mode debug et de la mettre en pause. Sur le courant de la pile, vous pouvez voir qu'il y a une méthode ou d'un groupe de la méthode qui apparaît plusieurs fois, ce sont les problématiques, les méthodes. Placez un point d'arrêt sur cette méthode et regarde ce que sa vocation lui-même tout le temps.
La ProcDump utilitaire nous a aidé à déboguer le problème que décrit en détails ici. Étapes:
procdump -accepteula -e 1 -f C00000FD.STACK_OVERFLOW -g -ma <process ID> d:\home\DebugTools\Dumps
(le répertoire doit exister)Nous pouvons utiliser la même technique sur Azure en permettant à la CrashDiagnoser extension, comme décrit ici. Fondamentalement, il effectue la même procédure que ci-dessus. Le fichier de vidage il génère peut être téléchargé et ouvert dans Visual Studio.
À la méthode qui est le "point d'entrée" à l'opération échoue, mettre un point d'arrêt. Étape dans le code et de regarder pour les occurrences de la même séquence d'appels de méthode qui se passe de plus de et plus identiques de façon à ce que la pile d'appel devient plus profonde et plus profonde.
Dès que vous remarquez que, placez un point d'arrêt à l'emplacement actuel, où que ce soit. Continuer l'exécution (F5 dans Visual Studio) - si vous êtes sur la bonne voie alors, le débogueur s'arrêter très rapidement au même endroit, et la pile d'appel sera encore plus profond.
Maintenant, vous avez un "live" de la frame de pile, vous pouvez examiner, afin de comprendre comment s'assurer que cette récursivité va bien se terminer.
Voulais juste ajouter à la réponse sur l'utilisation de WinDbg, avec ce que j'ai trouvé pour le débogage d'un dotnet core application
.loadby sos coreclr
(ce doit détecter la version de .net de base que vous utilisez, mais si pas, vous pouvez utiliser.load C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.5\sos
où 2,05 est la version de .netcore vous utilisez!help
!dso
pour faire un dump de la pileDans mon cas, m'a dit exactement où la stackoverflow exception qui se passait
Si vous avez le code, et sont en mesure d'exécuter votre programme à partir de Visual Studio, il doit casser dans le débogueur (si la première chance exceptions sont activées) lorsqu'il rencontre le Système.StackOverflowException. À partir de là, vous pouvez examiner la pile d'appel et de voir qui appelle le souffle de la pile.
J'ai confirmé que cela fonctionne pour Visual Studio 2010 et Visual C# 2010 Express.
Personnellement, j'aime à le réduire, autant que possible, dans une certaine section de code. Par exemple, j'ai juste eu un. La chose étrange était qu'elle était seule passe sur la machine, je ne pouvais pas directement de débogage.
J'ai eu deux threads s'exécutant en parallèle, j'ai donc arrêté l'un à partir de l'exécution(ou vous pouvez unparallelize il).
Puis je suis passé au travers de mes fonctions et ajoutée comme l'impression de fonctions, telles que:
Tout comme la fonction commence:
Juste avant le retour de fonction:
Où GetCurrentMethod est défini comme:
Puis-je exécuter, peut-être que je n'ai pas l'ajouter à toutes les fonctions, mais assez pour affiner où dans le code que ça se passe. Puis à l'intérieur de cette section, ajoutez plus.
Vous pouvez également ajouter un point de contrôle car il fonctionne grâce à certaines méthodes.
Puis exécutez de nouveau, ce que vous trouverez est que la StackOverFlow exception se produit entre ces états. Garder un rétrécissement vers le bas jusqu'à ce que vous trouver.
Assez simplement et rapide de trouver où ça se passe de cette façon.
Je soupçonne que si la taille de la pile du thread qui a provoqué le débordement de la pile est supérieure à un certain seuil que le débogueur Visual Studio peut suivre, puis la pile d'appel n'est pas disponible.
Une solution de contournement consiste à lancer un thread qui est la taille de la pile est inférieure à la taille de pile par défaut, donc débogueur Visual Studio peut suivre la pile d'appel.
Trouver des méthodes qui s'appellent eux-mêmes (ou d'une méthode en appelle un autre et vice-versa) et de les contrôler. La récursivité est généralement le principal suspect lorsque vous obtenez DONC des exceptions.