2009-06-01 5 views
7

Ist es möglich, dass der Debugger (oder der CLR-Ausnahmehandler) die Zeile anzeigt, in der die Ausnahme im Freigabemodus mithilfe von pdb aufgetreten ist?Abrufen der Zeilennummer aus pdb im Freigabemodus

Der Code im Freigabemodus ist optimiert und entspricht nicht immer der Reihenfolge und Logik des "ursprünglichen" Codes.

Es ist auch überraschend, dass der Debugger auch im Release-Modus Schritt für Schritt durch meinen Code navigieren kann. Die Optimierung sollte die Navigation sehr unproblematisch machen.

Könnten Sie bitte diese zwei Punkte für mich klären?

Antwort

10

Ich bin nicht so vertraut, wie dies mit CLR gemacht wird, aber es ist wahrscheinlich sehr ähnlich, wie es mit nativem Code getan wird. Wenn der Compiler Maschinenbefehle erzeugt, fügt er Einträge zur pdb hinzu, die im Grunde sagen "die Anweisung an der aktuellen Adresse, X, kam aus Zeile 25 in foo.cpp".

Der Debugger weiß, welche Programmadresse gerade ausgeführt wird. Es sieht also eine Adresse, X, in der pdb und sieht, dass es aus Zeile 25 in foo.cpp kam. Auf diese Weise können Sie Ihren Quellcode "durchlaufen".

Dieser Prozess ist unabhängig vom Debug- oder Release-Modus identisch (vorausgesetzt, dass im Release-Modus überhaupt ein pdb generiert wird). Sie haben jedoch recht, dass der Debugger im Release-Modus aufgrund von Optimierungen oft nicht "linear" durch den Code springt. Es kann unerwartet zu anderen Zeilen springen. Dies liegt daran, dass der Optimierer die Reihenfolge der Anweisungen ändert, aber die Zuordnung von Adresse zu Quellzeile nicht ändert, so dass der Debugger dem Befehl immer noch folgen kann.

+0

Ty für Ihre ausführliche Antwort. Die Dinge sind jetzt klar für mich. –

0

Der Debugger versucht möglichst genau zu ermitteln, wo das Problem aufgetreten ist. Es ist nicht garantiert, dass es zu 100% genau ist, und bei vollständig optimiertem Code wird es oft ungenau sein. Ich habe herausgefunden, dass die Ungenauigkeiten von einigen Zeilen bis hin zu einem völlig falschen Call-Stack reichen.

Wie genau der Debugger mit optimiertem Code ist, hängt wirklich vom Code selbst und von den Optimierungen ab, die Sie vornehmen.

+1

Ty. "zu einem völlig falschen Call-Stack." die Stack-Spur sollte nicht immer genau sein? –

+0

Gibt es eine Quelle oder mehr Informationen über Zeilennummern? Ich habe einige Posts in SO auf Debugging/PDB/Compiler-Code-Optimierung, und keinen klaren Punkt zu diesem Thema gefunden. – gerleim

1

[@Not Sure] hat es fast richtig. Der Compiler bemüht sich am besten, eine entsprechende Zeilennummer zu identifizieren, die der aktuellen Maschinencodeanweisung entspricht.

Die PDB und der Debugger wissen nichts über Optimierungen; Die PDB-Datei bildet Adressenadressen im Maschinencode im wesentlichen auf Quellcodezeilennummern ab. In optimiertem Code ist es nicht immer möglich, eine Assembly-Anweisung genau einer bestimmten Quellcodezeile zuzuordnen, sodass der Compiler die PDB so genau beschreibt, wie es gerade zur Verfügung steht. Dies könnte "die Quellcodezeile vor" oder "die Quellcodezeile des umschließenden Kontexts (Schleife, etc)" oder etwas anderes sein.

Unabhängig davon findet der Debugger im Wesentlichen den Eintrag in der PDB-Map, der der aktuellen IP (Instruction Pointer) am nächsten kommt (wie in "before or equal") und markiert diese Zeile.

Manchmal ist das Spiel nicht sehr gut und dann sieht man den hervorgehobenen Bereich überall herumspringen.

+1

Vielleicht generiert der Compiler eine andere pdb für die Freigabe und für den Debug-Modus. Der pdb für den Freigabemodus berücksichtigt die Optimierung, sodass eine relativ genaue Zeile für eine Ausnahme angegeben werden kann. –

+0

Oh, absolut. Die PDB ist für immer an dieselbe Instanz der DLL (oder EXE) gebunden, mit der sie erstellt wurde. Beachten Sie, dass Sie die PDBs und DLLs auch dann nicht mischen und abgleichen können, wenn Sie im selben Modus neu kompilieren, ohne dass Änderungen an der Quelldatei vorgenommen wurden. Ihr PDB muss derselbe genau sein, der erstellt wurde, wenn das Modul (DLL oder EXE), das Sie debuggen, kompiliert wurde, da der Compiler möglicherweise an verschiedenen Stellen in jedem Build Stoff anordnet. Wolltest du das tun? –

+0

@Euro Micelli:> der Compiler könnte zufällig Sachen an verschiedenen Stellen auf jedem Build setzen