Bagikan melalui


Debug Python dan C++ bersama-sama di Visual Studio

Sebagian besar debugger Python reguler hanya mendukung debugging kode Python, tetapi praktik umum bagi pengembang untuk menggunakan Python dengan C atau C++. Beberapa skenario yang menggunakan kode campuran adalah aplikasi yang memerlukan performa tinggi atau kemampuan untuk langsung memanggil API platform sering dikodekan dalam Python dan C atau C++.

Visual Studio menyediakan debugging mode campuran terintegrasi dan simultan untuk kode Python dan C/C++ asli. Dukungan tersedia saat Anda memilih opsi alat pengembangan asli Python untuk beban kerja Pengembangan Python di alat penginstal Visual Studio:

Cuplikan layar yang memperlihatkan opsi alat pengembangan asli Python yang dipilih di Penginstal Visual Studio.

Dalam artikel ini, Anda mengeksplorasi cara bekerja dengan fitur debugging mode campuran berikut:

  • Tumpukan panggilan gabungan
  • Langkah antara Python dan kode asli
  • Titik henti dalam kedua jenis kode
  • Lihat representasi Python objek dalam bingkai asli dan sebaliknya
  • Debugging dalam konteks proyek Python atau proyek C++

Cuplikan layar yang memperlihatkan contoh debugging mode campuran untuk kode Python dan C++ di Visual Studio.

Prasyarat

  • Visual Studio 2017 dan yang lebih baru. Debug mode campuran tidak tersedia dengan Python Tools 1.x untuk Visual Studio di Visual Studio 2015 dan versi sebelumnya.

  • Visual Studio diinstal dengan dukungan untuk beban kerja Python. Untuk informasi selengkapnya, lihat Menginstal dukungan Python di Visual Studio.

Mengaktifkan penelusuran kesalahan mode campuran dalam proyek Python

Langkah-langkah berikut menjelaskan cara mengaktifkan debugging mode campuran dalam proyek Python:

  1. Di Penjelajah Solusi, klik kanan proyek Python, dan pilih Properti.

  2. Di panel Properti , pilih tab Debug , lalu pilih opsi Debug>Aktifkan penelusuran kesalahan kode asli :

    Cuplikan layar yang memperlihatkan cara mengatur properti Aktifkan debugging kode asli di Visual Studio.

    Opsi ini memungkinkan mode campuran debugging untuk semua sesi debugging.

    Petunjuk / Saran

    Saat Anda mengaktifkan debugging kode asli, jendela output Python mungkin langsung tertutup setelah program selesai tanpa memberi jeda dan menampilkan Tekan sembarang tombol untuk melanjutkan. Untuk memaksa jeda dan perintah setelah Anda mengaktifkan penelusuran kesalahan kode asli, tambahkan -i argumen ke bidang Jalankan>Argumen Penerjemah pada tab Debug . Argumen ini menempatkan penerjemah Python ke dalam mode interaktif setelah kode berjalan. Program menunggu Anda memilih Ctrl+Z+Enter untuk menutup jendela.

  3. PilihSimpan> (atau Ctrl+S) untuk menyimpan perubahan properti.

  4. Untuk melampirkan debugger mode campuran ke proses yang ada, pilih Lampirkan Debug>ke Proses. Dialog terbuka.

    1. Dalam dialog Lampirkan ke Proses , pilih proses yang sesuai dari daftar.

    2. Untuk bidang Lampirkan ke , gunakan opsi Pilih untuk membuka dialog Pilih Jenis Kode .

    3. Dalam dialog Pilih Jenis Kode , pilih opsi Debug jenis kode ini .

    4. Dalam daftar, pilih kotak centang Python (asli), dan pilih OK:

      Cuplikan layar yang memperlihatkan cara memilih jenis kode Python (asli) untuk penelusuran kesalahan di Visual Studio.

    5. Pilih Lampirkan untuk memulai debugger.

    Pengaturan jenis kode persisten. Jika Anda ingin menonaktifkan debug mode campuran dan menghubungkan ke proses lain nanti, kosongkan kotak centang jenis kode Python (native) dan pilih kotak centang jenis kode asli.

    Anda dapat memilih jenis kode lain selain atau bukan opsi Asli . Misalnya, jika aplikasi terkelola menghosting CPython, yang pada gilirannya menggunakan modul ekstensi asli, dan Anda ingin men-debug ketiga proyek kode, pilih kotak centang Python, Native, dan Managed . Pendekatan ini memberi Anda pengalaman debugging terpadu termasuk tumpukan pemanggilan gabungan dan melewati ketiga runtime.

