26 Stimmen

Wie funktioniert die Funktion "Bearbeiten und fortfahren" in Visual Studio?

Ich habe dies immer als eine sehr nützliche Funktion in Visual Studio empfunden. Für diejenigen, die sie noch nicht kennen: Sie können damit Code bearbeiten, während Sie einen laufenden Prozess debuggen, den Code neu kompilieren während die Binärdatei noch läuft und die Anwendung nahtlos mit dem neuen Code weiter nutzen, ohne sie neu starten zu müssen.

Wie wird diese Funktion umgesetzt? Wenn der Code, den ich ändere, in einer von der Anwendung geladenen DLL enthalten ist, entlädt die Anwendung dann einfach die DLL und lädt sie erneut? Das scheint mir anfällig für Instabilitätsprobleme zu sein, daher nehme ich an, dass die Anwendung intelligenter ist als das. Hat jemand eine Idee?

18voto

Nick Punkte 6782

Meines Erachtens lässt der Compiler beim Kompilieren der Anwendung mit aktivierter Unterstützung für "Edit and Continue" zusätzlichen Platz um die Funktionen im Binärabbild herum, damit zusätzlicher Code hinzugefügt werden kann. Dann kann der Debugger eine neue Version der Funktion kompilieren, die bestehende Version ersetzen (unter Verwendung des Platzes zum Auffüllen, falls erforderlich), den Stack reparieren, den Befehlszeiger setzen und weitergehen. Auf diese Weise brauchen Sie keine Sprungzeiger zu reparieren, solange Sie genügend Platz haben.

Beachten Sie, dass "Bearbeiten und Fortsetzen" normalerweise nicht mit Code in Bibliotheken/DLLs funktioniert, sondern nur mit dem ausführbaren Hauptcode.

8voto

Evan Teran Punkte 83711

Meine erraten ist, dass die Anwendung neu kompiliert wird (und bei kleinen Änderungen würde dies nicht bedeuten, dass sehr viel neu kompiliert werden müsste). Da Microsoft sowohl den Compiler als auch den Debugger herstellt, können sie Garantien dafür geben, wie Speicher und Ähnliches angelegt sind. Sie können also die Debugging-API verwenden, um die Codesegmente mit den neuen Segmenten neu zu schreiben, solange die Änderungen klein genug sind.

Wenn die Änderungen zu völlig neuem Code führen, kann dieser natürlich in ähnlicher Weise wie DLLs in den Speicher geladen werden.

Microsoft hat auch einen Mechanismus für "hot-Parcheando". Funktionen haben einen 2-Byte-No-Op-Befehl, normalerweise etwas wie "mov edx, edx" vor dem eigentlichen Code. Dies ermöglicht es ihnen, die Ausführung einer Funktion sauber umzuleiten. Dies kann auch eine Option sein.

Das Wichtigste dabei ist, dass die Anwendung nicht "läuft", sondern alle Threads im angehaltenen Zustand sind. Soweit es den Prozess betrifft, sind also alle Änderungen, die der Debugger vornimmt, völlig atomar.

Natürlich ist das alles Spekulation ;)

1voto

graham.reeds Punkte 15745

Ich vermute, dass alle Objekte an einer Speichergrenze von 4096 Byte ausgerichtet sind. Wenn Sie also kleine Änderungen am Code vornehmen, werden die Objekte immer noch innerhalb dieser Grenzen liegen und daher wie zuvor ausgeführt.

Ich habe Fälle erlebt, in denen die Änderung von ein paar Zeilen eine vollständige Neukompilierung und -verknüpfung zur Folge hatte, und andere, in denen eine ziemlich umfangreiche Umstrukturierung einer Funktion ausgereicht hat, um e&c zu erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X