Tovább a tartalomhoz

Sikertelen teszt hibakeresése ügynökkel

Ez az útmutató megmutatja, hogyan vegye rá az ügynököt, hogy hibakeresőt használjon egy olyan hiba esetén, amelyet a print utasítások nem magyaráznak meg.

A debug eszköz valódi Debug Adapter Protocol-munkamenetet vezet. Egy megállított keret egyszerre válaszol meg minden kérdést arról a pillanatról — minden lokális változót, minden hívót, és egy kifejezést a keret saját hatókörében kiértékelve —, míg egy print utasítás csak arra a kérdésre válaszol, amelyet futtatás előtt gondolt feltenni.

Az eszköz a felszínen marad, hogy az ügynök megkérdezhesse, miért nem használható semmi, ahelyett hogy találgatna. Egy adapter valójában csak akkor tud elindulni, ha mindkettő teljesül az alábbiak közül:

  • van egy projektjelölő a checkoutban, és
  • feloldható az adapter binárisa.

Kérje meg az ügynököt, hogy ellenőrizze:

debug(op: "adapters")

Azt válaszolja, amit talált, vagy elmagyarázza, hogy egy adapterhez mindkét félre szükség van.

Nyelv Adapter Jelölő Telepítés
Dart / Flutter dart debug_adapter pubspec.yaml Az SDK-val érkezik — nincs teendő
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Az LLVM-mel érkezik
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Először állítsa be a töréspontot, majd indítson

Szekció neve “Először állítsa be a töréspontot, majd indítson”

A sorrend számít, és az eszköz kikényszeríti: a töréspontok egy munkamenet létrejötte előtt is beállíthatók, mert a protokoll ezt a sorrendet írja elő.

Kérjen az ügynöktől valami ilyesmit:

A compute függvény a bin/main.dart-ban rossz értéket ad vissza. Állítson töréspontot arra a sorra, amely a product értékét adja, indítsa el hibakereső alatt, és mondja meg, mennyi valójában a és b.

Nagyjából ezt fogja futtatni:

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

Az indítás jelenti, hol állt meg:

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)

Aztán lépkedjen bele:

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

Egy gyermekekkel rendelkező objektum [expand: reference N]-t jelent — de csak akkor, ha valóban van mögötte valami, így az ügynök soha nem kap olyan kibontást, amelyet nem tud használni.

Bármihez, ami lokálisként nem látható:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Amit szeretne Művelet
Futtatás a következő megállásig continue
Következő sor, ugyanabban a keretben step_over
Belépés a hívásba step_in
Kilépés a hívóhoz step_out
Egy futó program megállítása pause

Egy beragadt folyamathoz, nem egy éppen indítotthoz:

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

Mindig fejezze be a munkamenetet. Egy hibakereső adapter birtokol egy megállított folyamatot, amely mindent fog, amit az a folyamat fog — egy portot, egy zárat, egy adatbázis-kapcsolatot.

Egy variables-kibontás egy mély objektumgráfon természeténél fogva korlátlan — egyetlen Flutter widget eléri a teljes elemfát. A hatókörönkénti gyermekek száma legfeljebb 50, az értékek legfeljebb 400 karakter, a veremkeretek pedig legfeljebb 30. Az olyan eszközeredmény, amely megtölti a kontextusablakot, az az eszköz, amely véget vet annak a futásnak, amelyet segített.