Sdílet prostřednictvím


Společné ladění Pythonu a C++ v sadě Visual Studio

Většina běžných ladicích programů Pythonu podporuje pouze ladění kódu Pythonu, ale pro vývojáře je běžné používat Python s jazykem C nebo C++. Některé scénáře, které používají smíšený kód, jsou aplikace, které vyžadují vysoký výkon nebo schopnost přímo vyvolat rozhraní API platformy, jsou často kódovány v Pythonu a C nebo C++.

Visual Studio poskytuje integrované souběžné ladění ve smíšeném režimu pro python a nativní kód jazyka C/C++. Podpora je dostupná, když v instalačním programu sady Visual Studio vyberete možnost nativních vývojových nástrojůPythonu pro úlohu Vývoj pro Python:

Snímek obrazovky znázorňující možnost nativních vývojových nástrojů Pythonu vybranou v instalačním programu sady Visual Studio

V tomto článku se dozvíte, jak pracovat s následujícími funkcemi ladění ve smíšeném režimu:

  • Kombinované zásobníky volání
  • Krok mezi Pythonem a nativním kódem
  • Body přerušení v obou typech kódu
  • Zobrazení Pythonových reprezentací objektů v nativních rámcích a naopak
  • Ladění v kontextu projektu Pythonu nebo projektu C++

Snímek obrazovky znázorňující příklad ladění ve smíšeném režimu pro kód Pythonu a C++ v sadě Visual Studio

Požadavky

  • Visual Studio 2017 a novější Ladění ve smíšeném režimu není dostupné v nástrojích Python Tools for Visual Studio 1.x v sadě Visual Studio 2015 a starších verzích.

  • Visual Studio nainstalované s podporou úloh Pythonu Další informace najdete v tématu Instalace podpory Pythonu v sadě Visual Studio.

Povolení ladění ve smíšeném režimu v projektu Pythonu

Následující kroky popisují, jak povolit ladění ve smíšeném režimu v projektu Pythonu:

  1. V Průzkumníku řešení klikněte pravým tlačítkem na projekt Pythonu a vyberte Vlastnosti.

  2. V podokně Vlastnosti vyberte kartu Ladění a pak vyberte možnost Ladění>povolit nativní ladění kódu :

    Snímek obrazovky, který ukazuje, jak nastavit vlastnost Povolit ladění nativního kódu v sadě Visual Studio

    Tato možnost umožňuje smíšený režim pro všechny relace ladění.

    Návod

    Když povolíte ladění nativního kódu, okno výstupu Pythonu se může zavřít hned po dokončení programu bez pozastavení a zobrazení výzvy stisknutím libovolné klávesy . Chcete-li vynutit pozastavení a výzvu po povolení ladění nativního kódu, přidejte -i argument do pole Spustit>argumenty interpretu na kartě Ladění . Tento argument umístí interpret Pythonu do interaktivního režimu po spuštění kódu. Program čeká, až vyberete Ctrl+Z+Enter, abyste zavřeli okno.

  3. Výběrem možnosti Uložit> (nebo Ctrl+S) uložte změny vlastnosti.

  4. Pokud chcete k existujícímu procesu připojit ladicí program ve smíšeném režimu, vyberte ladění>Připojit k procesu. Otevře se dialogové okno.

    1. V dialogovém okně Připojit k procesu vyberte v seznamu příslušný proces.

    2. Pro pole Připojit k pomocí možnosti Vybrat otevřete dialogové okno Vybrat typ kódu .

    3. V dialogovém okně Vybrat typ kódu zvolte možnost Ladit tyto typy kódu .

    4. V seznamu zaškrtněte políčko Python (nativní) a vyberte OK:

      Snímek obrazovky, který ukazuje, jak vybrat typ kódu Pythonu (nativní) pro ladění v sadě Visual Studio

    5. Vyberte Připojit pro spuštění debuggeru.

    Nastavení typu kódu je trvalé. Pokud chcete později zakázat ladění ve smíšeném režimu a připojit se k jinému procesu, zrušte zaškrtnutí políčka Typ kódu Pythonu (nativní) a zaškrtněte políčko Typ nativního kódu.

    Kromě možnosti Native (Nativní ) můžete vybrat i jiné typy kódu. Pokud například spravovaná aplikace hostuje CPython, který zase používá nativní rozšiřující moduly a chcete ladit všechny tři projekty kódu, zaškrtněte políčka Python, Native a Managed . Tento přístup poskytuje jednotné prostředí ladění, včetně kombinovaných zásobníků volání a krokování mezi všemi třemi moduly runtime.

