Μετάβαση στο περιεχόμενο

Αποσφαλμάτωση αποτυχημένου τεστ με πράκτορα

Αυτός ο οδηγός δείχνει πώς να κάνετε έναν πράκτορα να χρησιμοποιήσει έναν αποσφαλματωτή σε μια αποτυχία που οι εντολές εκτύπωσης δεν εξηγούν.

Το εργαλείο debug οδηγεί μια πραγματική συνεδρία Debug Adapter Protocol. Ένα σταματημένο frame απαντά ταυτόχρονα σε κάθε ερώτημα για εκείνη τη στιγμή — κάθε τοπική μεταβλητή, κάθε καλούντα και μια έκφραση που αξιολογείται στο δικό του πεδίο — ενώ μια εντολή εκτύπωσης απαντά μόνο στο ερώτημα που σκεφτήκατε να θέσετε πριν την εκτέλεση.

Το εργαλείο παραμένει στην επιφάνεια, ώστε ο πράκτορας να μπορεί να ρωτήσει γιατί τίποτα δεν είναι αξιοποιήσιμο, αντί να μαντεύει. Ένας προσαρμογέας μπορεί πράγματι να ξεκινήσει μόνο όταν ισχύουν και τα δύο από τα παρακάτω:

  • ένας δείκτης έργου στο checkout, και
  • το εκτελέσιμο του προσαρμογέα να επιλύεται.

Ζητήστε από τον πράκτορα να ελέγξει:

debug(op: "adapters")

Απαντά με ό,τι βρήκε ή εξηγεί ότι ένας προσαρμογέας χρειάζεται και τα δύο μισά.

Γλώσσα Προσαρμογέας Δείκτης Εγκατάσταση
Dart / Flutter dart debug_adapter pubspec.yaml Παρέχεται με το SDK — τίποτα να κάνετε
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt Παρέχεται με το LLVM
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

Ορίστε πρώτα το σημείο διακοπής και έπειτα εκκινήστε

Ενότητα με τίτλο «Ορίστε πρώτα το σημείο διακοπής και έπειτα εκκινήστε»

Η σειρά έχει σημασία και το εργαλείο την επιβάλλει: τα σημεία διακοπής μπορούν να οριστούν πριν υπάρξει συνεδρία, γιατί αυτή είναι η ακολουθία που απαιτεί το πρωτόκολλο.

Ζητήστε από τον πράκτορα κάτι σαν το εξής:

Η συνάρτηση compute στο bin/main.dart επιστρέφει λάθος τιμή. Βάλτε ένα σημείο διακοπής στη γραμμή που αναθέτει το product, εκκινήστε το υπό τον αποσφαλματωτή και πείτε μου τι είναι στην πραγματικότητα τα a και b.

Θα εκτελέσει περίπου τα εξής:

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

Η εκκίνηση αναφέρει πού σταμάτησε:

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)

Έπειτα μπείτε μέσα του:

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

Ένα αντικείμενο με θυγατρικά αναφέρει [expand: reference N] — αλλά μόνο όταν υπάρχει πραγματικά κάτι από πίσω, ώστε μια επέκταση που ο πράκτορας δεν μπορεί να αξιοποιήσει να μην προσφέρεται ποτέ.

Για ό,τι δεν είναι ορατό ως τοπική μεταβλητή:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
Τι θέλετε Λειτουργία
Εκτέλεση μέχρι το επόμενο σταμάτημα continue
Επόμενη γραμμή, ίδιο frame step_over
Μέσα στην κλήση step_in
Έξω, προς τον καλούντα step_out
Διακοπή ενός προγράμματος που εκτελείται pause

Για μια κολλημένη διεργασία αντί για μία που ξεκινάτε εσείς:

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

Τερματίζετε πάντα τη συνεδρία. Ένας προσαρμογέας αποσφαλμάτωσης κατέχει μια σταματημένη διεργασία που κρατά ό,τι κρατά αυτή η διεργασία — μια θύρα, ένα κλείδωμα, μια σύνδεση βάσης δεδομένων.

Μια επέκταση variables σε ένα βαθύ γράφημα αντικειμένων είναι από τη φύση της απεριόριστη — ένα widget του Flutter φτάνει σε ολόκληρο το δέντρο στοιχείων. Τα θυγατρικά ανά πεδίο περιορίζονται στα 50, οι τιμές στους 400 χαρακτήρες και τα frames στοίβας στα 30. Ένα αποτέλεσμα εργαλείου που γεμίζει το παράθυρο πλαισίου είναι ένα εργαλείο που τερματίζει την εκτέλεση που βοηθούσε.