Bekerja dengan lingkungan virtual

Saat Anda menggunakan metode debugging mode campuran ini untuk lingkungan virtual (venvs), Python untuk Windows menggunakan file stub python.exe untuk venv yang ditemukan dan dimuat oleh Visual Studio sebagai subproses.

  • Untuk Python 3.8 dan yang lebih baru, mode campuran tidak mendukung debugging multi-proses. Saat Anda memulai sesi debugging, subproses stub di-debug daripada aplikasi. Untuk skenario lampirkan, solusinya adalah melampirkan ke file yang benar python.exe . Saat Anda meluncurkan aplikasi dengan penelusuran kesalahan (seperti melalui pintasan keyboard F5 ), Anda dapat membuat venv Anda dengan menggunakan perintah C:\Python310-64\python.exe -m venv venv --symlinks. Dalam perintah , sisipkan versi Python pilihan Anda. Secara default, hanya administrator yang dapat membuat symlink di Windows.

  • Untuk versi Python yang lebih lama dari 3.8, penelusuran kesalahan mode campuran harus berfungsi seperti yang diharapkan dengan venv.

Berjalan di lingkungan global tidak menyebabkan masalah ini untuk versi Python apa pun.

Memasang simbol Python

Saat Anda mulai men-debug dalam mode campuran untuk pertama kalinya, Anda mungkin melihat dialog Diperlukan Simbol Python . Anda perlu menginstal simbol hanya sekali untuk lingkungan Python tertentu. Simbol secara otomatis disertakan jika Anda menginstal dukungan Python melalui Penginstal Visual Studio (Visual Studio 2017 dan yang lebih baru). Untuk informasi selengkapnya, lihat Memasang simbol penelusuran kesalahan untuk penerjemah Python di Visual Studio.

Kode sumber Access Python

Anda dapat membuat kode sumber Python standar tersedia sendiri saat debugging.

  1. Pergi ke https://www.python.org/downloads/source/.

  2. Unduh arsip kode sumber Python yang sesuai untuk versi Anda, dan ekstrak kode ke folder.

  3. Saat Visual Studio meminta lokasi kode sumber Python, arahkan ke file tertentu di folder ekstraksi.

Mengaktifkan debugging mode campuran dalam proyek C/C++

Visual Studio 2017 versi 15.5 dan yang lebih baru mendukung debugging mode campuran dari proyek C/C++. Contoh penggunaan ini adalah ketika Anda ingin menyematkan Python di aplikasi lain seperti yang dijelaskan pada python.org.

Langkah-langkah berikut menjelaskan cara menghidupkan debugging mode campuran untuk proyek C/C++.

  1. Di Penjelajah Solusi, klik kanan proyek C/C++, dan pilih Properti.

  2. Di panel Halaman Properti, pilih tab Properti Konfigurasi>Penelusuran Kesalahan.

  3. Perluas menu dropdown untuk opsi Debugger untuk meluncurkan dan pilih Python/Native Debugging.

    Cuplikan layar yang memperlihatkan cara memilih opsi Debugging Asli Python untuk proyek C/C++ di Visual Studio.

    Nota

    Jika Anda tidak melihat opsi Debugging Python/Native , Anda harus terlebih dahulu menginstal alat pengembangan asli Python dengan menggunakan Alat Penginstal Visual Studio. Opsi debugging asli tersedia di bawah lingkungan pengembangan Python. Untuk informasi selengkapnya, lihat Menginstal dukungan Python di Visual Studio.

  4. Pilih OK untuk menyimpan perubahan.

Debug peluncur aplikasi

Ketika Anda menggunakan metode ini, Anda tidak dapat men-debug py.exe peluncur program karena memunculkan anak subproses python.exe. Debugger tidak terhubung ke subproses. Untuk skenario ini, solusinya adalah meluncurkan python.exe program secara langsung dengan argumen, sebagai berikut:

  1. Pada panel Halaman Properti untuk proyek C/C++, buka tab Konfigurasi Properti>Debugging.

  2. Untuk opsi Perintah , tentukan jalur lengkap ke python.exe file program.

  3. Tentukan argumen yang Anda inginkan di bidang Argumen Perintah .