Práce s virtuálními prostředími

Při použití této metody ladění ve smíšeném režimu pro virtuální prostředí (venvs) používá Python pro Windows stub soubor python.exe, který Visual Studio najde a načte jako podproces.

  • Smíšený režim v Pythonu 3.8 a novějším nepodporuje ladění s více procesy. Při spuštění ladicí relace se ladí zástupný podproces místo aplikace. V případě scénářů připojení je alternativním řešením připojit se ke správnému python.exe souboru. Při spuštění aplikace s laděním (například pomocí klávesové zkratky F5 ) můžete vytvořit venv pomocí příkazu C:\Python310-64\python.exe -m venv venv --symlinks. V příkazu vložte upřednostňovanou verzi Pythonu. Ve výchozím nastavení můžou symlinky ve Windows vytvářet jenom správci.

  • U verzí Pythonu starších než 3.8 by ladění smíšeného režimu mělo fungovat podle očekávání s venvs.

Spuštění v globálním prostředí nezpůsobuje tyto problémy u žádné verze Pythonu.

Instalace symbolů Pythonu

Při prvním spuštění ladění ve smíšeném režimu se může zobrazit dialogové okno Povinné symboly Pythonu . Symboly je potřeba nainstalovat jenom jednou pro libovolné prostředí Pythonu. Symboly se automaticky zahrnou, pokud instalujete podporu Pythonu prostřednictvím instalačního programu sady Visual Studio (Visual Studio 2017 a novější). Další informace najdete v tématu Instalace symbolů ladění pro interprety Pythonu v sadě Visual Studio.

Přístup ke zdrojovému kódu Pythonu

Zdrojový kód pro samotný standardní Python můžete zpřístupnit při ladění.

  1. Přejděte na https://www.python.org/downloads/source/ .

  2. Stáhněte si archiv zdrojového kódu Pythonu odpovídající vaší verzi a extrahujte kód do složky.

  3. Když Visual Studio vyzve k zadání umístění zdrojového kódu Pythonu, ukažte na konkrétní soubory v extrahované složce.

Povolení ladění ve smíšeném režimu v projektu C/C++

Visual Studio 2017 verze 15.5 a novější podporuje ladění ve smíšeném režimu z projektu C/C++. Příkladem tohoto použití je, když chcete python vložit do jiné aplikace, jak je popsáno v python.org.

Následující kroky popisují, jak povolit ladění ve smíšeném režimu pro projekt C/C++:

  1. V Průzkumníku řešení klikněte pravým tlačítkem na projekt C/C++ a vyberte Vlastnosti.

  2. V podokně Stránky vlastností vyberte kartu Vlastnosti konfigurace>Ladění.

  3. Rozbalte rozevírací nabídku pro možnost spuštění ladicího programu a vyberte Python/Native Debugging.

    Snímek obrazovky znázorňující výběr možnosti nativního ladění Pythonu pro projekt C/C++ v sadě Visual Studio

    Poznámka:

    Pokud možnost ladění Python/Native nevidíte, musíte nejprve nainstalovat Python Native Development Tools pomocí Instalačního programu Visual Studio. Možnost nativního ladění je k dispozici v rámci vývojové úlohy Pythonu. Další informace najdete v tématu Instalace podpory Pythonu v sadě Visual Studio.

  4. Kliknutím na TLAČÍTKO OK uložte změny.

Ladění spouštěče programů

Při použití této metody nelze ladit py.exe spouštěč programů, protože vytváří podřízený python.exe podproces. Ladicí program se nepřipojí k podprocesu. V tomto scénáři je alternativním řešením spustit python.exe program přímo s argumenty následujícím způsobem:

  1. Na podokně Stránky vlastností projektu C/C++ přejděte na vlastnosti konfigurace>Ladění.

  2. Pro možnost Příkaz zadejte úplnou cestu k python.exe souboru programu.

  3. Do pole Argumenty příkazu zadejte požadované argumenty .

