Der Java-Debugger JDB [] (Der Java-Debugger JDB), Lektion, Seite 722625
https://www.purl.org/stefan_ram/pub/jdb_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Der Java -Debugger JDB

Programmablauf anzeigen

Der Ablauf einer Sequenz läßt sich mit dem zum JDK  gehörenden jdb  (Java debugger ) anzeigen. Das wird hier am Beispiel der Quelldatei "Main.java" gezeigt. Diese Datei enthält einen Block mit sieben Ausdruckanweisungen.

Main.java
public class Main 
{ public static void main( final java.lang.String[] args ) 
{ java.lang.Thread.dumpStack(); 
java.lang.Thread.dumpStack(); 
java.lang.Thread.dumpStack(); }}

Die Quelldatei sollte mit der Option "-g" übersetzt werden, damit die für die Ablaufanzeige nötigen Information in die Klassendatei übertragen werden.

Konsole
javac -g Main.java

jdb

Wenn die Klassendatei vorliegt kann der Ablaufanzeiger "jdb" gestartet werden, der anstelle der virtuellen Javamaschine "java" mit dem Klassennamen als Argument aufgerufen wird. Durch die Ausgabe der Aufforderung ">" zeigt er seine Bereitschaft zur Entgegennahme von Kommandos an.

Konsole
jdb Main
Initializing jdb ... 
>

"stop" "in" 〈Klasse 〉 '.'

Mit dem stop-in -Kommando kann ein Haltepunkt gesetzt werden. Der Ablauf des Programmes wird dann an dieser Stelle unterbrochen werden, damit weitere Kommandos eingegeben werden können. Durch das Kommando "stop in Main.main" wird ein Haltepunkt am Anfang der Methode "Main.main" (also am Anfang des Blocks von "Main.java") gesetzt. Das bedeutet, daß die Ausführung des Programms an der Stelle des Haltepunktes unterbrochen werden wird und weitere Kommandos eingegeben werden können.

Konsole
> stop in Main.main
Deferring breakpoint Main.main. 
It will be set after the class is loaded. 
>

"run"

Das Kommando "run" startet die Ausführung der beim Aufruf des Programmes angegebenen Klasse. Dabei wird der noch vor der ersten Ausdruckanweisung liegende Haltepunkt erreicht und das Programm fordert mit der Ausgabe "main[1] " zur Eingabe weiterer Kommandos auf. Die erste Ausdruckanweisung wurde also bisher noch nicht ausgeführt.

Die nächste zur Ausführung anstehende Anweisung erscheint unter der mit dem Text "Breakpoint hit" beginnenden Zeile.

Konsole
> run
run Main 

VM Started: Set deferred breakpoint Main.main 
 
