Ενσωμάτωση με IDE και DAP#

Αυτό το κεφάλαιο καλύπτει την αποσφαλμάτωση με οδηγό τον editor: Perl::LanguageServer στο VS Code και τα αντίστοιχα σε Neovim / Emacs / IntelliJ, απομακρυσμένη αποσφαλμάτωση μέσω SSH, και αποσφαλμάτωση σε λειτουργία container μέσω kubectl ή docker.

Όσοι αναγνώστες καταφεύγουν σε IDE αντί σε προτροπή τερματικού θα βρουν εδώ την ελάχιστη βιώσιμη εγκατάσταση, τα κλειδιά ρυθμίσεων που έχουν σημασία, και τα γνωστά σημεία ευθραυστότητας (Coro, αντιστοίχιση διαδρομών, attach έναντι launch).

Το τοπίο#

Δύο πρωτόκολλα επί της γραμμής, και τα δύο με backends σε Perl:

Πρωτόκολλο

Backend Perl

Κατάσταση

DAP

Perl::LanguageServer

Ενεργό.

DBGp

Devel::Debug::DBGp

Στάσιμο από το 2018.

Για νέες εγκαταστάσεις, χρησιμοποιήστε DAP μέσω του Perl::LanguageServer. Το DBGp επιβιώνει μόνο εκεί όπου ένας υπάρχων πελάτης (vim vdebug, pugdebug) είναι ήδη σε χρήση.

Το Perl::LanguageServer συγκεντρώνει έναν LSP (νοημοσύνη κώδικα, διαγνωστικά, μετάβαση σε ορισμό) και έναν προσαρμογέα DAP (αποσφαλματωτή) σε μία διεργασία. Το μισό LSP λειτουργεί σε οποιοδήποτε αρχείο Perl στον editor· το μισό DAP τρέχει μόνο κατά τη διάρκεια συνεδρίας αποσφαλμάτωσης.

Ελάχιστη εγκατάσταση VS Code#

Πλευρά CPAN - εγκαταστήστε στην Perl υπό την οποία θα τρέξει το debuggee:

cpanm Perl::LanguageServer

Πλευρά editor - εγκαταστήστε την επέκταση richterger.perl:

Ctrl-P  →  ext install richterger.perl

.vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "perl",
      "request": "launch",
      "name": "Debug current file",
      "program": "${workspaceFolder}/${relativeFile}",
      "stopOnEntry": true,
      "args": [],
      "cwd": "${workspaceFolder}",
      "env": {},
      "reloadModules": true
    }
  ]
}

Ανοίξτε ένα .pl ή .pm, ορίστε breakpoints στο περιθώριο, πατήστε F5. Η Debug Console δέχεται οποιαδήποτε έκφραση Perl, που αποτιμάται στο τρέχον πλαίσιο στοίβας.

.vscode/settings.json για το @INC και την επιλογή διερμηνέα:

{
  "perl.perlInc": [
    "${workspaceFolder}/lib",
    "${workspaceFolder}/local/lib/perl5"
  ],
  "perl.perlCmd": "/usr/bin/perl"
}

Δυνατότητες#

Το Perl::LanguageServer υποστηρίζει τα χαρακτηριστικά DAP που έχουν σημασία:

  • Launch, pause, step in / over / out, return.

  • Breakpoints υπό συνθήκη και χωρίς συνθήκη, προστιθέμενα ανά πάσα στιγμή.

  • Επιθεώρηση μεταβλητών σε όλα τα πλαίσια στοίβας.

  • Set variable - αλλαγή τιμής στη μέση της συνεδρίας από τον editor.

  • Εκφράσεις watch.

  • Αποτίμηση εντός περιβάλλοντος στη Debug Console.

  • Hot-reload αρθρωμάτων μέσω reloadModules: true.

Δεν υποστηρίζονται:

  • Σύνδεση σε εκτελούμενη διεργασία. Το request: "attach" δεν είναι υλοποιημένο· μόνο το "launch" (ο LS εκκινεί ο ίδιος το debuggee).

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

Επεξεργαστείτε τοπικά· αποσφαλματώστε σε απομακρυσμένο υπολογιστή. settings.json:

{
  "perl.sshCmd": "ssh",
  "perl.sshAddr": "deploy@host.example",
  "perl.sshUser": "deploy",
  "perl.sshWorkspaceRoot": "/srv/app",
  "perl.pathMap": [
    ["/srv/app", "${workspaceFolder}"]
  ]
}

Το Perl::LanguageServer τρέχει στον απομακρυσμένο υπολογιστή· ο editor μένει τοπικός. Το pathMap μεταφράζει τα ονόματα αρχείων που αναφέρει το debuggee (/srv/app/lib/X.pm) σε διαδρομές του τοπικού editor (${workspaceFolder}/lib/X.pm).

Breakpoints που σιωπηρά αποτυγχάνουν να συνδεθούν είναι σχεδόν πάντα αναντιστοιχία pathMap.

Αποσφαλμάτωση σε λειτουργία container#

Το launch.json δέχεται κλειδιά container που επικαλούνται τα docker, podman, docker-compose, ή kubectl:

Κλειδί

Τιμές

containerCmd

"docker", "docker-compose", "podman", "kubectl"