Připojte ladicí program v režimu smíšeného módu

Pro verzi Visual Studio 2017 15.4 a starší je přímé ladění v režimu smíšeného módu povoleno pouze při spuštění Python projektu ve Visual Studio. Podpora je omezená, protože projekty C/C++ používají pouze nativní ladicí program.

V tomto scénáři je řešením připojit ladicí program samostatně:

  1. Spusťte projekt C++ bez ladění>, že vybereteSpustit bez ladění nebo použijete klávesovou zkratku Ctrl+F5.

  2. Pro připojení ladicího programu ve smíšeném režimu k existujícímu procesu vyberte Ladění>Připojit k procesu. Otevře se dialogové okno.

    1. V dialogovém okně Připojit k procesu vyberte v seznamu příslušný proces.

    2. Pro pole Připojit k pomocí možnosti Vybrat otevřete dialogové okno Vybrat typ kódu .

    3. V dialogovém okně Vybrat typ kódu zvolte možnost Ladit tyto typy kódu .

    4. V seznamu zaškrtněte políčko Python a vyberte OK.

    5. Vyberte Připojit pro spuštění ladicího programu.

Návod

Do aplikace C++ můžete přidat pozastavení nebo zpoždění, abyste se ujistili, že před připojením ladicího programu nevolá kód Pythonu, který chcete ladit.

Prozkoumání funkcí specifických pro smíšený režim

Visual Studio nabízí několik funkcí ladění ve smíšeném režimu, které usnadňují ladění aplikace:

Použijte kombinovaný zásobník volání

V okně Zásobník volání se zobrazují nativní a Python rámce zásobníku, prokládané s vyznačenými přechody mezi nimi.

Snímek obrazovky okna kombinovaného zásobníku volání s laděním ve smíšeném režimu v sadě Visual Studio

  • Pokud chcete, aby se přechody zobrazovaly jako [externí kód] bez zadání směru přechodu, použijte podokno Možnosti nástrojů>. Rozbalte část Všechna nastavení>Ladění>Obecné , zaškrtněte políčko Povolit pouze můj kód .
  • Pokud chcete, aby se přechody zobrazovaly jako [Externí kód] bez zadání směru přechodu, použijte dialogové okno Možnosti nástrojů>. Rozbalte Ladění>Obecné, zaškrtněte políčko Povolit pouze můj kód a poté vyberte OK.
  • Pokud chcete aktivovat libovolný rámec volání, poklikejte na rámec. Tato akce také otevře odpovídající zdrojový kód, pokud je to možné. Pokud zdrojový kód není dostupný, je rámec stále aktivní a je možné zkontrolovat místní proměnné.

Krok mezi Pythonem a nativním kódem

Visual Studio poskytuje příkazy Step Into (F11) nebo Step Out (Shift+F11), které umožňují ladicím programu smíšeného režimu správně zpracovávat změny mezi typy kódu.

  • Když Python volá metodu typu implementovaného v jazyce C, krokování volání této metody se zastaví na začátku nativní funkce, která implementuje metodu.

  • K tomuto chování dochází, když nativní kód volá funkci rozhraní PYTHON API, která má za následek vyvolání kódu Pythonu. Krokování volání PyObject_CallObject hodnoty funkce původně definované v Pythonu se zastaví na začátku funkce Pythonu.

  • Přechod z Pythonu na nativní je také podporován pro nativní funkce vyvolané z Pythonu prostřednictvím ctypes.

Použití zobrazení hodnot PyObject v nativním kódu

Pokud je aktivní nativní rámec (C nebo C++), místní proměnné se zobrazí v okně Locals ladicího programu. V nativních rozšiřujících modulech Pythonu je mnoho z těchto proměnných typu PyObject (což je typedef pro _object) nebo několik dalších základních typů Pythonu. Při ladění ve smíšeném režimu se tyto hodnoty zobrazují jako další podřízený uzel označený jako [zobrazení Pythonu].

  • Pokud chcete zobrazit reprezentaci Pythonu proměnné, rozbalte uzel. Zobrazení proměnných je stejné jako v případě, že se v rámci Pythonu nachází místní proměnná odkazující na stejný objekt. Podřízené položky tohoto uzlu se dají upravovat.

    Snímek obrazovky znázorňující zobrazení Pythonu v okně Místní hodnoty v sadě Visual Studio

  • Pokud chcete tuto funkci zakázat, klikněte pravým tlačítkem na libovolné místo v okně Místní okno a přepněte možnost nabídky Python>Zobrazit uzly zobrazení Pythonu:

    Snímek obrazovky, který ukazuje, jak povolit možnost Zobrazit uzly zobrazení Pythonu pro okno Místní hodnoty

