Einführung in den Perl Debugger (PDF) - Thomas Fahle
Einführung in den Perl Debugger (PDF) - Thomas Fahle
Einführung in den Perl Debugger (PDF) - Thomas Fahle
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>Perl</strong><br />
<strong>Debugger</strong><br />
<strong>E<strong>in</strong>führung</strong> <strong>in</strong> <strong>den</strong> <strong>Perl</strong> <strong>Debugger</strong><br />
Real Programmers don‘t need debuggers,<br />
they can read core dumps.<br />
Larry Wall<br />
Viele <strong>Perl</strong>-Programmierer mögen und nutzen <strong>den</strong> <strong>Perl</strong>-<strong>Debugger</strong><br />
aus unterschiedlichsten Grün<strong>den</strong> nicht. Auch ich<br />
habe mich jahrelang gesträubt, <strong>den</strong> <strong>Perl</strong>-<strong>Debugger</strong> zu benutzen.<br />
Wenn man jedoch e<strong>in</strong>ige Male mit dem <strong>Debugger</strong> gearbeitet<br />
hat, wird man ihn gerne <strong>in</strong> se<strong>in</strong>en Werkzeugkasten<br />
aufnehmen.<br />
Der nachfolgende Artikel soll e<strong>in</strong>en e<strong>in</strong>fachen E<strong>in</strong>stieg <strong>in</strong> <strong>den</strong><br />
<strong>Perl</strong>-<strong>Debugger</strong> ermöglichen, <strong>in</strong>dem die wichtigsten grundlegen<strong>den</strong><br />
Kommandos und Tricks Schritt für Schritt erläutert<br />
wer<strong>den</strong>.<br />
Der <strong>Perl</strong>-<strong>Debugger</strong> kann <strong>in</strong> <strong>den</strong> Apache Web Server (mod_<br />
perl) <strong>in</strong>tegriert wer<strong>den</strong> und es gibt natürlich auch graphische<br />
Benutzeroberflächen.<br />
Bevor man <strong>den</strong> <strong>Debugger</strong> anwirft<br />
If debugg<strong>in</strong>g is the process of remov<strong>in</strong>g bugs,<br />
then programm<strong>in</strong>g must be the process of putt<strong>in</strong>g them <strong>in</strong>.<br />
Edsger W. Dijkstra<br />
Viele Bugs lassen sich durch e<strong>in</strong>en defensiven Programmierstil<br />
vermei<strong>den</strong>. E<strong>in</strong> gutes <strong>Perl</strong>-Programm verwendet daher<br />
strict und warn<strong>in</strong>gs.<br />
<strong>Debugger</strong> Starten<br />
Features oder Was kann der<br />
<strong>Debugger</strong>?<br />
Der <strong>Perl</strong>-<strong>Debugger</strong> wird stets mit dem Kommandozeilenschalter<br />
-d aufgerufen.<br />
Der <strong>Perl</strong>-<strong>Debugger</strong> beherrscht die typischen <strong>Debugger</strong>features<br />
wie Haltepunkte (Breakpo<strong>in</strong>ts), Überprüfung von Variablen,<br />
Metho<strong>den</strong>, Code und Klassenhierachien, Verfolgung<br />
(Trace) der Code-Ausführung und Subrout<strong>in</strong>en-Argumente.<br />
Parameter, die an das zu debuggende Programm übergeben<br />
wer<strong>den</strong>, können auf der Kommandozeile angegeben wer<strong>den</strong>.<br />
perl -d programm [arg0 arg1 ...]<br />
Zusätzlich erlaubt der <strong>Debugger</strong> die Ausführung eigener Befehle<br />
(<strong>Perl</strong>-Code) vor und nach jeder Programmcode-Zeile<br />
und die Änderung von Variablen und Code während der Ausführung.<br />
Dies gilt auch für CGI-Programme, hier entsprechen die Parameter<br />
<strong>den</strong> Formularfeldern.<br />
perl -d programm.cgi [param1= param2=]<br />
Die Verfolgung geforkter Programme, Threads und remote<br />
debugg<strong>in</strong>g wird ebenfalls unterstützt.<br />
Der <strong>Debugger</strong> kann auch als <strong>Perl</strong>-Shell gestartet wer<strong>den</strong>.<br />
perl -d -e 0<br />
35
<strong>Perl</strong><br />
Erste Schritte - Der <strong>Debugger</strong> als<br />
<strong>Perl</strong>-Shell<br />
Für die ersten Schritte mit dem <strong>Perl</strong>-<strong>Debugger</strong> bietet sich die<br />
Nutzung als <strong>Perl</strong>-Shell an.<br />
perl -d -e 0<br />
... Ausgabe unterdrückt<br />
ma<strong>in</strong>::(-e:1): 0<br />
DB<br />
Der <strong>Debugger</strong> meldet sich mit e<strong>in</strong>em eigenem Prompt<br />
(DB) und wartet auf die E<strong>in</strong>gabe e<strong>in</strong>es Kommandos. Zum<br />
Been<strong>den</strong> des <strong>Debugger</strong>s dient das Kommando q, Hilfe erhält<br />
man über das Kommando h.<br />
Code e<strong>in</strong>geben<br />
Nun kann beliebiger <strong>Perl</strong>-Code e<strong>in</strong>geben wer<strong>den</strong>.<br />
perl -d -e 0<br />
DB pr<strong>in</strong>t “Hallo Foo-Magaz<strong>in</strong>”<br />
Hallo Foo-Magaz<strong>in</strong><br />
DB pr<strong>in</strong>t 6 * 7; pr<strong>in</strong>t “\n”; pr<strong>in</strong>t 6 x 7<br />
42<br />
6666666<br />
Das Zeilenende wird als Anweisungsende aufgefasst, das übliche<br />
Semikolon am Zeilenende kann daher entfallen. Mehrere<br />
Anweisungen <strong>in</strong> e<strong>in</strong>er Zeile müssen allerd<strong>in</strong>gs durch e<strong>in</strong><br />
Semikolon getrennt wer<strong>den</strong>.<br />
Cont<strong>in</strong>uation L<strong>in</strong>es (Fortführungszeilen)<br />
Falls mehr als e<strong>in</strong>e Zeile zur E<strong>in</strong>gabe des Codes benötigt wird,<br />
muss das Zeilenende mit e<strong>in</strong>em \ maskiert wer<strong>den</strong>.<br />
1<br />
2<br />
DB foreach my $number ( 1 .. 2 ) { \<br />
cont: pr<strong>in</strong>t “$number\n” \<br />
cont: }<br />
Variablen<strong>in</strong>halte ausgeben mit p<br />
Das Kommando p erlaubt die e<strong>in</strong>fache Ausgabe der Werte<br />
von Variablen.<br />
DB $scalar = “Text”<br />
DB @array = qw(e<strong>in</strong>s zwei)<br />
DB %hash = ( ‘a’ => ‘1’, ‘b’ => ‘2’)<br />
DB p $scalar<br />
Text<br />
DB p @array<br />
e<strong>in</strong>szwei<br />
DB p %hash<br />
a1b2<br />
Datenstrukturen und Variablen<strong>in</strong>halte mit x anzeigen<br />
Die Ausgabe von p ist für skalare Variablen durchaus brauchbar.<br />
E<strong>in</strong>e übersichtlichere Darstellung lässt sich mit dem<br />
Kommando x erzeugen.<br />
E<strong>in</strong>fache Variablen und Datenstrukturen<br />
Betrachten wir zunächst e<strong>in</strong>mal die grundlegen<strong>den</strong> e<strong>in</strong>fachen<br />
<strong>Perl</strong>-Datenstrukturen.<br />
Das Kommando x evaluiert se<strong>in</strong>e Parameter im Listenkontext.<br />
DB x $scalar<br />
0 ‘Text’<br />
Bei skalaren Variablen wird e<strong>in</strong>e Liste mit e<strong>in</strong>em Element zurückgegeben.<br />
DB x @array<br />
0 ‘e<strong>in</strong>s’<br />
1 ‘zwei’<br />
Bei Array-Variablen wird e<strong>in</strong>e Liste der Elemente mit dem<br />
jeweiligen Index zurückgegeben.<br />
DB x %hash<br />
0 ‘a’<br />
1 1<br />
2 ‘b’<br />
3 2<br />
Auch bei Hashes wird e<strong>in</strong>e Liste mit <strong>den</strong> entsprechen<strong>den</strong> Indizes<br />
ausgegeben.<br />
Wenn man jedoch dem Kommando x e<strong>in</strong>e Referenz auf e<strong>in</strong>e<br />
Variable übergibt, wird die Ausgabe wesentlich <strong>in</strong>formativer.<br />
DB x \$scalar<br />
0 SCALAR(0x8427f00)<br />
-> ‘Text’<br />
DB x \@array<br />
0 ARRAY(0x8427e1c)<br />
0 ‘e<strong>in</strong>s’<br />
1 ‘zwei’<br />
DB x \%hash<br />
0 HASH(0x8427d38)<br />
‘a’ => 1<br />
‘b’ => 2<br />
36
<strong>Perl</strong><br />
Komplexe Datenstrukturen betrachten<br />
Das Kommando x eignet sich weiterh<strong>in</strong> sehr gut zum Betrachten<br />
komplexer Datenstrukturen.<br />
Beispiel: Hash of Arrays (HoA)<br />
DB %HoA = ( \<br />
cont: fl<strong>in</strong>tstones => [ “fred”, “barney” ],\<br />
cont: jetsons => [ “george”, “jane”, \<br />
“elroy“ ],)<br />
DB x \%HoA<br />
0 HASH(0x8427de0)<br />
‘fl<strong>in</strong>tstones’ => ARRAY(0x81547bc)<br />
0 ‘fred’<br />
1 ‘barney’<br />
‘jetsons’ => ARRAY(0x8427d50)<br />
0 ‘george’<br />
1 ‘jane’<br />
2 ‘elroy’<br />
E<strong>in</strong> <strong>Perl</strong>-Programm im <strong>Debugger</strong><br />
Beispielprogramm<br />
Für die nachfolgen<strong>den</strong> Übungen wird e<strong>in</strong> kle<strong>in</strong>es Beispielprogramm<br />
(example.pl) verwendet.<br />
1 #!/usr/b<strong>in</strong>/perl<br />
2 use warn<strong>in</strong>gs;<br />
3 use strict;<br />
4 foreach my $number (1..2) {<br />
5 &display($number);<br />
6 }<br />
7 sub display {<br />
8 my $number = shift;<br />
9 $number = spr<strong>in</strong>tf(“*** %02d ***\n”,<br />
$number);<br />
10 pr<strong>in</strong>t $number;<br />
11 }<br />
Ich benutze x sehr gerne beim E<strong>in</strong>lesen von Daten aus Dateien,<br />
<strong>in</strong>dem ich durch das Programm steppe (s.u.) und mir<br />
nach jedem e<strong>in</strong>gelesenem Datensatz anzeigen lasse, ob die<br />
Daten auch korrekt und vollständig <strong>in</strong> die Datenstruktur<br />
übernommen wer<strong>den</strong>.<br />
Module, Packages und Klassen <strong>in</strong>spizieren<br />
Gela<strong>den</strong>e Module M<br />
Das Kommando M zeigt alle gela<strong>den</strong>en Module, auch die Pakete,<br />
die vom <strong>Debugger</strong> oder anderen gela<strong>den</strong>en Modulen<br />
gela<strong>den</strong> wer<strong>den</strong>, an.<br />
DB M<br />
‘Carp.pm’ => ‘1.04<br />
from /usr/share/perl/5.8/Carp.pm’<br />
... Ausgabe gekürzt<br />
Angezeigt wer<strong>den</strong> neben dem gela<strong>den</strong>en Modul die Versionsnummer<br />
und auch der Ort von dem das Paket gela<strong>den</strong> wurde.<br />
Das erleichtert die Suche nach Fehlern, die auf unterschiedlichen<br />
Modulversionen auf dem Entwicklungs- und Produktionsserver<br />
beruhen erheblich.<br />
Inheritance i<br />
Das Kommando i zeigt <strong>den</strong> Vererbungsbaum (@ISA) für gela<strong>den</strong>e<br />
Pakete an.<br />
DB use FileHandle<br />
DB i FileHandle<br />
FileHandle 2.01, IO::File 1.13, IO::Handle<br />
1.25, IO::Seekable 1.1, Exporter 5.58<br />
Dabei geht der <strong>Debugger</strong> rekursiv durch die Pakete, die vom<br />
untersuchten Paket gela<strong>den</strong> wer<strong>den</strong>.<br />
Dieses simple Programm erzeugt folgende Ausgabe:<br />
perl example.pl<br />
*** 01 ***<br />
*** 02 ***<br />
Beispielprogramm im <strong>Debugger</strong> aufrufen<br />
perl -d example.pl<br />
...<br />
ma<strong>in</strong>::(example.pl:4): \<br />
foreach my $number (1..2) {<br />
Der <strong>Debugger</strong> stoppt das Programm <strong>in</strong> der ersten ausführbaren<br />
Zeile (hier 4).<br />
Blättern im Code<br />
Mit dem Kommando l kann man durch <strong>den</strong> Code vorwärts<br />
blättern, mit - rückwärts. Die Angabe von Zeilennummern<br />
bzw. Zeilenbereichen, Subrout<strong>in</strong>en oder Variablen ist ebenfalls<br />
möglich.<br />
Beispiel Zeile 1 bis 15 anzeigen<br />
DB l 1-15<br />
1 #!/usr/b<strong>in</strong>/perl<br />
2: use warn<strong>in</strong>gs;<br />
3: use strict;<br />
4==> foreach my $number (1..2) {<br />
5: &display($number);<br />
6 }<br />
7 sub display {<br />
8: my $number = shift;<br />
9: $number = spr<strong>in</strong>tf(„*** %02d ***\n“, \<br />
$number);<br />
10: pr<strong>in</strong>t $number;<br />
11 }<br />
37
<strong>Perl</strong><br />
Doppelpunkte (:) nach der Zeilennummer zeigen an, wo<br />
Breakpo<strong>in</strong>ts oder Aktionen (s.u.) gesetzt wer<strong>den</strong> können. Der<br />
nach rechts zeigende Pfeil (==>) gibt die aktuelle Position im<br />
Programm an.<br />
Das Programm ausführen (cont<strong>in</strong>ue)<br />
Das Kommando c [l<strong>in</strong>e|sub] (cont<strong>in</strong>ue) führt <strong>den</strong> Code<br />
bis zur angegebenen Zeile oder bis zum angegebenen Unterprogramm<br />
aus.<br />
Subrout<strong>in</strong>en auflisten S<br />
Das Kommando S [[!] ~pattern] listet alle Unterprogramme<br />
auf, die dem regulären Ausdruck pattern (nicht !)<br />
entsprechen.<br />
Ohne Muster wer<strong>den</strong> alle Subrout<strong>in</strong>en, auch die Unterprogramme,<br />
die von Paketen oder dem <strong>Debugger</strong> selbst gela<strong>den</strong><br />
wer<strong>den</strong>, angezeigt. Diese Liste kann sehr, sehr lang wer<strong>den</strong>.<br />
Daher empfiehlt sich die Angabe e<strong>in</strong>es Pakets<br />
DB S ma<strong>in</strong><br />
ma<strong>in</strong>::BEGIN<br />
ma<strong>in</strong>::display<br />
oder die Verwendung e<strong>in</strong>es Patterns.<br />
DB S display<br />
Term::ReadL<strong>in</strong>e::Gnu::XS::display_readl<strong>in</strong>e_<br />
version<br />
Term::ReadL<strong>in</strong>e::Gnu::XS::shadow_redisplay<br />
ma<strong>in</strong>::display<br />
Hier sieht man sehr schön, das wirklich alle gela<strong>den</strong>en Subrout<strong>in</strong>en<br />
durchsucht wer<strong>den</strong>.<br />
Variablen anzeigen<br />
Das Kommando V zeigt alle Variablen im aktuellen Paket an.<br />
Wie bei <strong>den</strong> Subrout<strong>in</strong>en wer<strong>den</strong> alle gela<strong>den</strong>en Variablen<br />
angezeigt. Diese Liste kann ebenfalls sehr, sehr lang se<strong>in</strong>.<br />
Daher empfiehlt sich auch hier die Verwendung des Paketnamens<br />
<strong>in</strong> Verb<strong>in</strong>dung mit e<strong>in</strong>em Suchbegriff (eq)<br />
DB V Carp Verbose<br />
$Verbose = 0<br />
oder die Verwendung des Paketnamens <strong>in</strong> Verb<strong>in</strong>dung mit<br />
e<strong>in</strong>em regulärem Ausdruck<br />
DB V Carp ~V<br />
$Verbose = 0<br />
$VERSION = 1.04<br />
Mit my deklarierte Variablen wer<strong>den</strong> jedoch mit V nicht angezeigt.<br />
Hierzu kann das Kommando y verwendet wer<strong>den</strong>,<br />
welches das CPAN-Modul PadWalker benötigt.<br />
Ohne Parameter wird der Code von der aktuellen Zeile bis<br />
zum nächsten Breakpo<strong>in</strong>t oder Watch (s.u.) oder bis zum<br />
Ende des Programms ausgeführt.<br />
ma<strong>in</strong>::(example.pl:4): \<br />
foreach my $number (1..2) {<br />
DB c<br />
*** 01 ***<br />
*** 02 ***<br />
Da hier ke<strong>in</strong>e Breaks oder Watches (s.u.) gesetzt wur<strong>den</strong>,<br />
läuft das Programm e<strong>in</strong>fach durch.<br />
Restart R<br />
Sobald das Programm e<strong>in</strong>mal vollständig durchgelaufen ist,<br />
ist e<strong>in</strong> Neustart des Programms im <strong>Debugger</strong> notwendig.<br />
Intern verwendet der <strong>Perl</strong> <strong>Debugger</strong> (perl5db.pl) dazu die<br />
Funktion exec().<br />
Debugged program term<strong>in</strong>ated. Use q to quit<br />
or R to restart,<br />
use o <strong>in</strong>hibit_exit to avoid stopp<strong>in</strong>g after<br />
program term<strong>in</strong>ation,<br />
h q, h R or h o to get additional <strong>in</strong>fo.<br />
DBR<br />
Warn<strong>in</strong>g: some sett<strong>in</strong>gs and command-l<strong>in</strong>e options<br />
may be lost!<br />
...<br />
ma<strong>in</strong>::(example.pl:4): foreach my $number<br />
(1..2) {<br />
Mit ActiveState-<strong>Perl</strong> 5.8.x unter W<strong>in</strong>dows funktioniert das<br />
leider nicht. Hier ist e<strong>in</strong> Neustart des <strong>Debugger</strong>s auf der Kommandozeile<br />
zw<strong>in</strong>gend erforderlich. Dank der History-Funktion<br />
von command.com ist dies ke<strong>in</strong> wirkliches H<strong>in</strong>dernis für<br />
<strong>den</strong> E<strong>in</strong>satz des <strong>Debugger</strong>s.<br />
Step Into<br />
s führt die nächste Programmzeile aus und spr<strong>in</strong>gt dabei <strong>in</strong><br />
die Unterprogramme (Step Into)<br />
Beispiel Step Into<br />
DB s<br />
ma<strong>in</strong>::(example.pl:5):<br />
&display($number);<br />
DB s<br />
ma<strong>in</strong>::display(example.pl:8): \<br />
my $number = shift;<br />
DB s<br />
38
<strong>Perl</strong><br />
ma<strong>in</strong>::display(example.pl:9): \<br />
$number = spr<strong>in</strong>tf(“*** %02d ***\n”,$number);<br />
DB s<br />
ma<strong>in</strong>::display(example.pl:10): pr<strong>in</strong>t<br />
$number;<br />
DB s<br />
*** 01 ***<br />
ma<strong>in</strong>::(example.pl:5):<br />
&display($number);<br />
Step Over<br />
n führt die nächste Programmzeile aus und spr<strong>in</strong>gt dabei<br />
über die Unterprogramme (Step Over)<br />
Beispiel Step Over<br />
DB n<br />
ma<strong>in</strong>::(example.pl:5):<br />
DB n<br />
*** 01 ***<br />
ma<strong>in</strong>::(example.pl:5):<br />
DB n<br />
*** 02 ***<br />
&display($number);<br />
&display($number);<br />
Aus Subrout<strong>in</strong>en aussteigen mit return<br />
Das Kommando r (return) kehrt aus Unterprogrammen zurück<br />
und zeigt <strong>den</strong> Rückgabewert an. Das ist beispielsweise<br />
<strong>in</strong> Verb<strong>in</strong>dung mit s (Step Into) recht nützlich.<br />
DB s<br />
ma<strong>in</strong>::(example.pl:5): &display($number);<br />
DB s<br />
ma<strong>in</strong>::display(example.pl:8): \<br />
my $number = shift;<br />
Der <strong>Debugger</strong> steht jetzt <strong>in</strong> der Subrout<strong>in</strong>e display().<br />
DB r<br />
*** 01 ***<br />
void context return from ma<strong>in</strong>::display<br />
ma<strong>in</strong>::(example.pl:5): &display($number);<br />
Als Bonus wird der Rückgabewert der Subrout<strong>in</strong>e, hier void,<br />
angezeigt.<br />
Actions, Breakpo<strong>in</strong>ts und Watches<br />
Actions, Breakpo<strong>in</strong>ts und Watches auflisten<br />
Das Kommando L [a|b|w] listet die gesetzten Actions (a),<br />
Breakpo<strong>in</strong>ts (b) und Watches (w). Ohne Parameter wer<strong>den</strong><br />
alle Aktionen, Breakpo<strong>in</strong>ts und Watches angezeigt.<br />
Breakpo<strong>in</strong>ts<br />
Das Kommando b [l<strong>in</strong>e|sub [condition]] setzt e<strong>in</strong>en<br />
Haltepunkt <strong>in</strong> der angegebenen Zeile bzw. vor Ausführung<br />
des Unterprogramms. Zusätzlich kann e<strong>in</strong>e Bed<strong>in</strong>gung (beliebiger<br />
<strong>Perl</strong>-Code) festgelegt wer<strong>den</strong>.<br />
B (l<strong>in</strong>e|*) löscht <strong>den</strong> Haltepunkt <strong>in</strong> Zeile l<strong>in</strong>e oder alle<br />
Haltepunkte.<br />
Breakpo<strong>in</strong>t beim E<strong>in</strong>stieg <strong>in</strong> die Subrout<strong>in</strong>e display() setzen<br />
DB b display<br />
und prüfen, ob und wo er gesetzt wurde<br />
DB L<br />
example.pl:<br />
8: my $number = shift;<br />
break if (1)<br />
Der Haltepunkt bef<strong>in</strong>det sich <strong>in</strong> Zeile 8. c führt das Programm<br />
bis zum nächsten Breakpo<strong>in</strong>t aus.<br />
DB c<br />
ma<strong>in</strong>::display(example.pl:8): my $number =<br />
shift;<br />
Das Programm bis zum nächsten Haltepunkt weiter ausführen:<br />
Hier wird das Unterprogramm e<strong>in</strong>mal durchlaufen.<br />
DB c<br />
*** 01 ***<br />
ma<strong>in</strong>::display(example.pl:8): \<br />
my $number = shift;<br />
Das Programm bis zum nächsten Haltepunkt weiter ausführen:<br />
Hier wird das Unterprogramm noch e<strong>in</strong>mal durchlaufen.<br />
DB c<br />
*** 02 ***<br />
Sobald e<strong>in</strong> Haltepunkt erreicht wird, stoppt der <strong>Debugger</strong><br />
das Programm. Jetzt können Variablen mit <strong>den</strong> bereits vorgestellten<br />
Metho<strong>den</strong> <strong>in</strong>spiziert und geändert wer<strong>den</strong>.<br />
Beispiel:<br />
Breakpo<strong>in</strong>t <strong>in</strong> Zeile 5 setzen<br />
DB b 5<br />
39
<strong>Perl</strong><br />
und das Programm bis zum Haltepunkt ausführen.<br />
DB c<br />
ma<strong>in</strong>::(example.pl:5):<br />
Die skalare Variable $number <strong>in</strong>spizieren,<br />
ändern<br />
DB x \$number<br />
0 SCALAR(0x825a11c)<br />
-> 1<br />
DB $number = 42;<br />
&display($number);<br />
List Code revisited<br />
Sobald Haltepunkte oder Actions gesetzt s<strong>in</strong>d, wer<strong>den</strong> diese<br />
im Programmlist<strong>in</strong>g l durch e<strong>in</strong> b bzw. a nach der Zeilennummer<br />
gekennzeichnet.<br />
DB b display<br />
DB a 5 pr<strong>in</strong>t “A5 $number”;<br />
DB a 8 pr<strong>in</strong>t “A8 $number”;<br />
DB l 4-8<br />
4==> foreach my $number (1..2) {<br />
5:a &display($number);<br />
6 }<br />
7 sub display {<br />
8:ba my $number = shift;<br />
und das Programm bis zum nächsten Breakpo<strong>in</strong>t laufen lassen.<br />
DB c<br />
*** 42 ***<br />
ma<strong>in</strong>::(example.pl:5):<br />
&display($number);<br />
Die Änderung der Variable erfolgt nur im <strong>Debugger</strong>, der Orig<strong>in</strong>alcode<br />
muss nicht (!) geändert wer<strong>den</strong>.<br />
Actions<br />
Das Kommando a [l<strong>in</strong>e] command [condition] setzt<br />
<strong>in</strong> Zeile Nummer l<strong>in</strong>e e<strong>in</strong>e Aktion (beliebiger <strong>Perl</strong>-Code). Zusätzlich<br />
kann e<strong>in</strong>e Bed<strong>in</strong>gung (beliebiger <strong>Perl</strong>-Code) festgelegt<br />
wer<strong>den</strong>. E<strong>in</strong>e Aktion wird vor der Ausführung der Zeile<br />
ausgeführt. A [l<strong>in</strong>e|*] löscht die Action <strong>in</strong> Zeile l<strong>in</strong>e bzw.<br />
alle (*).<br />
Aktion <strong>in</strong> Zeile 5 setzen.<br />
DB a 5 pr<strong>in</strong>t “A5a $number ”; $number++;<br />
pr<strong>in</strong>t “A5b $number\n”<br />
Und das Programm e<strong>in</strong>mal durchlaufen lassen.<br />
DB c<br />
A5a 1 A5b 2<br />
*** 02 ***<br />
A5a 2 A5b 3<br />
*** 03 ***<br />
Übergabeparameter an Subrout<strong>in</strong>en lassen sich mit Actions<br />
aus @_ ermitteln.<br />
DB a 8 pr<strong>in</strong>t “Parameter $_[0]\n”<br />
DB c<br />
Parameter 1<br />
*** 01 ***<br />
Parameter 2<br />
*** 02 ***<br />
E<strong>in</strong> Haltepunkt hat Vorrang vor e<strong>in</strong>er Aktion.<br />
Variablen beobachten - Watches<br />
Das Kommando w [expr] setzt e<strong>in</strong>en Beobachter für expr<br />
(beliebiger <strong>Perl</strong>-Code), während W (expr|*a) e<strong>in</strong>en oder<br />
alle Watches löscht.<br />
DB w $number<br />
DB c<br />
Watchpo<strong>in</strong>t 0: $number changed:<br />
old value: ‘ ’<br />
new value: ‘1’<br />
ma<strong>in</strong>::(example.pl:5): &display($number);<br />
Graphische Benutzeroberflächen<br />
Als Alternative zur Kommandozeile gibt es auch e<strong>in</strong>ige graphische<br />
Benutzeroberflächen. Nachfolgend e<strong>in</strong>e kle<strong>in</strong>e Auswahl.<br />
ptkdb - Der Klassiker<br />
http://ptkdb.sourceforge.net/<br />
ddd (DataDisplay<strong>Debugger</strong>)<br />
http://www.gnu.org/software/ddd/<br />
Eclipse <strong>Perl</strong> Integration<br />
http://e-p-i-c.sourceforge.net/<br />
Komodo IDE<br />
Kommerzielles Produkt von Active-State<br />
http://activestate.com/products/komodo_ide/<br />
40
<strong>Perl</strong><br />
Affrus - für Macs<br />
Kommerzielles Produkt von Late Night Software Ltd<br />
http://www.latenightsw.com/affrus/<strong>in</strong>dex.html<br />
Referenzkarten zum Ausdrucken<br />
Andrew Ford: <strong>Perl</strong> <strong>Debugger</strong> Reference Card<br />
http://refcards.com/refcard/perl-debugger-forda<br />
The <strong>Perl</strong> <strong>Debugger</strong> Quick Reference Card, a <strong>PDF</strong> courtesy of<br />
O‘Reilly<br />
http://www.rfi.net/debugger-slides/reference-card.pdf<br />
<strong>Perl</strong> <strong>Debugger</strong> Quick Reference<br />
http://www.perl.com/2004/11/24/debugger_ref.pdf<br />
<strong>E<strong>in</strong>führung</strong> <strong>in</strong> <strong>Perl</strong> <strong>Debugger</strong><br />
http://www.ims.uni-stuttgart.de/lehre/teach<strong>in</strong>g/2006-<br />
WS/<strong>Perl</strong>/debugger4up.pdf<br />
Weiterführende Literatur<br />
In diesem Artikel kann ich nicht auf alle Features des <strong>Perl</strong>-<br />
<strong>Debugger</strong>s e<strong>in</strong>gehen. Wer mehr wissen möchte, sollte sich<br />
die nachfolgen<strong>den</strong> Bücher e<strong>in</strong>mal genauer ansehen.<br />
<strong>Perl</strong> <strong>Debugger</strong> Pocket Reference.<br />
Foley, Richard:<br />
<strong>Perl</strong> <strong>Debugger</strong> Pocket Reference.<br />
(O‘Reilly) ISBN: 0596005032<br />
Kle<strong>in</strong>, fe<strong>in</strong>, handlich, gut.<br />
Pro <strong>Perl</strong> Debugg<strong>in</strong>g: From Professional to Expert<br />
Foley, Richard, Lester, Andy:<br />
Pro <strong>Perl</strong> Debugg<strong>in</strong>g: From Professional to Expert<br />
(Apress) ISBN: 1590594541<br />
FMTEYEWTK: E<strong>in</strong> wirklich ausführliches und gutes Buch<br />
mit zahlreichen kommentierten Beispielen.<br />
<strong>Perl</strong> Debugged<br />
Peter Scott, Ed Wright:<br />
<strong>Perl</strong> Debugged<br />
ISBN: 02011700549<br />
(Out of pr<strong>in</strong>t, aber noch im Handel erhältlich)<br />
E<strong>in</strong> sehr gutes Buch über <strong>Perl</strong>-Programmierung und Debugg<strong>in</strong>g.<br />
Me<strong>in</strong>es Erachtens e<strong>in</strong>es der besten <strong>Perl</strong>-Bücher überhaupt.<br />
# <strong>Thomas</strong> <strong>Fahle</strong><br />
41