JDEbug User's Guide

About JDEbug

JDEbug is a Java debugger that comes with the Java Development Environment for Emacs. It permits you to execute a Java program step-by-step and display and modify the program's internal state. JDEbug features include:

JDEbug Requirements

JDEBug requires a virtual machine that conforms to the specifications of the Java Debug Platform Architecture (JPDA) defined by Sun Microsystems. The vm shipped with Sun's Java SDK 1.3 for Windows and Solaris conform to the JPDA specification.

Note JPDA does not run reliably when the JDK 1.3 vm is operating in HotSpot mode. For example, JPDA sometimes fails to stop the debuggee process at breakpoints and has trouble getting the this object of the method in which the debuggee process is currently suspended. Sun's JPDA development team is aware of this problem and is working to provide a solution. Meanwhile, you can work around the problem by running the vm in "classic" mode. To do this, toggle the JDE variable jde-run-classic-mode-vm on.

In addition, JPDA backward compatibility packages are available for Sun's Java SDK 1.2.2 for Windows, Linux, and Solaris platforms, respectively. The SDK 1.2.2 for Linux includes the JPDA components. You must download the JPDA compatibility packages for the Windows and Solaris versions of SDK 1.2.2 from the JPDA website.

Note. The JDE also provides a source-level debugging interface to jdb, the command-line debugger that comes with all version's of Sun's Java SDK. You can use this interface to debug applications running on Sun vm's that do not support the JPDA specification. See Debugging with jdb for more information.

Setting Up JDEbug

Setting up JDEbug entails the following tasks:

The following sections explain how to perform these tasks.

Selecting JDEbug As Your Debugger

The JDE is configured by default to serve as a source-level debugger front-end to jdb, the command-line debugger that comes with Sun's Java SDK. To use JDEbug, you must set the value of the JDE customization variable jde-db-debugger to specify JDEBug. To do this,

  1. Type M-x customize-variable.

    Emacs isplays a customization buffer for jde-db-debugger.

  2. Click the radio button next to JDEbug.
  3. Click the State button and select Save for Future Sessions if you want to enable JDEbug for all projects or Set for Current Session if you want to enable JDEbug only for the current project, in which case you should save the setting in your project file.

Select any Java source buffer. The JDEBug menu should appear in the Emacs menubar.

Specifying the Location of the JPDA Libraries

JDEbug uses class and native code libraries that implement the JPDA specification. You must tell JDEbug where these support libraries live. The way to do this depends on the platform and version of the Sun Java SDK you are using.

Sun Java SDK 1.3 for Windows and Solaris

To specify the location of the JPDA support libraries for Sun's Java SDK 1.3:

  1. Select JDEbug->Preferences to display a customization buffer for JDEbug variables.


  2. Customize the entries for the following variables (see Customizing the JDE).
    Variable Set to...
    jde-bug-vm-includes-jpda-p On.
    jde-bug-jdk-directory Directory that contains the Java SDK 1.3. Suppose that the SDK is installed in the directory d:\jdk-1.3 on your system. Then you would set jde-bug-jdk-directory to d:\jdk-1.3.

Java SDK 1.2.2 for Windows, Linux, and Solaris

To specify the location of the JPDA support libraries for Sun's Java SDK 1.2.2:

  1. Select JDEbug->Preferences to display a customization buffer for JDEbug variables.


  2. Customize the entries for the following variables (see Customizing the JDE).
    Variable Set to...
    jde-bug-vm-includes-jpda-p Off.
    jde-bug-jpda-directory Directory that contains the JPDA package.

  3. Include the directory containing the JDPA native code libraries (e.g., jdwp.dll) in your system's library load path. The libraries live in different places, depending on the platform:


Specifying the Location of Source Files

To display the current location in the program you are debugging, JDEBug needs to be able to find the source files from which the program was compile. The JDEbug looks for the files in the source directories specified by the JDE variable jde-db-source-directories. Therefore, before starting a debugging session, you must ensure that this variable specifies all the source files that you may step through during the debugging session.

