Configure Your JVM For Use With a Remote Debugger


As I’ve pointed out in several previous articles, I like the jdb command line debugger that is available with the Sun JDK. This debugger can actually be used with any spec-compliant JVM. The JPDA specification defines the interfaces and services that are used by remote debuggers and profiles. The JVMDI specification defines the debugging interfaces that JVM must implement. The JDWP specification defines the protocol used for JVM<->Debugger communication. The JDI specification defines the interfaces that a debugger uses. More information can be found in [2] & [3]. VM internals involved in allowing remote debuggers to function is beyond the scope of this article, but is still an interesting topic.

In order to access a JVM with a remote debugger, the remote debugging API must be enabled. Use the following command line parameters:

-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5002

The “-Xdebug” parameter enables remote debugging[4]. The “-Xrunjdwp” parameter “loads in-process debugging libraries and specifies the kind of connection to be made.”[1] The parameters specified above do the following:

transport=dt_socket — Use a TCP socket for debugger->JVM communication. dt_shmem is another option that uses shared memory.
server=y — this is the JVM that is to be debugged. Listen at the given address for incoming connections from debuggers.
suspend=n — Do NOT suspend Java threads until a debugger attaches. if “=y”, execution of main() doesn’t commence until a debugger attaches.
address=5002 — Endpoint that the server should listen on. Defaults to localhost.

Once you have a JVM running with these options. You should be able to use just about any debugger. If there are any firewalls between where the debugger is being run and where the JVM is being run, you will obviously have a problem.

I generally use the following options to attach jdb to a running JVM(assuming the previous java arguments being used on the debuggee JVM):

jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=5002

All of the debugger commands are documented here. It’s also possible to start a Java program from the debugger. The link explains how to do that.

There are a couple of articles on that gives examples of using jdb:

* Thread dumps
* Detecting deadlock conditions
* Thread dumps from a JVM running as a Windows Service