Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die meisten regulären Python-Debugger unterstützen nur das Debuggen von Python-Code, aber es ist üblich, dass Entwickler Python mit C oder C++ verwenden. Einige Szenarien, die gemischten Code verwenden, sind Anwendungen, die entweder eine hohe Leistung erfordern oder direkt Plattform-APIs aufrufen können und häufig in Python sowie C oder C++ geschrieben sind.
Visual Studio bietet integriertes, gleichzeitiges Debuggen im gemischten Modus für Python und systemeigenen C/C++-Code. Die Unterstützung ist verfügbar, wenn Sie die nativen Python-Entwicklungstools für die Python-Entwicklungsarbeitslast im Visual Studio-Installationsprogramm auswählen.
In diesem Artikel erfahren Sie, wie Sie mit den folgenden Features für das Debuggen im gemischten Modus arbeiten:
- Kombinierte Aufrufstapel
- Schritt zwischen Python und systemeigenem Code
- Haltepunkte in beiden Codetypen
- Anzeigen von Python-Darstellungen von Objekten in nativen Frames und umgekehrt
- Debuggen im Kontext des Python-Projekts oder des C++-Projekts
Voraussetzungen
Visual Studio 2017 und höher. Das Debuggen im gemischten Modus ist in Visual Studio 2015 und früheren Versionen nicht mit Python-Tools für Visual Studio 1.x verfügbar.
Visual Studio mit Unterstützung für Python-Workloads installiert. Weitere Informationen finden Sie unter Installieren der Python-Unterstützung in Visual Studio.
Gemischten Modus-Debugging in einem Python-Projekt aktivieren
Die folgenden Schritte beschreiben, wie Sie das Debuggen im gemischten Modus in einem Python-Projekt aktivieren:
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Python-Projekt, und wählen Sie "Eigenschaften" aus.
Wählen Sie im Eigenschaftenbereich die Registerkarte " Debuggen " und dann die Debugoption "Systemeigenes>Codedebugging aktivieren" aus :
Diese Option aktiviert den gemischten Modus für alle Debugsitzungen.
Tipp
Wenn Sie das Debugging des nativen Codes aktivieren, wird das Python-Ausgabefenster möglicherweise sofort geschlossen, nachdem das Programm beendet wurde, ohne anzuhalten und den Hinweis Press any key to continue anzuzeigen. Um die Pause und Eingabeaufforderung zu erzwingen, nachdem Sie das native Code-Debugging aktiviert haben, fügen Sie das
-iArgument zum Feld "Ausführen>-Interpreterargumente" auf der Registerkarte "Debuggen" hinzu. Dieses Argument versetzt den Python-Interpreter nach Ausführung des Codes in den interaktiven Modus. Das Programm wartet, bis Sie STRG+Z+EINGABETASTE zum Schließen des Fensters gedrückt haben.Wählen Sie "Datei>speichern " (oder STRG+S) aus, um die Eigenschaftsänderungen zu speichern.
Wenn Sie den Debugger im gemischten Modus an einen vorhandenen Prozess anfügen möchten, wählen Sie "An Prozess anfügen"> aus. Ein Dialogfeld wird geöffnet.
Wählen Sie im Dialogfeld "An Prozess anhängen " den entsprechenden Prozess aus der Liste aus.
Verwenden Sie für das Feld "Anfügen an" die Option " Auswählen ", um das Dialogfeld " Codetyp auswählen " zu öffnen.
Wählen Sie im Dialogfeld " Codetyp auswählen " die Option " Diese Codetypen debuggen " aus.
Aktivieren Sie in der Liste das Kontrollkästchen Python (systemeigene) und dann OK:
Wählen Sie "Anfügen" aus, um den Debugger zu starten.
Die Codetypeinstellungen sind persistent. Wenn Sie das Debuggen im gemischten Modus deaktivieren und später an einen anderen Prozess anfügen möchten, deaktivieren Sie das Kontrollkästchen für den Python-Codetyp (systemeigener Codetyp), und aktivieren Sie das Kontrollkästchen " Nativer Codetyp".
Sie können zusätzlich oder anstelle der Option "Native " andere Codetypen auswählen. Wenn beispielsweise eine verwaltete Anwendung CPython hostt, die wiederum native Erweiterungsmodule verwendet, und Sie alle drei Codeprojekte debuggen möchten, aktivieren Sie die Kontrollkästchen "Python", " Native" und "Verwaltet" . Mit diesem Ansatz erhalten Sie eine einheitliche Debugger-Erfahrung, einschließlich kombinierter Aufrufstapel und Schritt-für-Schritt-Debugging zwischen allen drei Laufzeiten.
Arbeiten mit virtuellen Umgebungen
Wenn Sie diese Methode für das Debuggen im gemischten Modus für virtuelle Umgebungen (venvs) verwenden, verwendet Python für Windows eine python.exe Stubdatei für Venvs, die Visual Studio als Unterprozess findet und lädt.
Für Python 3.8 und höher unterstützt der gemischte Modus das Debuggen mit mehreren Prozessen nicht. Wenn Sie die Debugsitzung starten, wird der Stub-Teilprozess anstelle der Anwendung gedebuggt. Bei Anfügen von Szenarien besteht die Problemumgehung darin, die richtige
python.exeDatei anzufügen. Wenn Sie die Anwendung mit der Fehlersuche (z. B. über die F5-Tastenkombination) starten, können Sie den venv mithilfe des BefehlsC:\Python310-64\python.exe -m venv venv --symlinkserstellen. Fügen Sie im Befehl Ihre bevorzugte Version von Python ein. Standardmäßig können nur Administratoren symlinks unter Windows erstellen.Für Python-Versionen vor 3.8 sollte das Debuggen im gemischten Modus mit venvs wie erwartet funktionieren.
Die Ausführung in einer globalen Umgebung führt nicht zu diesen Problemen für jede Version von Python.
Installieren von Python-Symbolen
Wenn Sie das Debuggen zum ersten Mal im gemischten Modus starten, wird möglicherweise ein Dialogfeld "Python-Symbole erforderlich " angezeigt. Sie müssen die Symbole nur einmal für eine beliebige Python-Umgebung installieren. Symbole werden automatisch eingeschlossen, wenn Sie python-Unterstützung über das Visual Studio-Installationsprogramm (Visual Studio 2017 und höher) installieren. Weitere Informationen finden Sie unter Installieren von Debugsymbolen für Python-Dolmetscher in Visual Studio.
Zugriff auf Python-Quellcode
Sie können den Quellcode für Standard-Python selbst beim Debuggen verfügbar machen.
Laden Sie das für Ihre Version geeignete Python-Quellcodearchiv herunter, und extrahieren Sie den Code in einen Ordner.
Wenn Visual Studio zur Eingabe des Speicherorts des Python-Quellcodes auffordert, zeigen Sie auf die spezifischen Dateien im Extraktionsordner.
Aktivieren des Debuggens im gemischten Modus in einem C/C++-Projekt
Visual Studio 2017, Version 15.5 und höher, unterstützt das Debuggen im gemischten Modus aus einem C/C++-Projekt. Ein Beispiel für diese Verwendung ist, wenn Sie Python in eine andere Anwendung einbetten möchten, wie unter python.org beschrieben.
Die folgenden Schritte beschreiben, wie Sie das Debuggen im gemischten Modus für ein C/C++-Projekt aktivieren:
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das C/C++-Projekt, und wählen Sie "Eigenschaften" aus.
Wählen Sie im Bereich "Eigenschaftenseiten" die Registerkarte "Debuggen>" aus.
Erweitern Sie das Dropdownmenü für den Debugger, um die Option zu starten , und wählen Sie Python/Native Debugging aus.
Hinweis
Wenn die Option "Python/Native Debugging " nicht angezeigt wird, müssen Sie zuerst die nativen Python-Entwicklungstools mithilfe des Visual Studio Installer installieren. Die systemeigene Debugoption ist unter der Python-Entwicklungsarbeitslast verfügbar. Weitere Informationen finden Sie unter Installieren der Python-Unterstützung in Visual Studio.
Klicken Sie zum Speichern der Änderungen auf OK.
Debuggen des Programmstarters
Wenn Sie diese Methode verwenden, können Sie das py.exe Programmstartprogramm nicht debuggen, da es einen untergeordneten python.exe Unterprozess spawnsiert. Der Debugger wird nicht an den Unterprozess angefügt. Für dieses Szenario besteht die Problemumgehung darin, das python.exe Programm direkt mit Argumenten zu starten, wie folgt:
Wechseln Sie im Bereich "Eigenschaftenseiten" für das C/C++-Projekt zur Registerkarte "Debuggen>".
Geben Sie für die Befehlsoption den vollständigen Pfad zur
python.exeProgrammdatei an.Geben Sie die gewünschten Argumente im Feld "Befehlsargumente " an.
Anfügen des Debuggers mit gemischtem Modus
Für Visual Studio 2017, Version 15.4 und früher, ist das direkte Debuggen im gemischten Modus nur beim Starten eines Python-Projekts in Visual Studio aktiviert. Die Unterstützung ist eingeschränkt, da C/C++-Projekte nur den systemeigenen Debugger verwenden.
In diesem Szenario besteht die Problemumgehung darin, den Debugger separat anzufügen:
Starten Sie das C++-Projekt ohne Debugging, indem Sie Debug>ohne Debugging starten auswählen oder die Tastenkombination Strg+F5 verwenden.
Wenn Sie den Debugger im gemischten Modus an einen vorhandenen Prozess anfügen möchten, wählen Sie "An Prozess anfügen"> aus. Ein Dialogfeld wird geöffnet.
Wählen Sie im Dialogfeld "An Prozess anhängen " den entsprechenden Prozess aus der Liste aus.
Verwenden Sie für das Feld "Anfügen an" die Option " Auswählen ", um das Dialogfeld " Codetyp auswählen " zu öffnen.
Wählen Sie im Dialogfeld " Codetyp auswählen " die Option " Diese Codetypen debuggen " aus.
Aktivieren Sie in der Liste das Python-Kontrollkästchen , und wählen Sie "OK" aus.
Wählen Sie "Anfügen" aus, um den Debugger zu starten.
Tipp
Sie können in der C++-Anwendung eine Pause oder Verzögerung hinzufügen, um sicherzustellen, dass der Python-Code, den Sie debuggen möchten, nicht aufgerufen wird, bevor Sie den Debugger anfügen.
Erkunden bestimmter Features im gemischten Modus
Visual Studio bietet mehrere Debugfeatures für den gemischten Modus, um das Debuggen Ihrer Anwendung zu vereinfachen:
- Kombinierter Aufrufstapel
- Schritt zwischen Python und systemeigenem Code
- PyObject-Werteansicht in nativem Code
- Ansicht "Systemeigene Werte" in Python-Code
Verwenden eines kombinierten Aufrufstapels
Das Fenster "Aufrufstapel" zeigt sowohl native als auch Python-Stapelrahmen, mit Übergängen zwischen den beiden, die markiert sind:
- Wenn Übergänge als [Externer Code] angezeigt werden sollen, ohne die Übergangsrichtung anzugeben, verwenden Sie den Bereich ">". Erweitern Sie den Abschnitt "Alle Einstellungen>debuggen>allgemein ", und aktivieren Sie das Kontrollkästchen "Nur mein Code aktivieren ".
- Wenn Übergänge als [Externer Code] angezeigt werden sollen, ohne die Übergangsrichtung anzugeben, verwenden Sie das Dialogfeld ">". Erweitern Sieden Abschnitt>", aktivieren Sie das Kontrollkästchen "Nur mein Code aktivieren", und wählen Sie dann "OK" aus.
- Um einen beliebigen Aufrufframe aktiv zu machen, doppelklicken Sie auf den Frame. Diese Aktion öffnet ggf. auch den entsprechenden Quellcode. Wenn der Quellcode nicht verfügbar ist, wird der Frame weiterhin aktiv gemacht, und lokale Variablen können überprüft werden.
Schritt zwischen Python und systemeigenem Code
Visual Studio stellt die Befehle "Schritt in " (F11) oder " Aussteigen " (Umschalt+F11) bereit, damit der Debugger im gemischten Modus Änderungen zwischen Codetypen ordnungsgemäß verarbeiten kann.
Wenn Python eine In C implementierte Methode eines Typs aufruft, wird ein Aufruf dieser Methode am Anfang der systemeigenen Funktion beendet, die die Methode implementiert.
Dieses Verhalten tritt auf, wenn systemeigener Code eine Python-API-Funktion aufruft, die dazu führt, dass Python-Code aufgerufen wird. Das Aufrufen eines
PyObject_CallObjectfunktionswerts, der ursprünglich in Python definiert wurde, wird am Anfang der Python-Funktion beendet.Der Übergang von Python zu nativen Funktionen wird ebenfalls unterstützt, wenn native Funktionen über ctypes aus Python heraus aufgerufen werden.
Verwenden der PyObject-Werte-Ansicht in native Code
Wenn ein systemeigener Frame (C oder C++) aktiv ist, werden die lokalen Variablen im Fenster " Locals" des Debuggers angezeigt. In nativen Python-Erweiterungsmodulen sind viele dieser Variablen vom Typ PyObject (ein Typedef für _object) oder ein paar andere grundlegende Python-Typen. Beim Debuggen im gemischten Modus stellen diese Werte einen anderen untergeordneten Knoten mit der Bezeichnung [Python-Ansicht] dar.
Erweitern Sie den Knoten, um die Python-Darstellung der Variablen anzuzeigen. Die Ansicht der Variablen ist identisch mit dem, was Sie sehen, wenn eine lokale Variable, die auf dasselbe Objekt verweist, in einem Python-Frame vorhanden ist. Die untergeordneten Elemente dieses Knotens können bearbeitet werden.
Um dieses Feature zu deaktivieren, klicken Sie im Fenster "Locals" mit der rechten Maustaste auf eine beliebige Stelle, und schalten Sie die Menüoption "> anzeigen" ein:
C-Typen, die Python-Ansichtsknoten anzeigen
Die folgenden C-Typen zeigen [Python-Ansicht] Knoten an, wenn diese aktiviert sind:
PyObjectPyVarObjectPyTypeObjectPyByteArrayObjectPyBytesObjectPyTupleObjectPyListObjectPyDictObjectPySetObjectPyIntObjectPyLongObjectPyFloatObjectPyStringObjectPyUnicodeObject
[Python-Ansicht] wird nicht automatisch für Typen angezeigt, die Sie selbst erstellen. Wenn Sie Erweiterungen für Python 3.x erstellen, ist dieser Mangel normalerweise kein Problem. Jedes Objekt hat letztendlich ein ob_base Feld mit einem der aufgelisteten C-Typen, was dazu führt, dass [Python-Ansicht] angezeigt wird.
Anzeigen systemeigener Werte im Python-Code
Sie können eine [C++-Ansicht] für systemeigene Werte im Fenster "Locals " aktivieren, wenn ein Python-Frame aktiv ist. Dieses Feature ist nicht standardmäßig aktiviert.
Um das Feature zu aktivieren, klicken Sie mit der rechten Maustaste in das Fenster "Locals ", und legen Sie die Menüoption "Python>Show C++-Ansichtsknoten" fest.
Der Knoten [C++-Ansicht] stellt eine Darstellung der zugrunde liegenden C/C++-Struktur für einen Wert bereit, identisch mit dem, was Sie in einem systemeigenen Frame sehen. Es zeigt eine Instanz von
_longobject(für diePyLongObjectein Typedef ist) für eine Python-Langzahl, und versucht, Typen für native Klassen abzuleiten, die Sie selbst entwickelt haben. Die Kinder dieses Knotens sind bearbeitbar.
Wenn ein untergeordnetes Feld eines Objekts vom Typ PyObjectoder einem anderen unterstützten Typ ist, verfügt es über einen [Python-Ansicht] -Darstellungsknoten (wenn diese Darstellungen aktiviert sind). Dieses Verhalten ermöglicht das Navigieren in Objektdiagrammen, bei denen Links nicht direkt für Python verfügbar gemacht werden.
Im Gegensatz zu [Python-Ansicht] -Knoten, die Python-Objektmetadaten verwenden, um den Typ des Objekts zu bestimmen, gibt es keinen ähnlich zuverlässigen Mechanismus für [C++-Ansicht]. Im Allgemeinen ist es bei einem Python-Wert (d. h. einem PyObject Verweis) nicht möglich, zuverlässig zu bestimmen, welche C/C++-Struktur sie unterstützt. Der Debugger mit gemischten Modus versucht, den Typ zu erraten, indem er verschiedene Felder des Typs des Objekts (z. B. den Verweis auf das PyTypeObjectob_type Feld) mit Funktionszeigertypen betrachtet. Wenn einer dieser Funktionszeiger auf eine Funktion verweist, die aufgelöst werden kann, und diese Funktion einen Parameter mit einem spezifischeren Typ als PyObject* aufweist, wird dieser Typ als Sicherungstyp angenommen.
Betrachten Sie das folgende Beispiel, in dem der ob_type->tp_init Wert für ein bestimmtes Objekt an der folgenden Funktion liegt:
static int FobObject_init(FobObject* self, PyObject* args, PyObject* kwds) {
return 0;
}
In diesem Fall kann der Debugger korrekt ableiten, dass der C-Typ des Objekts ist FobObject. Wenn der Debugger keinen präziseren Typ aus tp_init bestimmen kann, geht er zu anderen Feldern weiter. Wenn der Typ nicht von einem dieser Felder abgeleitet werden kann, stellt der Knoten [C++-Ansicht] das Objekt als PyObject Instanz dar.
Um immer eine nützliche Darstellung für benutzerdefinierte Typen zu erhalten, empfiehlt es sich, mindestens eine spezielle Funktion bei der Anmeldung des Typs zu registrieren und einen stark typisierten self-Parameter zu verwenden. Die meisten Typen erfüllen diese Anforderung natürlich. Bei anderen Typen ist die Inspektion tp_init in der Regel der bequemste Weg, um dies zu tun. Eine Dummyimplementierung tp_init für einen Typ, der ausschließlich zum Aktivieren der Debuggertyp-Ableitung vorhanden ist, kann wie im vorherigen Beispiel einfach null sofort zurückgeben.
Überprüfen von Unterschieden im standardmäßigen Python-Debugging
Der Debugger mit gemischten Modus unterscheidet sich vom Standardmäßigen Python-Debugger. Es führt einige zusätzliche Features ein, aber es fehlen einige Python-bezogene Funktionen, wie folgt:
- Nicht unterstützte Features umfassen bedingte Haltepunkte, das interaktive Debugfenster und plattformübergreifendes Remotedebugging.
- Das Direktfenster ist verfügbar, jedoch mit einer begrenzten Anzahl seiner Funktionen, einschließlich aller in diesem Abschnitt aufgeführten Einschränkungen.
- Unterstützte Python-Versionen enthalten nur CPython 2.7 und 3.3+.
- Um Python mit Visual Studio Shell zu verwenden (z. B. wenn Sie es mit dem integrierten Installationsprogramm installieren), kann Visual Studio keine C++-Projekte öffnen. Daher ist die Bearbeitungsoberfläche für C++-Dateien nur der eines einfachen Text-Editors. Debugging von C/C++ und Mixed-Mode-Debugging werden in der Shell jedoch vollständig unterstützt. Sie können Quellcode einsehen, in nativen Code hineinsteppen und C++-Ausdrücke in den Debugger-Fenstern auswerten.
- Wenn Sie Python-Objekte in den Locals- und Watch-Debuggerfenstern anzeigen, zeigt der gemischte Modus-Debugger nur die Struktur der Objekte an. Es werden keine Eigenschaften automatisch ausgewertet oder berechnete Attribute angezeigt. Bei Auflistungen werden nur Elemente für integrierte Auflistungstypen (
tuple,list,dict,set) angezeigt. Benutzerdefinierte Sammlungstypen werden nicht als Sammlungen visualisiert, es sei denn, sie werden von einem integrierten Sammlungstyp geerbt. - Die Ausdrucksauswertung wird wie im folgenden Abschnitt beschrieben durchgeführt.
Verwenden Sie die Ausdrucksauswertung
Der Standardmäßige Python-Debugger ermöglicht die Auswertung beliebiger Python-Ausdrücke in den Überwachungs - und Direktfenstern , wenn der debuggierte Prozess an einem beliebigen Punkt im Code angehalten wird, solange er nicht in einem E/A-Vorgang oder einem anderen ähnlichen Systemaufruf blockiert wird. Beim Debuggen im gemischten Modus können beliebige Ausdrücke nur ausgewertet werden, wenn der Code im Python-Skript angehalten wird, entweder nach einem Haltepunkt oder beim Eintreten in den Code. Ausdrücke können nur in dem Thread ausgewertet werden, in dem der Haltepunkt erreicht oder der Schrittvorgang durchgeführt wurde.
Wenn der Debugger in nativem Code oder im Python-Code anhält, bei dem die beschriebenen Bedingungen nicht gelten, z. B. nach einem Step-Out-Vorgang oder in einem anderen Thread. Die Ausdrucksauswertung ist auf den Zugriff auf lokale und globale Variablen im Umfang des aktuell ausgewählten Frames, Zugriff auf ihre Felder und das Indizieren integrierter Sammlungstypen mit Literalen beschränkt. Beispielsweise kann der folgende Ausdruck in jedem Kontext ausgewertet werden (vorausgesetzt, alle Bezeichner beziehen sich auf vorhandene Variablen und Felder geeigneter Typen):
foo.bar[0].baz['key']
Der Debugger mit gemischten Modus löst solche Ausdrücke auch anders auf. Alle Memberzugriffsvorgänge suchen nur nach Feldern, die direkt Teil des Objekts sind (z. B. ein Eintrag in seinem __dict__ oder __slots__ oder ein Feld einer systemeigenen Struktur, die über tp_members Python zur Verfügung gestellt wird) und ignorieren jegliche __getattr__, __getattribute__ oder Deskriptorlogik. Ebenso ignorieren alle Indizierungsvorgänge __getitem__ und greifen direkt auf die inneren Datenstrukturen von Sammlungen zu.
Aus Gründen der Konsistenz wird dieses Namensauflösungsschema für alle Ausdrücke verwendet, die den Einschränkungen für die eingeschränkte Ausdrucksauswertung entsprechen. Dieses Schema wird unabhängig davon angewendet, ob beliebige Ausdrücke am aktuellen Stopppunkt zulässig sind. Um die richtige Python-Semantik zu erzwingen, wenn ein voll funktionsfähiger Evaluator verfügbar ist, schließen Sie den Ausdruck in Klammern ein:
(foo.bar[0].baz['key'])