Norm Matloff's Introduction to the JSwat Java Debugging Tool

JSwat is a free Java debugging tool. (It "swats bugs.") You can either use it together with your favorite text editor -- I suggest using the VIM extension to vi or jEdit-- or if you prefer an integrated development environment (IDE), the JIPE Java IDE uses JSwat as its debugging tool. (I prefer the former setting; details below.)

JSwat has a nice small size, both in terms of disk/memory usage and in terms of its footprint on your screen.

It also has some nice features which are lacking in some other debugging tools. For example, in JSwat you can trace through the elements of a linked list quite easily, by repeatedly clicking on a certain icon. And JSwat has a macros capability, which allows you to automate keystroke sequences of actions specific to a given debugging project.

Contents of this Web page:

Where to get JSwat:

Download from the JSwat home page.

How to install it:

Make sure you have the Java JDK package installed on your system. For the current version of JSwat you should avoid JDK 1.4. Obtain JDK 1.3 at JavaSoft.

After unpacking the .tar.gz file, you get a .jar file. You could unpack that too, but I will assume here that you don't.

You'll need to find out where your tools.jar file is. Use the UNIX which command to find out where javac is, and then go to the directory ../lib from there, or use the UNIX find command.

IMPORTANT: READ THIS FIRST

This document has been prepared on the basis of JSwat 1.4.5.

It is assumed here that you are familiar with the general use of debugging tools, to set breakpoints etc. If not, see my debug Web page.

A small amount of the material here in this tutorial is OS-dependent. We are assuming a UNIX environment here.

I will assume the following in my running example throughout the rest of this document:

It will be clear how to modify this data for your own setting.

Starting it up:

Simply type

java -cp 
/mydir/ex1:/usr/local/java/jdk1.3/lib/tools.jar:/usr/local/jswat/
jswat-20010804.jar com.bluemarsh.jswat.Main

(This is one long command line, not three lines. There is a blank space after "-cp" but not one between "/jswat/" and "jswat-20010804".)

If you have trouble getting JSwat to run, try setting -classic for the Java VM; see the JSwat home page for details. Also, you are likely to encounter problems if you are using Red Hat Linux 7.0; upgrade to 7.1 or better.

Panels in the JSwat window:

JSwat is very compact in its usage of screen space. Instead of having multiple windows, JSwat's display consists of a single window, subdivided into a number of panels:

You may resize the various panels and the window as a whole for your convenience.

How to load a Java class:

(The word load here is a bit misleading. The action refererred to does not actually load the class into memory; it merely makes preparations for that. However, I will continue to use the word below, without further disclaimers, since it is used in JSwat.)

Recall that in our running example, Main() is in the class Intro, and calls another class, NumNode.

We first make sure that we have compiled both source files, using the -g option in javac. Then in the Command panel, we type

load Intro

(Or, click on the Debug icon, described below, and specify the class name and arguments. Actually, JSwat will automatically use the name and arguments from your last JSwat session, so this might be the more convenient way to load a class.) The source code, Intro.java, will then . show up in the Source Code panel.

The other class, NumNode, will be loaded automatically when called by Intro. However, if you wish to set breakpoints in NumNode but none in Intro, you must manually load NumNode before Intro.

How to use the debugger:

Starting a debugging session:

You must first start a debugging session, by clicking on the debug icon, just below the word Debug near the top-left of the screen. A window will pop up. Go to the line labeled "Class name and arguments." In our example, we will run the program with the arguments 12, 5 and 8, so we make sure this line consists of

Intro 12 5 8

Make sure that "Start VM suspended" is checked.

Note that if you recompile and reload one of the classes (see below), or if you allow the program to execution to completion, the debugging session will end, and you must start another one.

Setting breakpoints:

After starting a debugging session (always remember this must be done first), go to the line at which you want to set the breakpoint, and right-click on it. (If the desired source file is not currently displayed in the Source Code panel, click on Windows and then on the associated class name.) A (one-line) menu will pop up, consisting of a single choice, "Add breakpoint." Choose this, being careful to move the mouse a bit so that the pointer lies within this choice. Your adding the breakpoint will be confirmed in the Messages panel.

You can delete, temporarily disable or impose conditions on breakpoints, by right-clicking on the breakpoint, and then choosing Properties.

Breakpoints are preserved between debugging sessions, even ifJSwat. is exited.

You can get information about all of your breakpoints by choosing the Breakpoints panel near the lower-left of the window (or select Debug at the top of the windown, then Breakpoints). Note that this will result in showing you all breakpoints that JSwat knows about, including other Java programs of yours which you are not currently debugging!

Executing, single-stepping, etc.:

Since you chose "Start VM suspended" above, the program is not yet running yet. Start it, by clicking on the Resume icon (a triangle which looks like a Play button on a boom box). The program will execute to the first breakpoint. Any terminal output (from System.out.println()) during this time will appear in the I/O panel, and you should type any keyboard input to your program there too.

You can then single-step, run until you leave the method, etc., using the icons under Options and Windows or by clicking on the Resume icon (which will make the program execute until it next hits a breakpoint).

Checking and setting the values of variables:

The values of the local variables are displayed in the Locals panel.

Note that if a variable is a pointer, you can dereference it, i.e. find out the values in the object it points to, by clicking on the diamond-shaped box icon to the left. If the referenced object also has a pointer, you can then click on its icon. In this manner, you can easily traverse all or part of a linked data structure.

(Note: There are also "values" shown for the pointers themselves. These are object IDs used internally by the Java VM. They don't mean much, but can help you locate circular references in linked data structures; JSwat may point out such a situation to you automatically, by the way.)

You can also view local variables through the "locals" command in the Command panel. This is sometimes useful if you are currently in one class, say NumNode, but wish to quickly view the locals in another class, say Intro.

If a class contains a lot of locals, you may find it inconvenient to pick out the one you want each time you step through the program. If so, try setting a watchpoint for that variable. Go to the Watches panel (when you are in the class), fill in an entry for the name of the variable and then hit the Enter key. (Just type the name of the variable, without the class name.)

A variable can be set (currently only to a constant rvalue) using the "set" command.

Reloading a class after a recompile:

After recompiling a class, you will need to load it again, and start a new debugging session. However, you need not reload the other classes which have not changed since last being loaded.

Labor-saving devices:

The whole point of a debugging tool is to save time. By using the JSwat features described below, you can save on typing keystrokes, which not only saves time but also allows you to concentrate better in finding your bugs, since there is less distraction from typing.

Aliases:

In our running example, we could type into the Command panel

alias li load Intro

to define an alias, "li". Afterward, every time we wish to load Intro, we could simply type "li".

Macros:

These are essentially multi-line aliases. They consist of several commands, some or all of which could be invocations of aliases.

In our running example, I could type the following into the Command panel (assuming I had already defined the li alias above, and a similar ln macro for NumNode:

macro lni
ln
li
endmacro

From that point onward, every time I type "lni" then I would load both classes. And again, note that even though in this example the lines were both alias invocations, they could be just ordinary commands.

The "read" command:

Aliases and macros are only temporary; after you exit JSwat, they won't be there the next time you start it up. To maintain permanent items of this kind, use the "read" command.

In our running example above, for instance, I could create a file, say /mydir/ex1/load_all, with the following lines:

load NumNode
load Intro

Then, whenever I start up JSwat, I could type the following into the Command panel:

read /mydir/ex1/load_all

A "read" file can contain aliases and macros, and the read command itself could be aliased.

The JSwat console mode:

You can use JSwat in text-only mode. This is necessary if you are debugging through a text-only interface, say telnet, and sometimes desirable if you need a very quick startup, or an automated debugging session.

The only actions available in this mode are through the Command panel. Here for example is how you might debug Intro/NumNode in console mode: You would first start up JSwat with the -console command-line option, and then type, say,

load Intro
stop NumNode:34
run Intro 12 5 8
resume

Commands you might use after that might be "next" and "step" for single-stepping, "resume" again, "locals", "print", "dump", "enable" and "disable".

As of JSwat version 1.4.5, the "view" command for viewing the source code has not been implemented, so you will need to use a text editor in another window for this purpose. (Make sure you know how to use the editor to show the line number of a given line.)

With skillful use of "print", "dump", "alias", "macro" and "read", you can make consolde mode fairly usable.

The JSwat startup files:

On Unix/Linux platforms, the JSwat startup files are in a subdirectory .jswat of your home directory.

Documentation:

Some documentation is available in the Command panel for the text-oriented commands, e.g. "load". Type

help commands

Further documentation is available on the JSwat home page.

Integrating with a text editor:

Use with vim:

The vim text editor is one of the most widely used. It is a very flexible extension of the old vi editor.

To use vim in conjunction with JSwat or some other debugger, first make sure that vim autowrite option is set, say with a line

set autowrite 

in your ~/.vimrc file. Then, assuming you have a Makefile in the current directory, either type

:make

in vim, or if you are in vim's GUI mode, click on the hammer icon. If there are any compilation errors, vim will report them and after you hit Return, vim will take you to the line where the first error occurs. Don't forget that you must now reload the recompiled class in JSwat.

Use with jEdit:

Click here for a plug-in with which you can access JSwat from within jEdit.