To set this variable:

  1. Type M-x customize-variable jde-db-source-directories

    Emacs displays the customization buffer for the variable.

  2. Edit the buffer to reflect the location of Java source files on your system.

    Note You should specify only the root directory of the top-level packages you may need to visit during a debugging session. For example, suppose the top-level packages for your current project reside in c:/java/projects/prj1/src and the Java SDK source lives in c:/java/jdk1.3/src. Then the customization buffer should appear as follows:

    jde-db-source-directories: [Hide]
    [INS] [DEL] Path: c:/java/projects/prj1/src
    [INS] [DEL] Path: c:/java/jdk1.3/src/
    [INS]
    [State]: you have edited the value as text, but you have not set the option.
    List of source directory paths. [More]
    Parent groups: [jde-project]

  3. Save the setting in your .emacs or .prj file (see Customizing the JDE).

Starting the Debugger

To start the debugger, select Processes->Start Debugger from the JDEbug menu. This command simply starts the debugger. To debug an application, you must either

Setting the Debug Session Working Directory

The debugger launches all processes from the directory in which it was started. This directory is known as the debug session working directory. By default, the debug session working directory is the directory of the source buffer that was active when you started the debugger. To specify another directory as the working directory for the current debugger session, set the variable jde-run-working-directory to the directory's path.

Note You cannot set the working directory on a per-process basis. All processes launched during the current session start in the debug session working directory.

Exiting the Debugger

