05.11.2013 Aufrufe

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

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!