Wie kann ich eine StackOverflowException verhindern und / oder behandeln?
Ich würde gerne entweder zu verhindern oder zu behandeln eine StackOverflowException, dass ich immer von einem Aufruf der XslCompiledTransform.Transform-Methode innerhalb einer Xsl-Editor, Schreibe ich. Das problem scheint zu sein, dass die Benutzer schreiben Sie ein Xsl-Skript, das ist unendlich rekursiv, und es weht bis auf den Aufruf der Transform-Methode. (Das heißt, das problem ist nicht nur die typische programmatische Fehler, die in der Regel die Ursache für solche eine Ausnahme.)
Gibt es eine Möglichkeit zu erkennen und/oder zu begrenzen, wie viele rekursionen zugelassen werden? Oder irgendwelche anderen Ideen, um diesen code aus nur Sprengung auf mich?
ProfilerCallback::_LogCallTrace
der CLRProfiler möglicherweise ein guter Ort, um zu starten, aber es scheint nicht so ein leichtes Unterfangen. Link zum profiler Quellcode-download über David Browman ' s blog: blogs.msdn.com/b/davbr/archive/2011/02/01/... InformationsquelleAutor der Frage JohnnyM | 2008-10-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Von Microsoft:
Ich gehe davon aus, dass die Ausnahme geschieht im Rahmen eines internen .NETTO-Methode, und nicht in Ihrem code.
Können Sie tun, ein paar Dinge.
Können Sie die Process-Klasse zum laden der assembly, die die Transformation in einen separaten Prozess, und den Nutzer warnen, der Fehler, wenn es stirbt, ohne zu töten, Ihre Haupt-app.
EDIT: ich habe gerade getestet, hier ist, wie es zu tun:
MainProcess:
ApplyTransform Prozess:
InformationsquelleAutor der Antwort FlySwat
Stack-overflows passieren, weil die Daten auf dem stack einen bestimmten Grenzwert überschreitet (in bytes). Die details, wie diese Erkennung funktioniert, finden Sie hier.
Als ich oben in den link, die Erkennung eines stack-überlauf von der statischen code-Analyse erforderlich wäre die Lösung das Halteproblem ist unentscheidbaren. Jetzt haben wir festgestellt, dass es gibt keine silberne Kugel, ich kann Ihnen zeigen, ein paar tricks, die ich denke, hilft, das problem zurückzuverfolgen.
Ich denke, diese Frage kann Verschieden interpretiert werden, und da bin ich ein wenig gelangweilt :-), werde ich brechen Sie in verschiedenen Variationen.
Erkennung eines stack-überlauf in einem test-Umgebung
Grundsätzlich das problem hier ist, dass Sie eine (begrenzte) test-Umgebung und entdecken wollen, einen stack-überlauf in einem (erweiterten) Produktionsumgebung.
Statt erkennen das SO an sich, ich wird dieses Problem durch die Ausnutzung der Tatsache, dass die stack-Tiefe eingestellt werden kann. Der debugger gibt Ihnen alle Informationen, die Sie benötigen. Die meisten Sprachen können Sie angeben, die stack-Größe oder die max Rekursionstiefe.
Im Grunde versuche ich zu erzwingen, indem Sie die stack-Tiefe so klein wie möglich. Wenn es nicht überläuft, kann ich immer machen, größer (=in diesem Fall: sicherer) für die Produktionsumgebung. Im moment bekommen Sie einen stack-überlauf, können Sie manuell entscheiden, ob es ein "Gültiger" oder nicht.
Um dies zu tun, übergeben Sie die stack-Größe (in unserem Fall: ein kleiner Wert), um einen Thread-parameter, und sehen, was passiert. Die Standard-stack-Größe .NET ist 1 MB ist, verwenden wir eine Art kleiner Wert:
Hinweis: wir verwenden diesen code unten, wie gut.
Sobald es läuft, können Sie es auf einen größeren Wert, bis Sie ein, SO dass macht Sinn.
Erstellen von Ausnahmen vor, die Sie SO
Den
StackOverflowException
ist nicht abfangbar. Dies bedeutet, dass es nicht viel Sie tun können, wenn es passiert ist. So, wenn Sie glauben, etwas ist verpflichtet, die schief gehen in Ihrem code, können Sie Ihre eigenen Ausnahme in einigen Fällen. Das einzige, was Sie dazu brauchen, ist der aktuelle stack-Tiefe; es gibt keine Notwendigkeit für einen Schalter, die Sie verwenden können, die echte Werte aus .NET:Beachten Sie, dass dieser Ansatz funktioniert auch, wenn Sie Umgang mit den third-party-Komponenten, die mit einem callback-Mechanismus. Das einzige, was erforderlich ist, dass Sie abfangen können einige fordert in dem stack-trace.
Erkennung in einem separaten thread
Du explizit vorgeschlagen, so hier geht.
Können Sie versuchen, erkennen Sie dies in einem eigenen thread.. aber wahrscheinlich wird es nicht tun Sie etwas gutes. Ein stack-überlauf passieren kann schnell, noch bevor man sich ein Kontext-switch. Dies bedeutet, dass dieser Mechanismus nicht zuverlässig bei allen... würde ich nicht empfehlen, tatsächlich. Es war lustig zu bauen, aber, so ist hier der code 🙂
Führen Sie diese in den debugger und Spaß haben, was passiert.
Über die Merkmale von einem stack-überlauf
Andere interpretation deiner Frage ist: "Wo sind die Teile des Codes, die möglicherweise zu einem stack-überlauf Ausnahme?". Offensichtlich wird die Antwort HIERFÜR ist: alle Codes mit Rekursion. Für jedes Stück code, können Sie eine manuelle Analyse.
Ist es auch möglich zu ermitteln, diese mithilfe von statische code-Analyse. Was Sie tun müssen, ist zu dekompilieren, alle Methoden und herauszufinden, ob Sie enthalten eine unendliche Rekursion. Hier ist etwas code, der dies für Sie übernimmt:
Nun, die Tatsache, dass eine Methode Zyklus enthält eine Rekursion, ist keineswegs eine Garantie, dass ein stack-überlauf wird passieren - es ist nur die wahrscheinlichste Voraussetzung für einen stack-überlauf Ausnahme. Kurz gesagt bedeutet dies, dass dieser code bestimmt die code-Stücken, wo ein stack-überlauf kann auftreten, der sollte verengen die meisten code erheblich.
Noch andere Ansätze
Es gibt einige andere Ansätze, die Sie versuchen können, dass ich noch nicht hier beschrieben.
InformationsquelleAutor der Antwort atlaste
Ich würde vorschlagen, die Schaffung eines wrapper um XmlWriter-Objekt, so würde es zählen, Anzahl der Anrufe zu WriteStartElement/WriteEndElement, und wenn Sie den Grenzbetrag von tags bis zu einem gewissen Zahl (f.e. 100), Sie wäre in der Lage zu werfen eine andere Ausnahme, die zum Beispiel von InvalidOperation.
Das sollte das problem lösen in der Mehrzahl der Fälle
InformationsquelleAutor der Antwort Dmitry Dzygin
Wenn Sie die Anwendung hängt davon ab, 3d-party-code (in Xsl-Skripten), dann müssen Sie zunächst entscheiden wollen Sie verteidigen von Fehlern in Ihnen oder nicht.
Wenn Sie wirklich wollen, zu verteidigen, dann denke ich, sollten Sie Ihrer Logik, die anfällig für äußere Fehler in separate AppDomains.
Fang StackOverflowException ist nicht gut.
Überprüfen Sie auch diese Frage.
InformationsquelleAutor der Antwort Shrike
Hatte ich einen stackoverflow heute und ich Las manche Ihrer Beiträge und beschlossen, zu helfen, aus der Garbage Collecter.
Ich verwendet, um eine nahezu unendliche Schleife wie diese:
Stattdessen lassen Sie uns die Ressourcen ausgehen Umfang wie diese:
Bei mir hat es geklappt, hoffe es hilft jemandem.
InformationsquelleAutor der Antwort Fixation
Mit .NET 4.0 können Sie die
HandleProcessCorruptedStateExceptions
Attribut aus dem System.- Laufzeit.ExceptionServices, um die Methode mit try/catch-block. Dies funktionierte wirklich! Vielleicht nicht empfohlen, aber funktioniert.InformationsquelleAutor der Antwort jdehaan
Diese Antwort ist für @WilliamJockusch.
Es klingt wie Sie daran interessiert zu hören, einige debugging-Techniken zu erwischen, StackOverflow, so dass ich dachte, ich würde teilen, ein paar für Sie versuchen,.
1. Speicher-Dumps.
Pro: Memory-Dumps sind ein sicherer Weg, um herauszufinden, die Ursache von Stack Overflow. Ein C# - MVP und ich arbeiteten zusammen, Fehlerbehebung und SO ging er weiter zum blog über es hier.
Diese Methode ist der Schnellste Weg, um track down das problem.
Diese Methode nicht verlangen, dass Sie zum reproduzieren des Problems, indem Sie die folgenden Schritte aus gesehen in den logs.
Con ' s: Memory-Dumps sind sehr groß und befestigen Sie AdPlus/procdump den Prozess.
2. Aspekt Orientierte Programmierung.
Pro: Dies ist wahrscheinlich der einfachste Weg für Sie code implementieren, die überprüft die Größe der call-stack von jeder Methode, die ohne das schreiben von code in jeder Methode Ihrer Anwendung. Es gibt eine Reihe von AOP-Frameworks, die es ermöglichen, Sie Abzufangen, bevor und nach anrufen.
Wird Ihnen sagen, die Methoden sind, was die Stack-Überlauf.
Ermöglicht die Kontrolle der
StackTrace().FrameCount
bei der Einreise und Ausreise aller Methoden in Ihrer Anwendung.Con ' s: Es wird auf die Leistung auswirken - die Haken sind eingebettet in die IL für jede Methode und man kann nicht wirklich "de-aktivieren" aus.
Es etwas hängt von Ihrer Entwicklungsumgebung Werkzeug-set.
3. Protokollierung Der Benutzer-Aktivität.
Woche war ich versucht, auf die Jagd nach mehreren schwer zu reproduzieren Probleme. Ich stellte diese QA User Activity Logging, Telemetrie (und Variablen im Globalen Exception-Handler) . Die Schlussfolgerung kam ich, war eine wirklich einfache Benutzer-Aktionen-logger, um zu sehen, wie zum reproduzieren von Problemen in einer debugger, wenn jede nicht behandelte Ausnahme Auftritt.
Pro: Sie können ihn ein-oder auszuschalten (ie Anmeldung zu Veranstaltungen).
Tracking, das die Aktionen des Benutzers nicht erforderlich ist, das abfangen jeder Methode.
Können Sie zählen die Anzahl der Ereignisse, die Methoden sind abonniert zu weit einfacher als mit AOP.
Den log-Dateien sind relativ klein und konzentrieren sich auf das, was Aktionen, die Sie durchführen müssen, um das problem zu reproduzieren.
Es kann Ihnen helfen, zu verstehen, wie Benutzer mit Ihrer Anwendung.
Con ' s: Ist nicht geeignet, um einen Windows-Dienst und ich bin sicher, es gibt bessere Werkzeuge für web-Anwendungen.
Nicht unbedingt Ihnen sagen, die Methoden, die Ursache der Stack Overflow.
Erfordert, dass Sie Schritt für Schritt durch Protokolle manuell zu reproduzieren, eher Probleme als ein Speicher-Dump, wo Sie es bekommen können, und Debuggen Sie es sofort.
Vielleicht könnten Sie versuchen, alle Methoden, die ich oben erwähnt und einige, die @atlaste gepostet und sagen Sie uns was Sie fanden, waren die einfachste/Schnellste/schmutzigsten/die meisten akzeptabel laufen in eine PROD-Umgebung/usw.
Jedenfalls viel Glück das aufspüren dieser SO.
InformationsquelleAutor der Antwort Jeremy Thompson
Durch die Blicke von ihm, abgesehen vom starten von einem anderen Prozess, es scheint nicht zu irgendeiner Weise der Handhabung einer
StackOverflowException
. Bevor jemand fragt, ich habe versucht, mitAppDomain
, aber das hat nicht funktioniert:Wenn Sie am Ende mit dem trennen-process-Lösung, jedoch würde ich empfehlen, mit
Process.Exited
undProcess.StandardOutput
und verarbeiten die Fehler selber, um Ihren Benutzern eine bessere Erfahrung.InformationsquelleAutor der Antwort Nicholas Mertin
@WilliamJockusch, wenn ich das richtig verstanden deine Sorge, es ist nicht möglich (aus mathematischer Sicht) zu immer identifizieren, die eine unendliche Rekursion, da es bedeuten würde, zu lösen, die Halteproblem. Um es zu lösen brauchen Sie einen Super-rekursiven Algorithmus (wie Trial-and-error-Prädikate zum Beispiel) oder eine Maschine, die hypercompute (ein Beispiel ist die oben in der folgenden Abschnitt - verfügbar als Vorschau - der dieses Buch).
Aus praktischer Sicht, müsstest du wissen:
Bedenken, dass man mit den aktuellen Maschinen, die diese Daten ist extrem wandelbar ist, wegen multitasking und ich habe nicht gehört, einer software, die die Aufgabe.
Lassen Sie mich wissen, wenn etwas unklar ist.
InformationsquelleAutor der Antwort Gentian Kasa
Sind, Lesen Sie bitte diese Eigenschaft alle paar Anrufe
Environment.StackTrace
, und wenn der stacktrace exceded einen bestimmten Schwellenwert, den Sie voreingestellt haben, können Sie wieder die Funktion.Sollten Sie auch versuchen, zu ersetzen einige der rekursiven Funktionen mit Schlaufen.
InformationsquelleAutor der Antwort sharp12345