Melampirkan debugger mode campuran

Untuk Visual Studio 2017 versi 15.4 dan yang lebih lama, debugging mode campuran langsung diaktifkan hanya saat meluncurkan proyek Python di Visual Studio. Dukungan terbatas karena proyek C/C++ hanya menggunakan debugger asli.

Untuk skenario ini, solusinya adalah melampirkan debugger secara terpisah:

  1. Mulai proyek C++ tanpa penelusuran kesalahan dengan memilih Debug>Mulai tanpa Penelusuran Kesalahan atau gunakan pintasan keyboard Ctrl+F5.

  2. Untuk melampirkan debugger mode campuran ke proses yang ada, pilih Lampirkan Debug>ke Proses. Dialog terbuka.

    1. Dalam dialog Lampirkan ke Proses , pilih proses yang sesuai dari daftar.

    2. Untuk bidang Lampirkan ke , gunakan opsi Pilih untuk membuka dialog Pilih Jenis Kode .

    3. Dalam dialog Pilih Jenis Kode , pilih opsi Debug jenis kode ini .

    4. Dalam daftar, pilih kotak centang Python , dan pilih OK.

    5. Pilih Lampirkan untuk memulai debugger.

Petunjuk / Saran

Anda dapat menambahkan jeda atau penundaan dalam aplikasi C++ untuk memastikannya tidak memanggil kode Python yang ingin Anda debug sebelum melampirkan debugger.

Menjelajahi fitur khusus mode campuran

Visual Studio menyediakan beberapa fitur debugging mode campuran untuk mempermudah debug aplikasi Anda:

Menggunakan tumpukan panggilan gabungan

Jendela Call Stack menunjukkan bingkai tumpukan asli dan Python yang saling terkait, dengan transisi yang ditandai di antara keduanya:

Cuplikan layar jendela jalinan panggilan gabungan dengan debugging mode campuran di Visual Studio.

  • Untuk membuat transisi muncul sebagai [Kode Eksternal] tanpa menentukan arah transisi, gunakan panelOpsi>. Perluas bagianUmum>>, pilih kotak centang Aktifkan Hanya Kode Saya.
  • Untuk membuat transisi muncul sebagai [Kode Eksternal] tanpa menentukan arah transisi, gunakan dialogOpsi>. Perluas bagianUmum>, pilih kotak centang Aktifkan Hanya Kode Saya, lalu pilih OK.
  • Untuk menjadikan kerangka panggilan aktif, klik ganda pada kerangka tersebut. Tindakan ini juga membuka kode sumber yang sesuai, jika memungkinkan. Jika kode sumber tidak tersedia, bingkai masih dibuat aktif dan variabel lokal dapat diperiksa.

Langkah antara Python dan kode asli

Visual Studio menyediakan perintah Step Into (F11) atau Step Out (Shift+F11) untuk mengaktifkan debugger mode campuran untuk menangani perubahan antara jenis kode dengan benar.

  • Ketika Python memanggil metode dari jenis yang diimplementasikan dalam bahasa C, masuk ke dalam panggilan ke metode tersebut akan berhenti di awal fungsi asli yang mengimplementasikannya.

  • Perilaku yang sama ini terjadi ketika kode asli memanggil fungsi API Python yang mengakibatkan kode Python dipanggil. Melangkah ke panggilan ke PyObject_CallObject pada nilai fungsi yang awalnya ditentukan dalam Python berhenti di awal fungsi Python.

  • Masuk dari Python ke fungsi bawaan juga didukung untuk fungsi bawaan yang dipanggil dari Python melalui ctypes.

Menggunakan tampilan nilai PyObject dalam kode asli