Breakpoint hit: "thread=main", Main.main(), line=3 bci=0 
3 { java.lang.Thread.dumpStack();;

main[1]

"next"

Durch das Kommando "next" kann die zuvor angezeigte Zeile  nun ausgeführt werden. Da hier mehrere Anweisungen in einer Zeile gleichzeitig ausgeführt werden würden, kann es zur Benutzung der Ablaufanzeige hilfreich sein, nur höchstens eine Anweisung pro Zeile zu verwenden.

Konsole
main[1] next
> ... 
 
Step completed: "thread=main", Main.main(), line=4 bci=8 
4 java.lang.Thread.dumpStack();; 
main[1]

"!!"

Das Kommando "!!" wiederholt immer das direkt zuvor gegebene Kommando. Daher kann anstelle einer erneuten Eingabe des Kommandos "next" hier auch das Kommando "!!" eingegeben werden, um eine weitere Zeile ausführen zu lassen.

Konsole
main[1] !!
> ... 
 
Step completed: "thread=main", Main.main(), line=5 bci=16 
5 java.lang.Thread.dumpStack(); 
main[1]

"list"

Das Kommando "list" gibt den Quelltext aus. Dabei wird die nächste zur Ausführung anstehende Zeile durch den Text "=>" markiert.

Konsole
main[1] list
1 public class Main 
2 { public static void main( String s[]) 
3 { java.lang.Thread.dumpStack(); 
4 java.lang.Thread.dumpStack(); 
5 => java.lang.Thread.dumpStack(); }} 
main[1]

"stop" "at" 〈Klasse 〉 ':'

Das stop-at -Kommando erlaubt es, einen Haltepunkt vor eine bestimmte Zeilennummer einer bestimmten Klasse zu setzen. Das Kommando "stop at Main:8" setzt einen Haltepunkt vor Zeile 8 des obigen Auflistung des Quelltextes der Klasse "Main".

Konsole
main[1] stop at Main:8
Set breakpoint Main:8 
main[1]

"stop"

Durch Eingabe des Kommandos "stop" alleine können die bisher gesetzten Haltepunkt angezeigt werden.

Konsole
main[1] stop 
Breakpoints set: 
breakpoint Test.main 
breakpoint Main:8

"cont"

Während die erste Ausführung einer Klasse mit dem Kommando "run" gestartet wird, dient das Kommando "cont" (continue , „setze fort!“) zur Fortsetzung der Ausführung an der aktuellen Stelle. Der vom Block erzeugten Ausgabe wird noch ein Größer-Zeichen ">" hinzugefügt, das an dieser Stelle etwas irritiert. Die Ausführung läuft bis zum nächsten Haltepunkt vor Zeile 8 weiter.

Konsole
main[1] cont
... 
 
Breakpoint hit: "thread=main", Main.main(), line=8 bci=40 
8 System.out.println( "Alte Kinder, junge Kinder" ); 
 
main[1]

Wie zuvor kann das Kommando "next" verwendet werden, um die zur Ausführung anstehende Zeile auszuführen.

Konsole
main[1] next
> ... 
 
Step completed: "thread=main", Main.main(), line=9 bci=48 
9 System.out.println( "Hoerens immer gerne." ); 
 
main[1]

"exit" | "quit"

Das Kommando "exit" beendet das Programm zur Ablaufanzeige. Die Ausführung wird dabei aber zunächst noch fortgesetzt. Das Kommando "quit" hat die gleiche Wirkung. (Unter manchen Umgebungen kann eine Eingabe wie Strg-C die Ablaufanzeige sofort unterbrechen.)

Konsole
main[1] exit
... 
 
>

Die Datei ".jdbrc"

Kommandos, die am Anfang des Testens immer wieder eingegeben werden, können einmal in eine Datei namens ".jdbrc" geschrieben werden.

.jdbrc
stop in Main.main 
run

Durch die hier als Beispiel gegeben Datei ".jdbrc" geht der Ablaufanzeiger „automatisch“ vor den Anfang der ersten Ausdruckanweisung und wartet auch weitere Kommandos. Hier kann nun beispielsweise sofort das Kommando "next" eingegeben werden.

Konsole
>jdb Main
Initializing jdb ... 
*** Reading commands from F:\r\k\java\.jdbrc 
Deferring breakpoint Main.main. 
It will be set after the class is loaded. 
> run Main 
> > 
VM Started: Set deferred breakpoint Main.main 
 
Breakpoint hit: "thread=main", Main.main(), line=3 bci=0 
3 { java.lang.Thread.dumpStack();; 
 
main[1]

"print"

Die Ausgabe eines Ausdrucks mit dem Kommando "print" ist hilfreich, wenn eine Ausdruck ausgewertet werden soll, ohne daß erst ein Programm geschrieben werden muß. Doch es werden zum Zeitpunkt der Niederschrift dieses Textes noch nicht alle Arten von Ausdrücken unterstützt.

Konsole
main[1] print 4 + 5.0 * 3.24333 
4 + 5.0 * 3.24333 = 20.21665
main[1] print 4 % 3 
com.sun.tools.example.debug.expr.ParseException: Unknown operation: % 
4 % 3 = null

main[1] print java.lang.Math.abs( -2 ) 
operation not yet supported 
java.lang.Math.abs( -2 ) = null 
main[1]

"classes"

Das Kommando "classes" zeigt alle verfügbaren Klassen an.

Konsole [Anfang]
main[1] classes
boolean[] 
byte[] 
char[] 
char[][] 
char[][][] 
double[] 
float[] 
int[] 
java.beans.PropertyChangeEvent 
java.beans.PropertyChangeSupport 
java.io.BufferedInputStream

"methods"

Mit dem methods -Kommando lassen sich alle Methode einer Klasse anzeigen.

Konsole [Anfang]
main[1] methods java.lang.Math
java.lang.Math <init>() 
java.lang.Math sin(double) 
java.lang.Math cos(double) 
java.lang.Math tan(double) 
java.lang.Math asin(double)

Programmablauf anzeigen *

Der Ablauf eines Methodenaufrufs läßt sich mit dem zum JDK  gehörenden jdb  (java debugger ) anzeigen. Das wird hier am Beispiel der Quelldatei »Main.java« gezeigt.

Main.java
public class Main 
{ public static void refrainAusgeben() 
{ Java.lang.System.out.println( "Sim sa la dim, bam ba," ); 
Java.lang.System.out.println( "Sa la du, sa la dim -" ); } 
public static void main( final java.lang.String[] args ) 
{ { Java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" ); 
refrainAusgeben(); 
Java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." ); } 
{ Java.lang.System.out.println( "Da kam ein junger Jaeger, -" ); 
refrainAusgeben(); 
Java.lang.System.out.println( "Da kam ein junger Jaegersmann." ); } 
{ Java.lang.System.out.println( "Der schoss den armen Kuckuck, -" ); 
refrainAusgeben(); 
Java.lang.System.out.println( "Der schoss den armen Kuckuck tot." ); }}}

System.out
Auf einem Baum ein Kuckuck, - 
Sim sa la dim, bam ba, 
Sa la du, sa la dim - 
Auf einem Baum ein Kuckuck sass. 
Da kam ein junger Jaeger, - 
Sim sa la dim, bam ba, 
Sa la du, sa la dim - 
Da kam ein junger Jaegersmann. 
Der schoss den armen Kuckuck, - 
Sim sa la dim, bam ba, 
Sa la du, sa la dim - 
Der schoss den armen Kuckuck tot.

Die Grundlagen der Bedienung der Ablaufanzeige wurden bereits in einer anderen Lektion behandelt. Hier werden nun noch einige Aspekte ergänzt, die mit Methodenaufrufen zusammenhängen. Die Ablaufanzeige wird hier mit einer Datei ».jdbrc« im aktuellen Verzeichnis »dir0« so gestartet, daß sie bei der ersten Zeile der Hauptmethode zunächst anhält.

.jdbrc
stop in Main.main 
run

Konsole
dir0>jdb Main 
Initializing jdb ... 
*** Reading commands from dir0\.jdbrc 
Deferring breakpoint Main.main. 
It will be set after the class is loaded.

> run Main 
> > 
VM Started: Set deferred breakpoint Main.main 
 
Breakpoint hit: "thread=main", Main.main(), line=6 bci=0 
6 { { Java.lang.System.out.println( "Auf einem Baum ein Kuckuck, -" );

»methods«

Mit dem methods -Kommando lassen sich die beiden Methoden unserer Klasse anzeigen. Daneben werden noch weitere Methoden angezeigt, die aber in dieser Lektion ignoriert werden können.

Konsole
main[1] methods Main 
** methods list ** 
Main <init>() 
Main refrainAusgeben() 
Main main(java.lang.String[]) 
java.lang.Object <init>() 
java.lang.Object registerNatives() 
java.lang.Object getClass() 
java.lang.Object hashCode() 
java.lang.Object equals(java.lang.Object) 
java.lang.Object clone() 
java.lang.Object toString() 
java.lang.Object notify() 
java.lang.Object notifyAll() 
java.lang.Object wait(long) 
java.lang.Object wait(long, int) 
java.lang.Object wait() 
java.lang.Object finalize() 
java.lang.Object <clinit>()

»next«

Durch das Kommando »next« kann die nächste Zeile  bekanntlich ausgeführt werden.

Konsole
main[1] next 
> Auf einem Baum ein Kuckuck, - 
 
Step completed: "thread=main", Main.main(), line=7 bci=8 
7 refrainAusgeben();

Ein Methodenaufruf wird dabei als ein  Schritt angesehen, die einzelnen Zeilen der aufgerufenen Methode werden also nicht zur Einzelzeilenausführung vorgelegt. Daher wird die Methode »refrainAusgeben« nach der Eingabe des ersten Kommandos »!!« vollständig abgearbeitet und der gesamte  Refrain erscheint vor der nächsten Eingabemöglichkeit.

Konsole
main[1] !! 
> Sim sa la dim, bam ba, 
Sa la du, sa la dim - 
 
Step completed: "thread=main", Main.main(), line=8 bci=11 
8 Java.lang.System.out.println( "Auf einem Baum ein Kuckuck sass." ); }

Nach dem Ende der Auswertung des Methodenaufrufs geht der Ablauf natürlich wieder in der aufrufenden Methode weiter.

Konsole
main[1] !! 
> Auf einem Baum ein Kuckuck sass. 
 
Step completed: "thread=main", Main.main(), line=9 bci=19 
9 { Java.lang.System.out.println( "Da kam ein junger Jaeger, -" ); 
 
main[1]

»step«

Falls keine verfolgbare Methode aufgerufen wird, ist die Wirkung des Kommandos »step« der des Kommandos »next« gleich. Es wird die nächste zur Ausführung anstehende Zeile aufgerufen.

Konsole
main[1] step 
> Da kam ein junger Jaeger, - 
 
Step completed: "thread=main", Main.main(), line=10 bci=27 
10 refrainAusgeben();

Das Kommando »step« setzt die Einzelzeilenausführung gegebenenfalls innerhalb  einer aufgerufenen Methode fort (falls die Methode angezeigt werden kann). So kann auch nach jeder Zeile einer aufgerufenen Methode ein Kommando eingegeben werden.

Konsole
main[1] !! 
step 

Step completed: "thread=main", Main.refrainAusgeben(), line=3 bci=0 
3 { Java.lang.System.out.println( "Sim sa la dim, bam ba," );

main[1] !! 
step 
> Sim sa la dim, bam ba, 
 
Step completed: "thread=main", Main.refrainAusgeben(), line=4 bci=8 
4 Java.lang.System.out.println( "Sa la du, sa la dim -" ); }

main[1] !! 
step 
> Sa la du, sa la dim - 
 
Step completed: "thread=main", Main.main(), line=11 bci=30 
11 Java.lang.System.out.println( "Da kam ein junger Jaegersmann." ); }

Nach dem Ende der aufgerufenen Methode geht der Ablauf auch hier wieder in der aufrufenden Methode weiter.

Konsole
main[1] !! 
step 
> Da kam ein junger Jaegersmann. 
 
Step completed: "thread=main", Main.main(), line=12 bci=38 
12 { Java.lang.System.out.println( "Der schoss den armen Kuckuck, -" );

main[1] !! 
> Der schoss den armen Kuckuck, - 
 
Step completed: "thread=main", Main.main(), line=13 bci=46 
13 refrainAusgeben();

»step« »up«

Das step-up -Kommando erlaubt es, alle weiteren Zeilen einer Methode bis zum Ende der Methode auszuführen. Der nächste Schritt ist dann also gegebenenfalls die nächste Zeile in der aufrufenden Methode.

Konsole
main[1] step 

Step completed: "thread=main", Main.refrainAusgeben(), line=3 bci=0 
3 { Java.lang.System.out.println( "Sim sa la dim, bam ba," );

main[1] step up 
Sim sa la dim, bam ba,> 
Sa la du, sa la dim - 
 
Step completed: "thread=main", Main.main(), line=14 bci=49 
14 Java.lang.System.out.println( "Der schoss den armen Kuckuck tot." ); }}}

main[1] step 
> Der schoss den armen Kuckuck tot. 
 
The application exited
$

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722625 stefan_ram:722625 Der Java-Debugger JDB Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722625, slrprddef722625, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/jdb_java