Typy jazyka C, které zobrazují uzly zobrazení Pythonu

Následující typy jazyka C zobrazují uzly [zobrazení Pythonu], pokud jsou povolené:

  • PyObject
  • PyVarObject
  • PyTypeObject
  • PyByteArrayObject
  • PyBytesObject
  • PyTupleObject
  • PyListObject
  • PyDictObject
  • PySetObject
  • PyIntObject
  • PyLongObject
  • PyFloatObject
  • PyStringObject
  • PyUnicodeObject

[Zobrazení Pythonu] se automaticky nezobrazuje pro typy, které sami vytvoříte. Když vytvoříte rozšíření pro Python 3.x, obvykle to není problém. Jakýkoli objekt má nakonec pole jednoho z uvedených typů jazyka C, což způsobuje, že se zobrazí [zobrazení Pythonu].

Zobrazení nativních hodnot v kódu Pythonu

Pokud je aktivní rámeček Pythonu, můžete povolit zobrazení [C++] pro nativní hodnoty v okně Místní hodnoty. Tato funkce není ve výchozím nastavení povolená.

  • Pokud chcete tuto funkci povolit, klikněte pravým tlačítkem v okně Místní hodnoty a nastavte položku nabídky Python>Zobrazit uzly zobrazení C++.

    Snímek obrazovky, který ukazuje, jak povolit možnosti Zobrazit uzly C++ pro okno Místní

  • Uzel [zobrazení C++] poskytuje reprezentaci základní struktury C/C++ pro hodnotu, která je identická s tím, co vidíte v nativním rámci. Zobrazuje instanci _longobject (pro kterou PyLongObject je typedef) pro dlouhé celé číslo Pythonu a snaží se odvodit typy pro nativní třídy, které sami vytvoříte. Podřízené položky tohoto uzlu se dají upravovat.

    Snímek obrazovky znázorňující zobrazení C++ v okně Místní hodnoty v sadě Visual Studio

Pokud je podřízené pole objektu typu PyObjectnebo jiného podporovaného typu, má uzel reprezentace [zobrazení Pythonu] (pokud jsou tyto reprezentace povolené). Díky tomuto chování můžete procházet grafy objektů, ve kterých nejsou odkazy přímo vystavené Pythonu.

Na rozdíl od uzlů [zobrazení Pythonu] využívajících metadata objektu Pythonu k určení typu objektu neexistuje podobný mechanismus pro [zobrazení C++]. Obecně řečeno, vzhledem k hodnotě Pythonu (tj PyObject . odkazu) není možné spolehlivě určit, která struktura C/C++ ji podporuje. Debugger pro smíšené režimy se pokouší odhadnout typ tím, že se podívá na různá pole typu objektu (například PyTypeObject odkazovaná jeho ob_type polem), která mají typy ukazatelů funkcí. Pokud některý z těchto ukazatelů funkce odkazuje na funkci, která se dá přeložit, a tato funkce má self parametr s typem konkrétnějším než PyObject*, předpokládá se, že se jedná o záložní typ.

Podívejte se na následující příklad, kde ob_type->tp_init hodnota daného objektu odkazuje na následující funkci:

static int FobObject_init(FobObject* self, PyObject* args, PyObject* kwds) {
    return 0;
}

V tomto případě ladicí program může správně odvodit, že typ jazyka C objektu je FobObject. Pokud ladicí program nedokáže určit přesnější typ z tp_init, přesune se do jiných polí. Pokud nelze odvodit typ z některého z těchto polí, uzel [zobrazení C++] zobrazí objekt jako PyObject instanci.