Ketika bingkai asli (C atau C++) aktif, variabel lokalnya muncul di jendela Lokal debugger. Dalam modul ekstensi Python asli, banyak dari variabel ini berjenis PyObject (yang merupakan typedef untuk _object), atau beberapa jenis Python mendasar lainnya. Dalam debugging mode campuran, nilai-nilai ini memperlihatkan simpul anak lain berlabel [Python view].

  • Untuk melihat representasi Python variabel, perluas simpul. Tampilan variabel identik dengan apa yang Anda lihat jika variabel lokal yang mereferensikan objek yang sama ada dalam bingkai Python. Anak-anak simpul ini dapat diedit.

    Cuplikan layar yang memperlihatkan Tampilan Python di jendela Lokal di Visual Studio.

  • Untuk menonaktifkan fitur ini, klik kanan di mana saja di jendela Lokal dan alihkan opsi menu Python>Show Python View Nodes :

    Cuplikan layar yang memperlihatkan cara mengaktifkan opsi Tampilkan Simpul Tampilan Python untuk jendela Lokal.

Jenis C yang memperlihatkan simpul tampilan Python

Jenis C berikut menunjukkan node [tampilan Python] , jika diaktifkan:

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

[Tampilan Python] tidak secara otomatis muncul untuk jenis yang Anda tulis sendiri. Saat Anda menulis ekstensi untuk Python 3.x, kekurangan ini biasanya bukan masalah. Objek apa pun pada akhirnya memiliki ob_base bidang dari salah satu jenis C yang tercantum, yang menyebabkan [tampilan Python] muncul.

Menampilkan nilai asli dalam kode Python

Anda dapat mengaktifkan [tampilan C++] untuk nilai asli di jendela Lokal saat bingkai Python aktif. Fitur ini tidak diaktifkan secara default.

  • Untuk mengaktifkan fitur, klik kanan di jendela Lokal dan atur opsi menu Python>Show C++ View Nodes .

    Cuplikan layar yang memperlihatkan cara mengaktifkan opsi Tampilkan Simpul Tampilan C++ untuk jendela Lokal.

  • Simpul [tampilan C++] menyediakan representasi struktur C/C++ yang mendasar untuk nilai, identik dengan apa yang Anda lihat dalam bingkai asli. Ini menunjukkan instans _longobject (yang PyLongObject merupakan typedef) untuk bilangan bulat panjang Python, dan mencoba menyimpulkan jenis untuk kelas asli yang Anda buat sendiri. Anak-anak simpul ini dapat diedit.

    Cuplikan layar yang memperlihatkan Tampilan C++ di jendela Lokal di Visual Studio.

Jika bidang anak dari objek berjenis PyObject, atau jenis lain yang didukung, maka memiliki node representasi [tampilan Python] (jika representasi tersebut diaktifkan). Perilaku ini memungkinkan untuk menavigasi grafik objek di mana tautan tidak secara langsung terekspos ke Python.

Tidak seperti simpul [tampilan Python] , yang menggunakan metadata objek Python untuk menentukan jenis objek, tidak ada mekanisme yang sama dapat diandalkan untuk [tampilan C++]. Secara umum, mengingat nilai Python (yaitu, PyObject referensi) tidak mungkin untuk secara andal menentukan struktur C/C++ mana yang mendukungnya. Debugger mode campuran mencoba menebak jenis dengan melihat berbagai bidang jenis objek (seperti yang PyTypeObject direferensikan oleh bidangnya ob_type ) yang memiliki jenis penunjuk fungsi. Jika salah satu penunjuk fungsi tersebut mereferensikan fungsi yang dapat diselesaikan, dan fungsi tersebut memiliki self parameter dengan jenis yang lebih spesifik daripada PyObject*, maka jenis tersebut diasumsikan sebagai jenis pendukung.

Pertimbangkan contoh berikut, di mana nilai ob_type->tp_init dari suatu objek tertentu menunjuk pada fungsi berikut:

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

Dalam hal ini, debugger dapat menyimpulkan dengan benar bahwa jenis C objek adalah FobObject. Jika debugger tidak dapat menentukan jenis yang lebih tepat dari tp_init, debugger berpindah ke bidang lain. Jika tidak dapat menyimpulkan jenis dari salah satu bidang tersebut, simpul [tampilan C++] menyajikan objek sebagai PyObject instans.

