The PJEE is a developer tool for testing Java software. This includes running Java software to observe its behavior and debugging Java software to explore the relationships between the source code's structure, the compiled code's behavior and the PJEE's capabilities.
Some of the debugging techniques described here can be used to debug Java software on a PersonalJava device as well as on the PJEE. But for most debugging tasks the PJEE will be more convenient and have more debugging resources (e.g. symbol tables) than a PersonalJava device.
Note: The debugging support in the PJEE is based on the Java Virtual Machine Debugger Interface (JVMDI). To support compatibility with the PJEE, third-party developer tools must support this interface.
The following sections describe the debugging resources available for PersonalJava software development and introduce their basic usage.
The JDK 1.2.x includes the jdb command-line debugger which can be used to debug Java programs running on the PJEE. The JDK must be installed on either the same system as the PJEE or on a system connected over an IP network.
The following steps describe how to use jdb to debug a Java applet running on the PJEE.
% pjava_g -ss1024k -debug sun.tools.agent.EmptyApp
EmptyApp is a placeholder Java application which is used by jdb when it is launched without an initial class.
Note: The default Java stack size may be too small for debugging purposes. So it may be necessary to increase the stack size with the -ssnum option.
Record the session password identifier:
% Agent password: identifier
% jdb -host pjava_host -password identifier
pjava_host is the host name or IP address of the system running the PJEE. identifier is the session password identifier displayed by the PersonalJava application launcher in the previous step.
> load sun.applet.AppletViewer
> stop in HelloWorldApplet.paint
> run sun.applet.AppletViewer HelloWorldApplet.html
At this point, execution should be stopped at the first line in the paint method, and jdb should be connected to the PJEE for debugging. See jdb for a list of debugging commands or type help at the jdb command line prompt.
During a jdb session, the currently executing thread stack can be dumped with a platform-specific key sequence:
Platform | Key Sequence |
---|---|
Microsoft Windows 95/NT | CONTROL-break |
Solaris | CONTROL-\ |
The most basic method for generating useful data from a Java application at runtime is to use the println method. This technique displays a text stream on the standard output. If the PJAE implementation is running on a device, then the device must be attached to a development system with a serial cable so that the standard output stream can be captured with a communications terminal program.
Similarly, the best way to get runtime information about a native method is to use printf() to format data for display on a terminal window or through a serial port.
Debugging native methods requires techniques that are different from those used for Java software. There are two basic approaches:
A native debugger used with the PJEE should be compatible with the symbol tables generated by the compiler used to build the PJEE. The Solaris version of the PJEE was built with the GNU C Compiler, version 2.7.3 and the Microsoft Windows 95/NT version was built with Microsoft Visual C++, version 5.0.
The PersonalJava Environment Software (PJES) includes a build environment for building binary executable versions of the PJAE like the PJEE. The PJES build environment has a mechanism for including native libraries in the list of object files that are statically linked with the PJAE binary executable. This procedure can be used to include native methods for applications that will be bundled with an implementation of the PJAE on a device. Debugging statically linked native code is much easier than debugging native code that is included in a shared library.
See the section Adding Object Files in the PersonalJava Porting Guide for a description of how to include object files in the PJES build environment.
Versions of the PersonalJava invocation tools that include symbol tables for debugging Java software with native debuggers like gdb(1) must be built from the PersonalJava source. The following Solaris-based procedure outlines the steps involved in using gdb to debug a simple Java application with a native method. The emphasis here is on the mechanics of debugging rather than special debugging techniques for different programming problems.
% setenv CLASSPATH .:PJEE-dir/lib/classes.zip % setenv LD_LIBRARY_PATH .:PJEE-dir/lib/sparc
% gdb PJEE-dir/bin/sparc/pjava_g
(gdb) tbreak main
(gdb) run HelloWorld
(gdb) break sysAddDLSegmentNote: sysAddDLSegment() is an internal VM function that dynamically links shared libraries for native methods. It is used here solely as a convenient reference for setting a break point after a shared library has been linked. This technique may not apply to other VM implementations.
(gdb) continue
(gdb) finish
(gdb) share
(gdb) clear sysAddDLSegment
(gdb) break HelloWorldImpl.c:Java_HelloWorld_greet
(gdb) continue
(gdb) step
gdb has several other commands that display source code, show a stack trace and examine data. These are described in Debugging with GDB.