Pokud chcete vždy získat užitečnou reprezentaci pro vlastní vytvořené typy, je nejlepší při registraci typu zaregistrovat aspoň jednu speciální funkci a použít parametr silného typu self . Většina typů tento požadavek splňuje přirozeně. Pro jiné typy je tp_init kontrola obvykle nejpohodlnější vstup pro tento účel. Fiktivní implementace tp_init pro typ, který je k dispozici pouze pro povolení odvození typu ladicího programu, může okamžitě vrátit nulu, jako v uvedeném příkladu.

Přezkoumání odchylek od standardního ladění Pythonu

Ladicí program smíšeného režimu se liší od standardního ladicího programu Pythonu. Představuje některé další funkce, ale chybí některé funkce související s Pythonem, a to následujícím způsobem:

  • Mezi nepodporované funkce patří podmíněné zarážky, okno Debug Interactive a vzdálené ladění napříč platformami.
  • Okno Okamžité je k dispozici, ale s omezenou podmnožinou jeho funkcí, včetně všech omezení uvedených v této části.
  • Podporované verze Pythonu zahrnují pouze CPython 2.7 a 3.3+.
  • Pokud chcete použít Python se sadou Visual Studio Shell (například pokud ho nainstalujete pomocí integrovaného instalačního programu), Visual Studio nemůže otevřít projekty C++. V důsledku toho je prostředí pro úpravy pro soubory C++ pouze v základním textovém editoru. Ladění C/C++ a ladění ve smíšeném režimu jsou však plně podporovány v Shellu s prací se zdrojovým kódem, vstupem do nativního kódu a vyhodnocováním C++ výrazů v oknech ladicího programu.
  • Při zobrazení objektů Pythonu v oknech nástrojů Locals a Watch debugger zobrazí ladicí program smíšeného režimu pouze strukturu objektů. Nevyhodnocuje automaticky vlastnosti ani nezobrazuje vypočítané atributy. U kolekcí zobrazuje pouze prvky pro předdefinované typy kolekcí (tuple, list, dict, set). Vlastní typy kolekcí nejsou vizualizovány jako kolekce, pokud nejsou zděděny z některého předdefinovaného typu kolekce.
  • Vyhodnocení výrazu probíhá tak, jak je popsáno v následující části.

Použijte vyhodnocení výrazu

Standardní debugger Pythonu umožňuje vyhodnocení libovolných výrazů Pythonu v oknech Sledování a Okamžité vyhodnocení, pokud je laděný proces pozastavený v libovolném bodě kódu, pokud není blokován vstupně-výstupní operací nebo jiným podobným systémovým voláním. V ladění ve smíšeném režimu lze libovolné výrazy vyhodnotit pouze v případě, že se zastaví v kódu Pythonu, po zarážce nebo při přechodu do kódu. Výrazy lze vyhodnotit pouze ve vlákně, kde došlo k bodu přerušení nebo operaci krokování.

Když se ladicí program zastaví v nativním kódu nebo v kódu Pythonu, kde se popsané podmínky nepoužijí, například po operaci krokování nebo v jiném vlákně). Vyhodnocení výrazů je omezené na přístup k místním a globálním proměnným v rámci aktuálně vybraného rámce, k přístupu k jejich polím a k indexování vestavěných typů kolekcí pomocí literálů. Například následující výraz lze vyhodnotit v libovolném kontextu (za předpokladu, že všechny identifikátory odkazují na existující proměnné a pole odpovídajících typů):

foo.bar[0].baz['key']

Ladicí program ve smíšeném režimu také tyto výrazy řeší odlišně. Všechny operace přístupu členů vyhledávají pouze pole, která jsou přímo součástí objektu (například položka v jeho __dict__ objektu nebo __slots__nebo pole nativní struktury vystavené Pythonu prostřednictvímtp_members) a ignorují libovolnou __getattr____getattribute__logiku , nebo popisovače. Podobně všechny operace indexování ignorují __getitem__a přistupují přímo k vnitřním datovým strukturám kolekcí.

V zájmu konzistence se toto schéma rozpoznávání názvů používá pro všechny výrazy, které splňují omezení pro vyhodnocení omezených výrazů. Toto schéma se použije bez ohledu na to, zda jsou v aktuálním bodu zastavení povoleny libovolné výrazy. Pokud chcete vynutit správnou sémantiku Pythonu, pokud je k dispozici plnohodnotný vyhodnocovací modul, uzavřete výraz do závorek:

(foo.bar[0].baz['key'])