Επιθεώρηση κατάστασης#
Αυτό το κεφάλαιο καλύπτει το λεξιλόγιο επιθεώρησης δεδομένων του αποσφαλματωτή: x, V, X, y, m, M, i, και τις επιλογές που ελέγχουν πόσο βαθιά γίνεται dump συγκεντρωτικών τιμών. Μετά από αυτό το κεφάλαιο μπορείτε να ρωτήσετε οποιοδήποτε εκτελούμενο πρόγραμμα «πώς μοιάζει στην πραγματικότητα αυτή η μεταβλητή, αυτό το πακέτο, αυτό το αντικείμενο αυτή τη στιγμή;»
Οι αναγνώστες φτάνουν εδώ γνωρίζοντας ότι το p EXPR εκτυπώνει ένα βαθμωτό. Οι υπόλοιπες εντολές επιθεώρησης κερδίζουν τη χρήση τους τη στιγμή που η απάντηση στο «τι είναι αυτό;» απαιτεί πάνω από μία τιμή.
x: dump δομών#
Το x EXPR εκτυπώνει όμορφα σε περιβάλλον λίστας, αναδρομικά μέσα σε αναφορές:
DB<1> x \%config
0 HASH(0x5651f9a82358)
'debug' => 1
'dsn' => 'dbi:SQLite::memory:'
'timeout' => 30
'users' => ARRAY(0x5651f9b28a10)
0 'alice'
1 'bob'
2 'carol'
Πάντα περάστε αναφορά για συγκεντρωτικά. Το x %h κάνει dump την επίπεδη λίστα κλειδιού/τιμής, που κρύβει τη δομή. Το x \%h κάνει αυτό που θέλετε.
DB<2> x \@list
0 ARRAY(0x5651f9b28a10)
0 'alice'
1 'bob'
2 'carol'
DB<3> x $obj
0 MY::Class=HASH(0x5651fa01c2b0)
'id' => 42
'prefs' => HASH(0x5651fa01c330)
'theme' => 'dark'
Για βαθιές ή κυκλικές δομές, περιορίστε την αναδρομή:
DB<4> x 2 \%tree # recurse 2 levels deep
DB<5> x 1 $obj # one level
Αν το πρώτο διακριτικό της έκφρασης είναι αριθμητικό, βάλτε σε παρενθέσεις:
DB<6> x (3 + $offset) # without parens, 3 is mis-parsed as depth
V και X: μεταβλητές πακέτου#
Το V [PKG [VARS]] κάνει dump τις καθολικές ενός πακέτου:
DB<1> V main
$counter = 42
@ARGV = (
0 '--verbose'
1 'input.txt'
)
%ENV = (
'PATH' => '/usr/bin:/bin'
...
)
Με δεύτερο όρισμα, φιλτράρει μεταβλητές:
DB<2> V MyApp $config $last_user # only these
DB<3> V MyApp ~^config # regex: names matching /^config/
DB<4> V MyApp !^_ # regex: names NOT matching /^_/
Το X είναι το V για το τρέχον πακέτο:
DB<5> X # dump current package's globals
DB<6> X $foo @bar # filtered
Τα V / X δεν βλέπουν λεξιλογικές (μεταβλητές my). Για αυτές, χρησιμοποιήστε το y.
y: λεξιλογικές στην περικλείουσα εμβέλεια#
Το y LEVEL [VARS] διαβάζει λεξιλογικές μεταβλητές my μέσω του PadWalker:
DB<1> y 0 # lexicals of the current sub
my $req = HTTP::Request=HASH(0x...)
my $user_id = 42
my @errors = ()
DB<2> y 1 # one frame up (the caller's lexicals)
my $request_count = 118
my $dispatcher = MyApp::Dispatcher=HASH(0x...)
DB<3> y 0 $req $user_id # only those
Το y απαιτεί PadWalker έκδοση 0.08 ή νεότερη. Λειτουργεί μόνο μέσα σε sub (το εξωτερικό σώμα του σεναρίου δεν έχει pad για να διασχιστεί).
m: μέθοδοι αντικειμένου ή κλάσης#
Το m EXPR παραθέτει μεθόδους που μπορούν να κληθούν σε ένα αντικείμενο ή κλάση:
DB<1> m $user
via UNIVERSAL: isa can DOES VERSION DESTROY
via MyApp::Model: save load delete update
via MyApp::Role::Auditable: audit_log record_event
DB<2> m 'MyApp::Worker'
via UNIVERSAL: ...
via MyApp::Worker: dispatch retry cancel
Ομαδοποιεί τις μεθόδους ανά το πακέτο που τις παρέχει - χρήσιμο για να εντοπίσετε από ποιον ρόλο ή υπερκλάση προέρχεται μια μέθοδος.
M και i: αρθρώματα και κληρονομικότητα#
Το M παραθέτει τα φορτωμένα αρθρώματα με τις εκδόσεις τους:
DB<1> M
'DBI' (version 1.643)
'JSON::PP' (version 4.16)
'MyApp::Model' (version undef)
...
Το i CLASS ή το i $obj εκτυπώνει το δέντρο κληρονομικότητας:
DB<2> i $user
MyApp::User 0.12
MyApp::Model 0.42
Moo::Object ?
Χρήσιμο για το «από πού προέρχεται στην πραγματικότητα αυτή η μέθοδος;» όταν η επίλυση μεθόδου διασχίζει πολλούς ρόλους.
S: ονόματα υπορουτινών#
Το S [[!]PAT] παραθέτει ονόματα sub που ταιριάζουν (ή δεν ταιριάζουν) με ένα μοτίβο:
DB<1> S ^MyApp::Worker::
MyApp::Worker::cancel
MyApp::Worker::dispatch
MyApp::Worker::retry
DB<2> S !^(main|DB|UNIVERSAL):: # everything except these
Το S σκέτο τα παραθέτει όλα - μακρύ.
p έναντι x: ποιο να χρησιμοποιείτε πότε#
Θέλετε | Χρησιμοποιήστε |
|---|---|
Την τιμή ενός μόνο βαθμωτού, σκέτη |
|
Μια συνενωμένη / μορφοποιημένη έκφραση |
|
Κατακερματισμό ή πίνακα |
|
Τα πεδία ενός αντικειμένου |
|
Μόνο το ανώτατο επίπεδο |
|
Μεταβλητές πακέτου του |
|
Λεξιλογικές της τρέχουσας sub |
|
Λίστα μεθόδων του |
|
Αλυσίδα |
|
Ειδική περίπτωση: το p είναι επίπεδο print. Για αναφορά, το p $ref εκτυπώνει HASH(0x…). Χρησιμοποιήστε x $ref για τα περιεχόμενα.
Επιλογές βάθους και συμπαγότητας#
Η έξοδος dump διαμορφώνεται από επιλογές που ορίζονται μέσω της εντολής o. Οι σχετικές ρυθμίσεις για επιθεώρηση:
Επιλογή | Αποτέλεσμα |
|---|---|
| Βάθος αναδρομής (αρνητικό = απεριόριστο). Προεπιλογή 4. |
| Μόνο τα πρώτα N στοιχεία πίνακα· κενό = όλα. |
| Το ίδιο, για κατακερματισμούς. |
| Σύντομοι πίνακες σε μία γραμμή. |
| Ακόμη πιο σφιχτό. |
| Dump περιεχομένων glob. |
| Πλήρης ανάπτυξη επαναλαμβανόμενων αναφορών (προσοχή σε κύκλους). |
|
|
| Πώς αποδίδεται το |
| Εκτύπωση της overload-μετατραμμένης σε συμβολοσειρά μορφής. |
Ορισμός επιλογής μέσα σε συνεδρία:
DB<1> o dumpDepth=6
DB<2> o compactDump=1
DB<3> o arrayDepth=20
DB<4> o compactDump? # query current value
Ορισμός επιλογών στην εκκίνηση μέσω του PERLDB_OPTS ή στο .perldb:
PERLDB_OPTS="dumpDepth=6 compactDump=1" perl -d script.pl
Επιθεώρηση εσωτερικών SV#
Το Devel::Peek εκθέτει την εσωτερική αποθήκευση του βαθμωτού - σημαίες τύπου, refcount, διάταξη PV/NV/IV, αλυσίδα magic - όταν η ερώτηση είναι «τι είδους βαθμωτό είναι πραγματικά αυτό;»:
DB<1> use Devel::Peek; Dump($sv)
Κυρίως για τη διερεύνηση tied μεταβλητών, overloaded αντικειμένων, ή ανωμαλιών απόδοσης όπου η απάντηση εξαρτάται από το αν ένα βαθμωτό αποθηκεύεται αυτή τη στιγμή ως ακέραιος, συμβολοσειρά, ή και τα δύο.
Σημείωση: το Devel::Peek στην pperl είναι στρώμα συμβατότητας - αναφέρει μια ειδική για την pperl διάταξη Sv αντί της διάταξης SV της perl5. Πεδία όπως REFCNT, FLAGS, PV, IV, NV έχουν ισοδύναμα· η ακριβής έξοδος διαφέρει. Δείτε τον pperl-architecture guide για λεπτομέρειες διάταξης.
Αποτίμηση στην προτροπή#
Ό,τι δεν αναγνωρίζεται ως εντολή αποτιμάται ως Perl. Χρησιμοποιήστε το για να εμβαθύνετε πέρα από μία μόνο εντολή:
DB<1> p keys %{ $obj->{prefs} }
theme,locale,tz
DB<2> x [ grep { !defined $_->{parent} } @nodes ]
DB<3> x { map { $_->id => $_->name } @users }
Για εφάπαξ διεκδικήσεις χωρίς διακοπή:
DB<1> die "unexpected" if ref $obj ne 'MyApp::User'
I/O προγράμματος έναντι I/O αποσφαλματωτή#
Η είσοδος και έξοδος του ίδιου του αποσφαλματωτή περνούν μέσω των $DB::IN και $DB::OUT, που ανοίγουν απευθείας στο /dev/tty. Το πρόγραμμα μπορεί να ανακατευθύνει ελεύθερα STDIN / STDOUT / STDERR· η προτροπή του αποσφαλματωτή εμφανίζεται κανονικά. Αντίστροφα, η έξοδος του p EXPR δεν μολύνει το δεσμευμένο stdout του προγράμματος.
Μάθετε περισσότερα#
breakpoints - σταματήστε εκεί που μπορείτε να επιθεωρήσετε· αυτό το κεφάλαιο αφορά το τι να κοιτάξετε αφού σταματήσετε.
tracing - παρακολουθήστε τιμές να αλλάζουν με τον χρόνο χωρίς να σταματάτε σε κάθε βήμα.