Langkau ke kandungan

Nyahpepijat ujian yang gagal dengan ejen

Panduan ini menunjukkan cara membuat ejen menggunakan penyahpepijat pada kegagalan yang tidak dapat dijelaskan oleh pernyataan cetak.

Alat debug memandu sesi Debug Adapter Protocol sebenar. Bingkai yang dihentikan menjawab setiap soalan tentang saat itu sekali gus — setiap pembolehubah setempat, setiap pemanggil, dan satu ungkapan yang dinilai dalam skop bingkai itu sendiri — manakala pernyataan cetak hanya menjawab soalan yang anda terfikir untuk tanyakan sebelum menjalankannya.

Alat ini kekal di permukaan supaya ejen boleh bertanya mengapa tiada apa yang boleh digunakan, dan bukannya meneka. Penyesuai hanya boleh bermula apabila kedua-dua perkara berikut dipenuhi:

  • penanda projek dalam checkout, dan
  • binari penyesuai itu dapat diselesaikan.

Minta ejen menyemak:

debug(op: "adapters")

Ia menjawab dengan apa yang dijumpainya, atau menerangkan bahawa penyesuai memerlukan kedua-dua bahagian itu.

Bahasa Penyesuai Penanda Pemasangan
Dart / Flutter dart debug_adapter pubspec.yaml Disertakan dengan SDK — tiada apa-apa perlu dilakukan
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Disertakan dengan LLVM
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Urutan itu penting dan alat ini menguatkuasakannya: titik henti boleh ditetapkan sebelum sesi wujud, kerana itulah urutan yang dikehendaki oleh protokol.

Tanyakan kepada ejen sesuatu seperti:

Fungsi compute dalam bin/main.dart mengembalikan nilai yang salah. Tetapkan titik henti pada baris yang menetapkan product, lancarkannya di bawah penyahpepijat dan beritahu saya apakah sebenarnya a dan b.

Ia akan menjalankan lebih kurang:

debug(op: "breakpoints", file: "bin/main.dart", lines: [7])
debug(op: "launch", program: "bin/main.dart")

Pelancaran melaporkan tempat ia berhenti:

Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.
debug(op: "stack")
→ #1 compute (bin/main.dart:7:3)
#2 main (bin/main.dart:2:18)

Kemudian masuk ke dalamnya:

debug(op: "scopes", frame_id: 1)
→ Locals (reference 12)
debug(op: "variables", reference: 12)
→ a (int) = 6
b (int) = 7
product (int) = 42

Objek yang mempunyai anak melaporkan [expand: reference N] — tetapi hanya apabila benar-benar ada sesuatu di belakangnya, jadi pengembangan yang tidak boleh digunakan oleh ejen tidak pernah ditawarkan.

Untuk apa-apa yang tidak kelihatan sebagai pembolehubah setempat:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Apa yang anda mahu Op
Jalankan ke hentian seterusnya continue
Baris seterusnya, bingkai sama step_over
Masuk ke dalam panggilan step_in
Keluar ke pemanggil step_out
Hentikan program yang sedang berjalan pause

Untuk proses yang tersekat dan bukan proses yang anda mulakan:

debug(op: "attach", port: 5858)
debug(op: "terminate")

Sentiasa tamatkan sesi. Penyesuai nyahpepijat memiliki proses yang dihentikan yang memegang apa sahaja yang dipegang oleh proses itu — satu port, satu kunci, satu sambungan pangkalan data.

Pengembangan variables pada graf objek yang dalam memang tidak terbatas secara semula jadi — satu widget Flutter mencapai keseluruhan pokok elemen. Anak bagi setiap skop dihadkan pada 50, nilai pada 400 aksara dan bingkai tindanan pada 30. Hasil alat yang memenuhi tetingkap konteks ialah alat yang menamatkan larian yang dibantunya.