containerMode

"run" (φρέσκο container) ή "exec" (υπάρχον)

containerName

Image (για run) ή όνομα container (για exec)

containerArgs

Επιπλέον ορίσματα που περνούν στο runtime του container.

pathMap

[["/in/container", "/on/host"], ...]

Σύνδεση σε ήδη εκτελούμενο container Docker:

{
  "type": "perl",
  "request": "launch",
  "name": "Debug in container",
  "program": "/app/bin/worker.pl",
  "containerCmd": "docker",
  "containerMode": "exec",
  "containerName": "my-running-worker",
  "pathMap": [["/app", "${workspaceFolder}"]]
}

Pod Kubernetes:

{
  "type": "perl",
  "request": "launch",
  "name": "Debug in pod",
  "program": "/app/bin/worker.pl",
  "containerCmd": "kubectl",
  "containerMode": "exec",
  "containerName": "my-pod-abc123",
  "containerArgs": ["-n", "staging", "--container", "app"],
  "pathMap": [["/app", "${workspaceFolder}"]]
}

Περιορισμοί:

  • Το Perl::LanguageServer πρέπει να είναι εγκατεστημένο μέσα στο image. Ενσωματώστε το στο Dockerfile ή χτίστε παραλλαγή dev-image.

  • Το pathMap είναι η μεγαλύτερη αιτία αποτυχίας. Breakpoints που δεν συνδέονται ποτέ σημαίνουν ότι το debuggee αναφέρει διαδρομή που δεν μεταφράζεται.

Άλλοι editors#

  • Neovim - χρησιμοποιήστε nvim-dap με το Perl::LanguageServer ως προσαρμογέα. Η προδιαγραφή του προσαρμογέα είναι ένα σύντομο απόσπασμα Lua που δείχνει στο perl -MPerl::LanguageServer -e '...'.

  • Emacs - dap-mode με τον ίδιο προσαρμογέα.

  • IntelliJ - Devel::Camelcadedb + το πρόσθετο Perl της JetBrains. Όχι DAP· ιδιόκτητο πρωτόκολλο. Βιώσιμο αλλά εκτός του οικοσυστήματος Perl::LanguageServer.

  • Sublime Text - υπάρχουν πελάτες DAP μέσω προσθέτων· χρησιμοποιήστε το Perl::LanguageServer ως προσαρμογέα.

Εκκινήσεις ειδικής λειτουργίας#

Κλειδιά launch.json για μη προεπιλεγμένη επίκληση:

Κλειδί

Αποτέλεσμα

useTaintForDebug

Εισάγει -T στην επίκληση perl του debuggee.

sudoUser

Επανεκτελεί το debuggee ως αυτός ο χρήστης (χρειάζεται sudo χωρίς κωδικό).

reloadModules

Ενεργοποιεί το hot-reload αρθρωμάτων κατά τη διάρκεια της συνεδρίας.

stopOnEntry

Διακοπή στην πρώτη δήλωση.

Παγίδες#

  • Σφάλματα σε χρόνο BEGIN εμφανίζονται ως γεγονότα «output» του DAP, όχι ως γεγονότα διακοπής σε breakpoint. Χρησιμοποιήστε stopOnEntry: true για να πετύχετε καν διακοπή αν το σενάριο πεθάνει στο BEGIN.

  • Το $SIG{__DIE__} της εφαρμογής μπορεί να καταπιεί εξαιρέσεις πριν τρέξει ο χειριστής του αποσφαλματωτή. Τυλίξτε τον χειριστή της εφαρμογής σε φύλακα if ($^S) (δείτε exceptions).

  • Οι εκφράσεις watch επανα-αποτιμώνται σε κάθε βήμα. Αποφύγετε ακριβές εκφράσεις ή εκφράσεις με παρενέργειες.

  • Όχι source maps. Η Perl δεν έχει ισοδύναμη έννοια με το source map της JavaScript. Φίλτρα πηγαίου (Smart::Comments) μπορούν να μετατοπίσουν τους αναφερόμενους αριθμούς γραμμών κατά ένα· breakpoints σε φιλτραρισμένα αρχεία μπορεί να προσγειωθούν σε λάθος γραμμή.

  • Βηματική εκτέλεση Future::AsyncAwait. Λειτουργεί σε απλές περιπτώσεις· η βηματική εκτέλεση σε σύνθετες αλυσίδες await είναι αναξιόπιστη. Πέστε σε perl -d για βαθιά διερεύνηση async, ή χρησιμοποιήστε καταγραφή.

  • Σε Windows native - ο χειρισμός stdin του Perl::LanguageServer είναι σπασμένος σε Windows. Το WSL δουλεύει.

  • Coro. Το Perl::LanguageServer βασίζεται εσωτερικά στο Coro· το πιο συχνά αναφερόμενο σημείο ευθραυστότητας είναι η κακή αλληλεπίδραση του Coro με ασυνήθιστες ρυθμίσεις build. Αν ο διακομιστής αρνείται να ξεκινήσει, ελέγξτε πρώτα το log εγκατάστασης του Coro.

Μάθετε περισσότερα#

  • interactive-debugger - απευθείας perl -d, όταν η στοίβα IDE είναι υπερβολή ή μη διαθέσιμη.