Remotedebuggen von Python-Code unter Linux in Visual Studio

In diesem Artikel erfahren Sie, wie Sie Ihre Visual Studio-Installation so konfigurieren, dass das Debuggen von Python-Code auf Remote-Linux-Computern unterstützt wird. Diese exemplarische Vorgehensweise basiert auf Visual Studio 2019, Version 16.6.

Visual Studio kann Python-Anwendungen sowohl lokal als auch remote auf einem Windows-Computer starten und debuggen. Visual Studio unterstützt auch das Remote-Debuggen auf einem anderen Betriebssystem, Gerät oder einer anderen Python-Implementierung als CPython mithilfe von debugpy-Bibliothek.

Visual Studio 2019, Version 16.4 und früher, verwendet die ptvsd-Bibliothek. Die debugpy-Bibliothek ersetzt ptvsd in Visual Studio 2019, Version 16.5 und höher. Bei Verwendung von debugpy hostet der Python-Code, für den das Debuggen ausgeführt werden soll, den Debugserver, an den Visual Studio angefügt werden kann. Für dieses Hosting ist eine kleine Änderung des Codes erforderlich, um den Server zu importieren und zu aktivieren. Möglicherweise müssen Sie auch die Netzwerk- oder Firewallkonfigurationen auf dem Remotecomputer anpassen, um TCP-Verbindungen zuzulassen.

Voraussetzungen

  • Visual Studio wurde mit Unterstützung für Python-Workloads installiert. Weitere Informationen finden Sie unter Installieren von Python-Unterstützung in Visual Studio.

  • Einen Remotecomputer, auf dem Python unter einem Betriebssystem wie Mac OSX oder Linux ausgeführt wird.

  • Port 5678 (eingehend) ist in der Firewall des Remotecomputers geöffnet. Dies ist die Standardeinstellung für das Remotedebuggen.

Einrichten eines Linux-Computers

Sie können problemlos virtuelle Linux-Computer in Azure erstellen und von Windows aus über Remotedesktop darauf zugreifen. Ubuntu für den virtuellen Computer ist praktisch, da Python standardmäßig installiert ist. Wenn Sie über eine andere Konfiguration verfügen, lesen Sie Installieren von Python-Interpreter für andere Python-Downloadspeicherorte.

Konfigurieren der Firewall

Der eingehende Port 5678 muss in der Firewall des Remotecomputers geöffnet sein, um Remotedebugging zu unterstützen.

Ausführliche Informationen zum Erstellen einer Firewallregel für einen virtuellen Azure-Computer finden Sie in den folgenden Artikeln:

Vorbereiten des Skripts für das Debuggen