To exit the debugger, select Exit Debugger from the JDEbug menu. The JDE terminates any processes (vm's) launched by the debugger and terminates the debugger process (vm) itself.

Note Exiting Emacs itself without first exiting the debugger orphans the debugger vm and any processes (vm's) launched by the debugger. Thus, it is important to exit JDEbug before exiting Emacs.

Launching a Process

In this guide, a process refers to a running instance of an application. JDEBug provides two commands for launching processes.

Issuing either of these commands cause JDEBug to split your Emacs frame into three windows.

.

The top window displays a Java source buffer. The source buffer displays either the source buffer where you launched the application or, if you used the Debug App command, the source buffer containing the first breakpoint hit after the application was launched.

The middle window displays the application process's local variables buffer. The buffer displays the local variables in the stack frame of the initial breakpoint hit when you launched the application. If your application does not hit a breakpoint at startup, the local variables buffer displays nothing.

The bottom window contains the debugger messages buffer for the process that was just launched. This buffer displays messages regarding the status of the process being debugged.

At this point, if the process was launched successfully and did not run to completion, you can begin debugging your application.

See Also

Working with Process Buffers

Debugging Multiple Processes

Attaching a Process

JDEbug allows you to attach the debugger to an existing local or remote process that was launched outside the current debugger session. This is useful for debugging servlets and processes that were launched by another application, for example, servelets.

NoteYou can use JDE->Run App to launch the third-party application. Use the JDE variables jde-run-executable and jde-run-executable-args to cause the Run App command to run a non-Java app that launches a Java subprocess to be debugged.

You can attach the debugger to an existing process via:

The shared memory option is available only on Windows. It is much faster and thus is preferable. In either case the existing process must have been started with the appropriate debug options.

Attaching via a Socket

To attach via a socket:

  1. Launch the debuggee process with the following vm command line arguments:
  2. Execute JDEbug->Processes->Start Debugger to start the debugger (if necessary).
  3. Execute JDEbug->Processes->Attach Process->Local Host or Remote Host to attach the debugger to a local or remote process, respectively.

    In the first case, the JDE prompts you to enter the socket address that you specified in step 1. In the second case, the JDE also prompts you to enter the name of the host on which the remote process is running.

Attaching via Shared Memory

To attach via shared memory:

  1. Launch the debuggee process with the following vm command line arguments:
  2. Execute JDEbug->Processes->Start Debugger to start the debugger (if necessary).
  3. Execute JDEbug->Processes->Attach Process->Via Shared Memory to attach the debugger to the process started in step 1.

    The JDE prompts you to enter the NAME you specified in step 1.

Note You can attach/detach from a running process as many times as you want during a session.

Listening for a Process

JDEbug's listen mode enables a process that is launched independently of JDEbug to attach itself to JDEbug when the independently launched process starts. Listen mode is useful for debugging the startup code of processes that JDEbug cannot launch itself. Examples of such processes are processes launched by other applications such as a web server or a hybrid C/Java application where a C main program uses an embedded vm to to run Java processes.

NoteYou can use JDE->Run App to launch the third-party application. Use the JDE variables jde-run-executable and jde-run-executable-args to cause the Run App command to run a non-Java app that launches a Java subprocess to be debugged.

When in listen mode, JDEbug acts as a debug server, listening for debug service requests from independently launched processes. You can cause JDEbug to use either a socket or a shared memory channel (Windows only) to communicate with processes requesting debug services. You must use the socket option, if you want to debug a process running on a remote machine or you are running the debugger under Unix, On Windows, you can use either option to debug processes running on the local machine. However, the shared memory option typically results in faster response to debug commands.

Listening on a Socket

  1. Execute JDEbug->Processes->Start Debugger to start the debugger (if necessary).
  2. Select JDEbug->Processes->Listen on->Socket to put JDEbug in listen mode.

    This command causes the debugger to listen on the socket specified by the JDE variable jde-bug-server-socket. The default value is 2112. You can customize this variable to specify any socket address you choose or to cause JDEbug to prompt you to enter an address. Whatever address you choose, you must enter the same address as an argument of the command that launches the process to be debugged.

  3. Launch the debuggee process with the command line arguments required to attach to JDEbug.

    See Listen Mode VM Arguments for more information.

When you launch a Java application with listen mode arguments, the vm halts before running the app's main method and attempts to connect with JDEbug. Once the connection is made, JDEbug is in complete control of the app. For example, the app won't run until the debugger issues a continue command. This means you can set breakpoints in the debuggee app's startup code.

Listening on a Shared Memory Channel

Note This option is available only if both the debugger and the debuggee process are running under Windows on the same machine.

  1. Execute JDEbug->Processes->Start Debugger to start the debugger (if necessary).
  2. Select JDEbug->Processes->Listen on->Shared Memory to put JDEbug in listen mode.

    This command causes the debugger to listen on the shared memory channel specified by the JDE variable jde-bug-server-shmem-name. The default value is jdebug. You can customize this variable to specify any name you choose or to cause JDEbug to prompt you to enter a name. Whatever name you choose, you must enter the same name as an argument of the command that launches the process to be debugged.

  3. Launch the debuggee process with the command line arguments required to attach to JDEbug.

    See Listen Mode VM Arguments for more information.

When you launch a Java application with listen mode arguments, the vm halts before running the app's main method and attempts to connect with JDEbug. Once the connection is made, JDEbug is in complete control of the app. For example, the app won't run until the debugger issues a continue command. This means you can set breakpoints in the debuggee app's startup code.

Listen Mode VM Arguments

Use the following vm arguments when launching a process to be debugged in listen mode.

Here is an example of a typical command line to launch a debuggee client, using JDK1.3:

java -classpath d:/myapp/myapp.jar -Xdebug -Xnoagent
-Xrunjdwp:transport=dt_socket,address=jdebug,server=n,suspend=y
-Xbootclasspath:e:/jdk1.3/jre/lib/rt.jar;e:/jdk1.3/lib/tools.jar
com.myorg.myapp.Main

Use the JDE variable jde-run-option-vm-args to specify vm arguments when launching an application from the JDE.

Debugging Multiple Processes

JDEbug allows you to launch and debug multiple debuggee processes during the same debugger session. JDEbug assigns a numeric identification number to each process that it launches or attaches in either attach or listen mode. All JDEbug commands, except those that launch or attach processes, implicitly address a process called the target process. When you launch or attach a process, that process becomes the target process until you specify a different process as the target process.

To specify a different process as the target process, select JDEbug->Processes->Set Target Process, then enter the ID of the target process at the prompt.

Working with Process Buffers

JDEbug creates a set of buffers for each process that you debug during a debugger session.

Buffer Description
Process Displays status messages from the debugger.
Local Variables Displays the values of local variables and the fields of the object on which the current method was invoked (the implicit this object).
Command Line Interface (CLI) Allows you to interact with a process that has a command line interface (CLI). The JDE sends lines that you type in this buffer to the process's standard input. The process's standard output also appears in this buffer.
Threads Displays the current status of all threads created by the debuggee process. The JDEbug->Display->Threads command creates this buffer.
*JDEbug* Displays the low-level commands sent by Emacs to the Java backend of JDEbug, the backend's responses to those commands, and events detected by the backend. You should always include a copy of this buffer in bug reports as it represents a complete record of your debugs session.

Displaying the Buffers

JDEbug displays the Process and Locals buffer in windows in the current frame when you launch or attach a process.

Deleting Buffers

JDEbug does not delete the buffers belonging to a process when it dies. To delete all the buffers created for dead processes, select JDEbug->Processes->Remove Dead Processes. This command removes all traces of the dead processes from the Emacs environment.