Der Stacktrace der Exception zeigt nicht an, wo die Ausnahme ausgelöst wurde

8

Wenn ich eine Ausnahme ausspreche, sie abfange und den Stacktrace ausdrucke, erhalte ich normalerweise den Aufruf, bei dem die Ausnahme ausgelöst wurde, den Aufruf, der dazu geführt hat, den Aufruf, der zu das und so weiter zurück zur Wurzel des gesamten Programms.

Jetzt wird mir nur der Aufruf angezeigt, bei dem die Ausnahme abgefangen wird, nicht wo sie geworfen wird . Ich kann nicht herausfinden, was geändert wurde, um zu diesem zu führen. Hier ist mein Programm:

%Vor%

Und hier wird was ausgedruckt:

%Vor%

Was ich erwartet habe, wäre etwa so:

%Vor%

Irgendwelche Ideen?

    
Joe 01.11.2011, 18:31
quelle

4 Antworten

10

Es wird weiterhin angezeigt, wo die Ausnahme ausgelöst wurde, nicht wo sie abgefangen wurde. Aber dank Optimierungen, die möglicherweise nicht dort sind, wo Sie erwarten, dass es geworfen wird.

Wahrscheinlich wurde die Funktion, die die Ausnahme auslöst, in die aufrufende Funktion eingebunden.

In diesem Fall erwarte ich, dass der JIT-Optimierer verantwortlich ist. Standardmäßig wird es nicht optimiert, wenn es in einem Debugger ausgeführt wird, sondern es wird optimiert und somit die Methode eingebunden, wenn es nicht in einem Debugger ausgeführt wird. Ich bin mir nicht sicher, ob ein Debug-Build Auswirkungen auf das Inlining hat.

Wenn Sie [MethodImpl(MethodImplOptions.NoInlining)] zu einer Funktion hinzufügen, wird es nicht inline und Ihre Stack-Trace sollte wie erwartet sein.

    
CodesInChaos 01.11.2011, 18:35
quelle
20

Ich werde diese Gelegenheit nutzen, um wieder zu sagen - wie ich es oft tue -, dass der Stack-Trace nicht Ihnen sagt, welche Methoden aufgerufen wurden, um zu dem Punkt zu gelangen, an dem die Ausnahme aufgetreten ist wurde geworfen . Ebenso sagt Ihnen das Stack-Fenster im Debugger nicht, welche Methoden die aktuelle Methode genannt wird.

In beiden Fällen teilt Ihnen ein Stack-Trace dagegen mit, wo die Kontrolle als nächstes hingehen wird, oder, im Falle einer Ausnahme, wo die Kontrolle wäre Als nächstes hatte es keine Ausnahme gegeben. Ein Stack-Trace ist eine Fortsetzung ; Es ist eine Datenstruktur, die die zukünftige Ausführung des Programms beschreibt. Es beschreibt nicht unbedingt die Vergangenheit.

Die Tatsache, dass "wohin du als nächstes gehst" fast immer dasselbe ist wie "woher ich komme" macht den Stack-Trace erst einmal zu einem nützlichen Debugging-Tool. Der Stack-Trace muss jedoch keine Informationen darüber enthalten, woher ich kam, wenn die Laufzeitumgebung diese Informationen sicher entfernen kann, ohne die Informationen "Wohin ich weiter muss" zu verfälschen. Die Laufzeit kann und beseitigt diese Information in einigen Fällen. Sie können sich nicht darauf verlassen, dass der Stack-Trace Ihnen sagt, woher Sie kommen, nur wohin Sie als nächstes gehen.

Diese Situation wird durch "async / await" in den nächsten Versionen von C # und VB nur verschärft; In einer Welt, in der asynchrone Methoden über den Fortsetzungsübergabestil implementiert werden, ist kein Stapel als Fortsetzung erforderlich, da die Fortsetzung in Form eines Delegaten auf dem Heap gespeichert ist. In dieser Welt wird dir die Stack-Spur fast nie sagen, "woher komme ich?"

    
Eric Lippert 01.11.2011 19:48
quelle
3

Wenn es sich um einen Release-Build ohne angehängtes Debugger handelt, ist es wahrscheinlich, dass das JIT eine Optimierung um inlining die Methoden; also f und g existieren nicht einmal.

Sie können bestätigen, dass dies der Fall ist, indem Sie das [MethodImpl(MethodImplOptions.NoInlining)] -Attribut auf die Methoden g und f anwenden, aber dies nur für Bildungszwecke tun. Sie sollten das JIT nicht daran hindern, in den Produktionscode zu inlinern.

Außerdem kann die x64-JIT als Tail-Call optimieren, so dass die MethodImplAttribute haben kann Keine Auswirkungen auf x64-Release-Builds.

    
vcsjones 01.11.2011 18:35
quelle
2

Aus der Dokumentation unter MSDN :

"Die StackTrace-Eigenschaft meldet möglicherweise nicht so viele Methodenaufrufe wie erwartet, da Codeumwandlungen, z. B. Inlining, während der Optimierung auftreten."

    
Dave C 01.11.2011 18:36
quelle

Tags und Links