Einen Bug debuggen, der nur auf einer Maschine ohne Visual Studio auftritt
Ein Bug reproduziert auf dem Testserver, aber nicht auf Ihrem Laptop. Der Testserver hat kein Visual Studio, und dort eine komplette IDE zu installieren, nur um einen Breakpoint zu setzen, kommt nicht infrage. Genau dafür ist Remote-Debugging gemacht. Ein kleines, eigenständiges Programm läuft auf der Zielmaschine, Ihr lokales Visual Studio verbindet sich über das Netzwerk damit, und Sie bekommen Breakpoints und Variableninspektion auf einem Prozess, der nirgendwo in der Nähe Ihres Schreibtischs läuft.
Es gibt drei Schritte: den Remote-Debugger auf dem Ziel starten, aus Visual Studio daran anhängen, passende Symbole laden. Jeder scheitert auf seine ganz eigene Art. Danach folgen die zwei Remote-Ziele, auf die Sie in der Praxis am ehesten stoßen: ein Prozess in einem Docker-Container und eine App auf Azure App Service.
Wie Sie den Visual Studio Remote-Debugger (msvsmon) installieren und starten
Das Programm heißt msvsmon.exe, der Visual Studio Remote-Debugger. Es gibt
zwei Wege, es auf die Zielmaschine zu bekommen.
Ist auf dem Ziel bereits Visual Studio Community, Professional oder Enterprise
installiert, liegt msvsmon.exe schon dort, unter
<Visual-Studio-Installationsordner>\Common7\IDE\Remote Debugger\x64\ (oder
x86\, passend zur Architektur, die Sie debuggen). Starten Sie es direkt.
Andernfalls laden Sie das eigenständige Remote-Tools-Paket von Microsofts Remote-Tools-Seite für Ihre Visual-Studio-Version herunter, und nehmen Sie den neuesten Stand davon. Die Kompatibilität funktioniert nur in eine Richtung: neuere Remote-Tools funktionieren mit einem älteren Visual Studio, aber ältere Remote-Tools können ein neueres ablehnen. Wählen Sie die Architektur des Ziel-Betriebssystems (x86, x64 oder ARM64), nicht die der App, die Sie debuggen.
Beim ersten Start öffnet sich ein Konfigurationsassistent, der eine Windows-Firewall-Regel für den Netzwerktyp anlegt, in dem Sie sich befinden (Domäne, privat oder öffentlich). Ist er fertig, zeigt das Remote-Debugger-Fenster einen Servernamen und einen Port an. Das ist die Adresse, die Sie später in Visual Studio eintragen. Lassen Sie das Fenster offen — es zu schließen (Datei > Beenden) beendet die Sitzung.
Remote-Debugger-Ports und Authentifizierung: was die Verbindung blockiert
Die Firewall-Regel des Assistenten öffnet nur den eingehenden TCP-Port, und dieser Port ändert sich mit der Visual-Studio-Version. Für Visual Studio 2022 ist es 4026, ältere Versionen verwenden andere Nummern. Sitzt das Ziel hinter einer Firewall, die der Assistent nicht konfiguriert hat — etwa einer Firmen-Appliance oder einer Cloud-Security-Group —, öffnen Sie diesen spezifischen Port selbst. „Den Debugger-Port“ zu raten, ohne Ihre Version zu prüfen, kostet nur Zeit.
UDP 3702 ausgehend ist optional. Es sorgt dafür, dass das Ziel im Suchen-Dialog von Visual Studio auftaucht. Ohne diesen Port können Sie sich trotzdem verbinden, Sie tragen die Adresse dann von Hand ein.
Der Authentifizierungsmodus muss auf beiden Seiten übereinstimmen.
Standardmäßig nutzt der Remote-Debugger Windows-Authentifizierung, das
Windows-Konto, unter dem Visual Studio läuft, braucht also eine Berechtigung
auf dem Remote-Debugger. Vergeben Sie sie unter Tools > Berechtigungen im
Remote-Debugger-Fenster (Administratorrechte erforderlich), oder starten Sie
msvsmon von der Kommandozeile mit dem bereits zugelassenen Konto:
| |
Auf Keine Authentifizierung umzuschalten (Tools > Optionen im Remote-Debugger-Fenster) überspringt all das, und auf einer Wegwerf-VM ist das verlockend. Tun Sie es nur in einem Netzwerk, dem Sie vollständig vertrauen. Wer immer diesen Port erreicht, kann sich an jeden Prozess anhängen, der unter demselben Konto läuft — keine Abfrage, kein Passwort.
Wie Sie sich von Visual Studio aus an einen Remote-Prozess anhängen
Läuft der Remote-Debugger und ist er erreichbar:
- Öffnen Sie in Visual Studio Debuggen > An Prozess anhängen
(
Strg+Alt+P). - Setzen Sie Verbindungstyp auf Remote (Windows).
- Tragen Sie unter Verbindungsziel die Adresse in dem Format ein, das
das Fenster des Remote-Debuggers selbst zeigt, meist
<Maschinenname>:<Port>. Löst der Maschinenname nicht auf, verwenden Sie die IP:10.0.0.15:4026. - Klicken Sie auf Aktualisieren, um die Prozessliste von der Remote-Maschine zu laden, und suchen und wählen Sie Ihren Prozess. Läuft er nicht unter Ihrem Konto, aktivieren Sie Prozesse von allen Benutzern anzeigen. Visual Studio zeigt vor dem Anhängen an einen fremden Prozess eine Sicherheitswarnung — lesen Sie sie, statt sie wegzuklicken.
- Lassen Sie Codetyp auf Automatisch. Die Ausnahme ist ein gemischter Prozess, bei dem das Anhängen für eine Sprache lautlos fehlschlägt: Wählen Sie diese Sprache explizit und hängen Sie erneut an, dann bekommen Sie einen konkreten Fehler statt gar nichts.
- Klicken Sie auf Anhängen.
Bei einer IIS-gehosteten ASP.NET-App ist w3wp.exe der gesuchte Prozess. Bei
einer .NET-App mit eigenem Kestrel-Server ist es dotnet.exe oder der Name
der eigenen ausführbaren Datei. IIS lässt oft mehrere identische
w3wp.exe-Prozesse nebeneinander laufen. Die Spalte Befehlszeile in der
Prozessliste unterscheidet sie voneinander.
„Keine Symbole geladen" beim Remote-Debugging beheben
Angehängt zu sein heißt noch nicht, debuggen zu können. Öffnen Sie Debuggen > Fenster > Module und prüfen Sie die Spalte Symbolstatus für Ihre Binärdatei. Ein hohler, roter Breakpoint-Kreis statt eines ausgefüllten sagt von der Editor-Seite aus dasselbe: Der Debugger hat keine Symbole, um diesen Breakpoint zuzuordnen.
In der Praxis tauchen drei Zustände auf:
| Status | Was es bedeutet | Lösung |
|---|---|---|
Skipped loading symbols | Das Laden von Symbolen wird durch Ihre Einstellungen herausgefiltert | Prüfen Sie Debuggen > Optionen > Symbole auf eine Ein-/Ausschlussregel, die dieses Modul blockiert |
Cannot find or open the PDB file | Keine passende .pdb ist erreichbar | Kopieren Sie exakt die .pdb aus dem Build, der die deployte Binärdatei erzeugt hat, auf die Remote-Maschine, oder verweisen Sie Visual Studio direkt darauf |
| Kein Eintrag / nur nativ wirkender Hex-Code | Das Modul hat gar keine Debug-Informationen | Es wurde im Release-Modus ohne .pdb gebaut, oder es ist eine System-DLL, die Sie nicht debuggen müssen |
Der Großteil der hier verlorenen Zeit kommt von einer einzigen Regel: Der
Debugger akzeptiert nur eine .pdb, die exakt zur Binärdatei passt. Nicht
„dieselbe Version" — die Datei aus genau diesem Build. Wurde die
Remote-Maschine nach Ihrem letzten lokalen Build neu deployt, passt Ihre
lokale .pdb nicht mehr. Findet das automatische Laden sie nicht,
klicken Sie im Modulfenster mit der rechten Maustaste auf das Modul, wählen
Sie Symbole laden und navigieren Sie zum eigenen Ausgabeordner des
Deployments.
Die Gewohnheit, die das von vornherein verhindert: Liefern Sie die .pdb
bei jedem Deploy, das Sie eventuell debuggen müssen, gleich mit der
Binärdatei aus. Eine passende im Nachhinein zu rekonstruieren, gelingt selten.
Wie Sie einen Prozess in einem Docker-Container debuggen
Alles bisher Gesagte setzt eine Windows-Maschine voraus, auf der Sie Software
installieren dürfen. Ein Container ist anders. msvsmon gehört nicht in ein
Produktions-Image, und je nach Konfiguration des
Docker-Netzwerks
ist der Container von Ihrem Host aus vielleicht nicht einmal über seinen
Namen erreichbar.
Hat das Projekt Docker-Unterstützung aktiviert (Hinzufügen > Docker-
Unterstützung, oder ein Projekt, das bereits mit einem Dockerfile
vorbereitet ist), übernimmt Visual Studios Container-Tooling die Arbeit:
F5 baut ein für Debugging konfiguriertes Image, startet den Container und
hängt sich an. Für einen Container, den Sie nicht aus Visual Studio gestartet
haben, öffnen Sie Debuggen > An Prozess anhängen, setzen den
Verbindungstyp passend zum Image auf Docker (Linux-Container) oder
Docker (Windows-Container) und wählen den Container aus der Liste. Visual
Studio geht dabei über den Docker-Daemon und setzt seinen eigenen Debugger in
den laufenden Container — Sie müssen dem Image selbst nie einen hinzufügen.
Wie Sie eine App auf Azure App Service remote debuggen
Für eine auf Azure App Service deployte App überspringen Sie das manuelle Remote-Debugger-Setup. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, wählen Sie Veröffentlichen und dann im …-Menü des Veröffentlichungsprofils Debugger anhängen. Visual Studio aktiviert den Remote-Debugging-Endpunkt auf der App-Service-Instanz und übernimmt Verbindung und Authentifizierung für Sie. Sobald Sie angehängt sind, gelten die Symbolregeln aus den vorherigen Abschnitten weiterhin. Prüfen Sie das Modulfenster, bevor Sie einem Breakpoint trauen.
Remote-Debugger oder Git Bisect: womit Sie zuerst anfangen
Ein Remote-Debugger sagt Ihnen, was eine bestimmte Zeile gerade auf einer
bestimmten Maschine tut. Welcher Commit das Problem eingeführt hat, kann er
nicht sagen. git bisect
beantwortet genau das, mit einer binären Suche über die Historie statt einer
Suche im eigenen Gedächtnis.
Bei einer Regression gehen Sie in dieser Reihenfolge vor. Wissen Sie noch nicht, welcher Commit etwas kaputt gemacht hat, bisecten Sie zuerst. Sobald Sie den Commit und eine Maschine haben, auf der der Bug reproduziert, richten Sie dort den Remote-Debugger ein und finden heraus, warum.