Untuk selalu mendapatkan representasi yang berguna untuk tipe yang disusun khusus, sebaiknya mendaftarkan setidaknya satu fungsi khusus saat mendaftarkan tipe, dan menggunakan parameter bertipe kuat self. Sebagian besar jenis memenuhi persyaratan tersebut secara alami. Untuk jenis lain, inspeksi tp_init biasanya merupakan entri yang paling nyaman digunakan untuk tujuan ini. Implementasi tiruan dari tp_init untuk tipe yang hanya ada untuk mengaktifkan inferensi tipe oleh debugger dapat mengembalikan nol segera, seperti pada contoh sebelumnya.

Meninjau Perbedaan dari Debugging Python Standar

Debugger mode campuran berbeda dengan debugger Python standar. Ini memperkenalkan beberapa fitur tambahan tetapi tidak memiliki beberapa kemampuan terkait Python, sebagai berikut:

  • Fitur yang tidak didukung termasuk titik henti kondisional, jendela Debug Interaktif , dan penelusuran kesalahan jarak jauh lintas platform.
  • Jendela Langsung tersedia tetapi dengan subset terbatas dari fungsionalitasnya, termasuk semua batasan yang tercantum di bagian ini.
  • Versi Python yang didukung hanya menyertakan CPython 2.7 dan 3.3+.
  • Untuk menggunakan Python dengan Visual Studio Shell (misalnya, jika Anda menginstalnya dengan alat penginstal terintegrasi), Visual Studio tidak dapat membuka proyek C++. Akibatnya, pengalaman pengeditan untuk file C++ hanya dari editor teks dasar. Namun, debugging C/C++ dan debugging mode campuran sepenuhnya didukung di Shell dengan kode sumber, memasuki kode native, dan evaluasi ekspresi C++ di jendela debugger.
  • Saat Anda melihat objek Python di jendela alat debugger Lokal dan Watch , debugger mode campuran hanya menampilkan struktur objek. Ini tidak secara otomatis mengevaluasi properti atau menampilkan atribut komputasi. Untuk koleksi, hanya menampilkan elemen untuk jenis koleksi bawaan (tuple, , list, dictset). Jenis koleksi kustom tidak divisualisasikan sebagai koleksi, kecuali jika diwarisi dari beberapa jenis koleksi bawaan.
  • Evaluasi ekspresi ditangani seperti yang dijelaskan di bagian berikut.

Gunakan evaluasi ekspresi

Debugger Python standar memungkinkan evaluasi ekspresi Python arbitrer di jendela Watch dan Immediate ketika proses debugged dijeda pada titik mana pun dalam kode, selama tidak diblokir dalam operasi I/O atau panggilan sistem serupa lainnya. Dalam debugging mode campuran, ekspresi sebarang hanya dapat dievaluasi ketika berhenti di dalam kode Python, setelah mencapai titik henti, atau saat melangkah ke dalam kode. Ekspresi hanya dapat dievaluasi pada utas tempat titik henti atau operasi melangkah terjadi.

Saat debugger berhenti dalam kode asli, atau dalam kode Python di mana kondisi yang dijelaskan tidak berlaku, seperti setelah operasi step-out, atau pada utas yang berbeda). Evaluasi ekspresi terbatas pada mengakses variabel lokal dan global dalam cakupan bingkai yang saat ini dipilih, mengakses bidangnya, dan mengindeks jenis koleksi bawaan dengan literal. Misalnya, ekspresi berikut dapat dievaluasi dalam konteks apa pun (asalkan semua pengidentifikasi merujuk ke variabel dan bidang yang ada dengan jenis yang sesuai):

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

Debugger mode campuran juga menangani ekspresi-ekspresi tersebut dengan cara berbeda. Semua operasi akses anggota hanya mencari bidang yang merupakan bagian langsung dari objek (seperti entri di __dict__ atau __slots__, atau bidang dari struktur asli yang diekspos ke Python melalui tp_members), dan mengabaikan __getattr__, __getattribute__, atau logika deskriptor apa pun. Demikian pula, semua operasi pengindeksan mengabaikan __getitem__, dan mengakses struktur data dalam koleksi secara langsung.

Demi konsistensi, skema resolusi nama ini digunakan untuk semua ekspresi yang cocok dengan batasan untuk evaluasi ekspresi terbatas. Skema ini diterapkan terlepas dari apakah ekspresi arbitrer diizinkan pada titik berhenti saat ini. Untuk memaksa semantik Python yang tepat ketika evaluator dengan fitur lengkap tersedia, sertakan ekspresi dalam tanda kurung:

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