Führen Sie die folgenden Schritte aus, um ein Skript zum Debuggen Ihres Python-Codes unter Linux vorzubereiten.

  1. Erstellen Sie auf dem Remotecomputer eine Python-Datei mit dem Namen guessing-game.py mit dem folgenden Code:

    import random
    
    guesses_made = 0
    name = input('Hello! What is your name?\n')
    number = random.randint(1, 20)
    print('Well, {0}, I am thinking of a number between 1 and 20.'.format(name))
    
    while guesses_made < 6:
        guess = int(input('Take a guess: '))
        guesses_made += 1
        if guess < number:
            print('Your guess is too low.')
        if guess > number:
            print('Your guess is too high.')
        if guess == number:
            break
    if guess == number:
        print('Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made))
    else:
        print('Nope. The number I was thinking of was {0}'.format(number))
    
  2. Installieren Sie das debugpy-Paket in Ihrer Umgebung mithilfe des pip3 install debugpy-Befehls.

    Hinweis

    Es empfiehlt sich, die installierte Version von debugpy aufzuzeichnen, falls Sie sie für die Problembehandlung benötigen. Die debugpy-Liste zeigt auch verfügbare Versionen an.

  3. Aktivieren Sie das Remotedebugging, indem Sie den folgenden Code oben in der guessing-game.py-Datei vor dem anderen Code hinzufügen. (Dies ist zwar nicht zwingend erforderlich, aber es ist unmöglich, Hintergrundthreads zu debuggen, die vor dem Aufruf der Funktion listen erzeugt werden.)

    import debugpy
    debugpy.listen(('0.0.0.0', 5678))
    
  4. Speichern Sie die Datei, und führen Sie das Programm aus:

    python3 guessing-game.py
    

    Der Aufruf der Funktion listen wird im Hintergrund ausgeführt und wartet auf eingehende Verbindungen, während Sie mit dem Programm interagieren. Bei Bedarf können Sie die wait_for_client-Funktion nach dem Aufrufen der listen-Funktion aufrufen, um das Programm zu blockieren, bis der Debugger angefügt wird.

Tipp

Zusätzlich zu den Funktionen listen und wait_for_client stellt debugpy auch eine Hilfsfunktion breakpoint bereit. Diese Funktion dient als programmgesteuerter Haltepunkt, wenn der Debugger angefügt ist. Eine andere Funktion is_client_connected1 gibt True zurück, wenn der Debugger angefügt ist. Sie müssen dieses Ergebnis nicht überprüfen, bevor Sie andere debugpy-Funktionen aufrufen.

Remoteanfügen über Python Tools

Die folgenden Schritte zeigen, wie Sie einen Haltepunkt festlegen, um den Remotevorgang zu beenden.

  1. Erstellen Sie eine Kopie der Remotedatei auf dem lokalen Computer, und öffnen Sie diese in Visual Studio. Es spielt keine Rolle, wo die Datei gespeichert wird, der Name muss aber dem Namen des Skripts auf dem Remotecomputer entsprechen.

  2. (Optional) Um auf dem lokalen Computer IntelliSense für debugpy zu nutzen, können Sie das debugpy-Paket in Ihrer Python-Umgebung installieren.

  3. Wählen Sie Debuggen>An den Prozess anhängen aus.

  4. Legen Sie im Dialogfeld An den Prozess anhängen den Verbindungstyp auf Python remote (debugpy) fest.

  5. Geben Sie im Feld Verbindungsziel den Befehl tcp://<ip_address>:5678 ein.

    • tcp:// gibt den Verbindungstyp als Transmission Control Protocol (TCP) an.
    • <ip_address> ist die IP-Adresse des Remotecomputers, die eine explizite Adresse oder ein Name wie myvm.cloudapp.net sein kann.
    • :5678 ist die Portnummer für Remotedebugging.
  6. Drücken Sie die EINGABETASTE, um die Liste der auf diesem Computer verfügbaren debugpy-Prozesse aufzufüllen:

    Screenshot that shows how to enter the connection target to see a list of available debugpy processes.

    Wenn Sie nach dem Auffüllen dieser Liste ein anderes Programm auf dem Remotecomputer starten, klicken Sie auf die Schaltfläche Aktualisieren.

  7. Wählen Sie den Prozess zum Debuggen und dann Anfügen aus, oder doppelklicken Sie auf den Prozess.

  8. Visual Studio wechselt in den Debugmodus, während das Skript weiterhin auf dem Remotecomputer ausgeführt wird, und bietet alle üblichen Funktionen zum Debuggen.

    Sie können einen Haltepunkt in der Zeile if guess < number: festlegen, dann zum Remotecomputer wechseln und einen anderen Schätzwert eingeben. Visual Studio auf Ihrem lokalen Computer stoppt am Haltepunkt, zeigt lokale Variablen an und so weiter:

    Screenshot that shows how Visual Studio pauses debugging when a breakpoint is hit.

  9. Wenn Sie das Debuggen beenden, wird Visual Studio vom Programm getrennt. Das Programm wird weiterhin auf dem Remotecomputer ausgeführt. debugpy lauscht außerdem weiterhin auf angefügte Debugger, sodass Sie den Prozess jederzeit erneut wieder anfügen können.

Problembehandlung der Verbindung

Überprüfen Sie die folgenden Punkte, um Probleme mit der Verbindung zu beheben.

  • Stellen Sie sicher, dass Sie Python remote (debugpy) als Verbindungstyp auswählen.

  • Bestätigen Sie, dass das Geheimnis im Verbindungsziel genau mit dem Geheimnis im Remotecode übereinstimmt.

  • Bestätigen Sie, dass die IP-Adresse im Verbindungsziel der des Remotecomputers entspricht.

  • Stellen Sie sicher, dass der Remotedebugging-Port auf dem Remote-Computer geöffnet ist und das Verbindungsziel das Port-Suffix enthält, z. B. :5678.

    Wenn Sie einen anderen Port verwenden möchten, geben Sie die Portnummer im Aufruf der listen-Funktion wie in debugpy.listen((host, port)) an. Stellen Sie in diesem Fall sicher, dass Sie den entsprechenden Port in der Firewall öffnen.

  • Bestätigen Sie, dass die auf dem Remotecomputer installierte debugpy-Version (wie vom pip3 list-Befehl zurückgegeben) mit der Visual Studio Python Tools-Version (PTVS) übereinstimmt.

    In der folgenden Tabelle sind die gültigen Versionspaare aufgeführt. Aktualisieren Sie bei Bedarf die Version von debugpy auf dem Remotecomputer.

    Visual Studio Python-Tools debugpy
    2019 16.6 1.0.0b5 1.0.0b5
    2019 16.5 1.0.0b1 1.0.0b1

Hinweis

Visual Studio 2019, Version 16.0-16.4 verwendet ptvsd, nicht debugpy. Das Verfahren in dieser exemplarischen Vorgehensweise ist für diese Versionen ähnlich, aber die Funktionsnamen unterscheiden sich. Visual Studio 2019, Version 16.5 verwendet debugpy, aber die Funktionsnamen sind dieselben wie in ptvsd. Anstelle von listen verwenden Sie enable_attach. Anstelle von wait_for_client verwenden Sie wait_for_attach. Anstelle von breakpoint verwenden Sie break_into_debugger.

Verwenden von ptvsd 3.x für ein Legacydebugging

Der Legacydebugger ptvsd 3.x ist der Standard in Visual Studio 2017 Version 15.7 und früher.

Abhängig von Ihrer Visual Studio-Konfiguration müssen Sie möglicherweise ptvsd 3.x für das Remotedebuggen verwenden:

  • Visual Studio 2017, Version 15.7 und früher mit Python 2.6, 3.1 bis 3.4 oder IronPython
  • Visual Studio 2019, Version 16.5 und höher mit Python 2.6, 3.1 bis 3.4 oder IronPython
  • Frühere 4.x-Versionen

Wenn Ihre Konfiguration ein älteres Versionsszenario implementiert, zeigt Visual Studio die Fehlermeldung Debugger unterstützt diese Python-Umgebung nicht an.

Einrichten des Remotedebuggings

Führen Sie die folgenden Schritte aus, um das Remotedebugging mit ptvsd 3.x vorzubereiten:

  1. Richten Sie Ihren geheimen Schlüssel ein, der verwendet wird, um den Zugriff auf das ausgeführte Skript einzuschränken.

    In ptvsd 3.x erfordert die enable_attach-Funktion, dass Sie ein „Geheimnis“ als erstes Argument übergeben.

    • Wenn Sie den Remotedebugger anfügen, geben Sie den geheimen Schlüssel mit dem Befehl enable_attach(secret="<secret>") ein.

    Obwohl Sie mit dem Befehl enable_attach(secret=None) jedem erlauben können, eine Verbindung herzustellen, wird diese Option nicht empfohlen.

  2. Erstellen Sie im Formular tcp://<secret>@<ip_address>:5678 Ihre Verbindungsziel-URL.

    • tcp:// gibt den Verbindungstyp als TCP an.
    • <secret> ist die Zeichenfolge, die mit der enable_attach-Funktion im Python-Code übergeben wird.
    • <ip_address> ist die IP-Adresse des Remotecomputers, die eine explizite Adresse oder ein Name wie myvm.cloudapp.net sein kann.
    • :5678 ist die Portnummer für Remotedebugging.

Sichere Verbindung mit TCPS-Protokoll

In der Standardeinstellung ist die Verbindung mit dem ptvsd-Remotedebugserver 3.x nur durch den geheimen Schlüssel geschützt, und alle Daten werden als Nur-Text übergeben. Für eine sicherere Verbindung unterstützt ptvsd 3.x SSL mithilfe der sicheren Form des TCP-Protokolls oder TCPS.

Führen Sie die folgenden Schritte aus, um ptvsd 3.x für die Arbeit mit dem TCPS-Protokoll zu konfigurieren:

  1. Verwenden Sie auf dem Remotecomputer den openssl-Befehl, um separate Dateien für den Schlüssel und das selbstsignierte Zertifikat zu generieren:

    openssl req -new -x509 -days 365 -nodes -out cert.cer -keyout cert.key
    
    • Geben Sie an der Eingabeaufforderung openssl den Hostnamen oder die IP-Adresse ein, die Sie für die Verbindung für den allgemeinen Namen verwenden.

    Weitere Informationen finden Sie unter selbstsignierte Zertifikate in der Python-Moduldokumentation ssl. Beachten Sie, dass der in der Python-Dokumentation beschriebene Befehl nur eine einzige kombinierte Datei generiert.

  2. Ändern Sie im Code den Aufruf der enable_attach-Funktion so, dass sie certfile- und keyfile-Argumente einbezieht, indem Sie die Dateinamen als Werte verwenden. Diese Argumente haben die gleiche Bedeutung wie für die ssl.wrap_socket-Python-Standardfunktion.

    ptvsd.enable_attach(secret='my_secret', certfile='cert.cer', keyfile='cert.key')
    

    Sie können auch dieselbe Änderung in der Codedatei auf dem lokalen Computer vornehmen. Da dieser Code nicht tatsächlich ausgeführt wird, ist er nicht unbedingt erforderlich.

  3. Starten Sie das Python-Programm auf dem Remotecomputer neu, damit es zum Debuggen bereit ist.

  4. Sichern Sie den Kanal, indem Sie das Zertifikat der vertrauenswürdigen Stammzertifizierungsstelle auf dem Windows-Computer mit Visual Studio hinzufügen:

    1. Kopieren Sie die Zertifikatdatei vom Remotecomputer auf den lokalen Computer.

    2. Öffnen Sie die Systemsteuerung, und wechseln Sie zu Windows-Tools>Computerzertifikate verwalten.

    3. Erweitern Sie im Dialogfeld certlm [Zertifikate – lokaler Computer] den Knoten Vertrauenswürdige Stammzertifizierungsstellen, klicken Sie mit der rechten Maustaste auf Zertifikate, und wählen Sie Alle Aufgaben>Importieren aus.

    4. Navigieren Sie zu der .cer-Datei, die vom Remotecomputer kopiert wurde, und wählen Sie sie aus.

    5. Fahren Sie mit den Dialogfeldaufforderungen fort, um den Importvorgang abzuschließen.

  5. Wiederholen Sie den Anfügungsprozess in Visual Studio, wie weiter oben in Remoteanfügen über Python Tools beschrieben.

    Definieren Sie tcps:// für diese Instanz als Protokoll für das Verbindungsziel (oder den Qualifizierer).

    Screenshot that shows how to specify TCPS as the remote debugging transport with SSL.

Beheben von Verbindungsproblemen

Während des Verbindungsversuchs treten möglicherweise Probleme in Visual Studio auf. Überprüfen Sie die folgenden Szenarien, und ergreifen Sie bei Bedarf die entsprechenden Maßnahmen.

  • Visual Studio warnt vor möglichen Zertifikatproblemen bei der Verbindung über SSL.

    Aktion: Sie können die Nachricht ignorieren und fortfahren.

    Achtung

    Bedenken Sie, dass der Kanal zwar immer noch gegen Abhören verschlüsselt ist, aber anfällig für Man-in-the-Middle-Angriffe sein kann.

  • Visual Studio zeigt die Warnung Das Remotezertifikat ist nicht vertrauenswürdig an.

    Problem: Das Zertifikat wird der vertrauenswürdigen Stammzertifizierungsstelle nicht ordnungsgemäß hinzugefügt.

    Aktion: Überprüfen Sie erneut die Schritte, um das Zertifikat der vertrauenswürdigen Stammzertifizierungsstelle auf dem Windows-Computer hinzuzufügen, und versuchen Sie erneut, die Verbindung herzustellen.

    Screenshot of the warning that says the remote SSL certificate isn't trusted.

  • Visual Studio zeigt die Warnung Der Name des Remotezertifikats stimmt nicht mit dem Hostnamen überein an.

    Problem: Der richtige Hostname oder die richtige IP-Adresse ist für den allgemeinen Namen für das Zertifikat nicht angegeben.

    Aktion: Überprüfen Sie die Schritte in Sichern der Verbindung mit TCPS. Stellen Sie sicher, dass Sie den richtigen allgemeinen Namen verwenden, wenn Sie das Zertifikat erstellen, und versuchen Sie erneut, eine Verbindung herzustellen.

    Screenshot of the warning that says the remote SSL certificate doesn't match the hostname.