A JPDA Transport is a method of communication between a debugger and
the virtual machine that is being debugged (hereafter the target VM).
The communication is connection oriented - one side acts as a server, listening
for a connection. The other side acts as a client and connects to the server.
JPDA allows either the debugger application or the target VM to act as the
server. Transport implementations can allow communications between processes
running on a single machine, on different machines, or either. When establishing
a connection a transport addresses is used to identify the end-point of
the connection. The format of a transport address depends on the type of
transport.
Within JPDA the debugger application uses the Java Debug Interface (JDI)
interface and the Connector abstraction to establish
a connection to the target VM. The Connector used by the debugger application
encapsulates the transport. On the target VM an agent supporting the
JavaTM Debug Wire Protocol is used to
communicate with the debugger. This agent (which may be built into the target
VM or loaded from a runtime library) encapsulates the transport to communicate
with the debugger.
Sun ships two transport implementations with the reference implementation:
A socket transport based on TCP/IP, and a shared memory transport. The
specifications do not require any specific transport implementation to exist.
In addition to transports provided with the implementation the architecture
includes service provider interfaces to allow additional transports
be developed and deployed.
Socket Transport
The JPDA reference implementation provides a socket transport for the
Solaris, Linux, and Microsoft Windows platforms. With the socket
transport, the debugger application and the target VM can reside either on
the same machine or on different machines. The socket transport uses a
single stream TCP/IP connection between the debugger application and
the target VM. Both IPv4 and IPv6 are supported on the JDI side of the
socket transport. The current implementation on the target VM side
only supports IPv4, but this could change in a future release so that
both IPv4 and IPv6 are supported.
Command and reply packets are written to the stream in accordance
with the
JDWP specification
using the
JDWP Transport Interface.
Since many small packets can be sent over JDWP, the TCP_NO_DELAY socket
option can improve performance in some socket implementations by avoiding delays
that could occur if the socket implementation buffers small packets before sending them.
Sockets are closed gracefully so that unsent data is sent if possible.
The socket transport is identified through a unique string, dt_socket.
This name can be used to select the socket transport when invoking the target VM. Within the debugger application
a corresponding Connector is used which encapsulates the socket transport.
In contexts where a client is attaching to a server, socket transport addresses
have the format "<name>:<port>" where <name>
is the host name and <port> is the socket port number
at which it attaches or listens. In contexts where a server is waiting for
a client to attach, the address consists of the port number alone (the host
name is implicit).
Shared Memory Transport
In addition to the socket transport, the JPDA reference implementation provides
a shared memory transport on the Microsoft Windows platform. The shared
memory transport uses a shared memory region to exchange
JDWP packets between the debugger application and the target VM. With the shared
memory transport, the debugger application and target VM must reside on the
same machine.
The shared memory transport is identified through a unique
string, dt_shmem. This name can be used to select the socket transport
when invoking the target VM. Within the debugger application
a corresponding Connector is used which encapsulates the shared memory transport.
Shared memory transport addresses are simply names that can be used as
Microsoft Windows file-mapping object names. The name string can consist of
any combination of characters, excluding the backslash.
Connectors
A connector is a JDI abstraction that is used in establishing a
connection between a debugger application (written to the JDI) and a target
VM. Different JDI implementations are free to provide different connector
implementations to match the transports and VMs they support. The connector
interfaces are very general, to allow JDI to be used with varying connector
implementations. Connectors are configured through a set of name/value
pairs. Specific connectors accept different name/value pairs.
A good JDI client application will allow users to choose and configure
any connector that may be present, but it can be beneficial to incorporate
knowledge of specific connectors into the debugger to make their configuration
a more pleasant user experience. The example JDB implementation
provided with the JPDA illustrates this approach.
The JDI reference implementations provides several connectors which map to the available transport types and the modes of connection (launching, listening, and attaching). These connectors are described in the following sections. A List containing these connectors is returned by JDI method VirtualMachineManager.allConnectors(). In addition, each attaching, listening, and launching connector is contained in the lists returned by the corresponding VirtualMachineManager methods attachingConnectors(), listeningConnectors(), and launchingConnectors().
Sun Command Line Launching Connector
This connector can be used by a debugger application to launch a Sun VM
or any other VM which supports the same invocation options
with respect to debugging. The details of launching the VM and specifying
the necessary debug options are handled by the connector. The underlying
transport used by this connector depends on the platform. On Microsoft Windows,
the shared memory transport is used. On Solaris and Linux
the socket transport is used.
This connector is uniquely identified by the name
"com.sun.jdi.CommandLineLaunch".
Sun Command Line Launching Connector Arguments
name
required?
default value
description
home
no
current java.home property value
Location of the Java 2 Runtime Environment used to invoke the Target
VM.
options
no
""
Options, in addition to the standard debugging options,
with which to invoke the VM.
main
yes
""
The debugged application's main class and command line arguments.
suspend
no
true
True if the target VM is to be suspended immediately before the main
class is loaded; false otherwise.
quote
yes
"\""
The character used to combine space-delimited text on the command line.
vmexec
yes
"java"
The VM launcher executable. This can be changed to javaw or to java_g
for debugging, if that launcher is available.
Raw Command Line Launching Connector
This connector can be used by a debugger application to launch any VM.
The entire command line must be specified and it is not edited in any way.
The details of launching the VM with the given command line are handled
by the connector. The underlying transport used by this connector depends
on the platform. On Microsoft Windows, the shared memory transport is used.
On the Solaris operating environment, the socket transport is used.
This connector is uniquely identified by the name "com.sun.jdi.RawCommandLineLaunch".
Raw Command Line Launching Connector Arguments
name
required?
default value
description
command
yes
""
Full command line to invoke the target VM with the application to be
debugged..
address
yes
""
Transport address at which to listen for
the newly launched target VM to connect. This value is typically part of
the raw command argument as well, but this is not required if the target
VM has some other means of determining the transport address to which it
should connect.
quote
yes
"\""
The character used to combine space-delimited text on the command line.
Socket Attaching Connector
This connector can be used by a debugger application to attach to a currently
running target VM through the socket transport.. The target VM must have
been invoked with options consistent with this connector's arguments described
in the table below. For Sun VMs, the necessary options are described below.
This connector is uniquely identified by the name "com.sun.jdi.SocketAttach".
Socket Attaching Connector Arguments
name
required?
default value
description
hostname
no
local host name
Name of host machine to connect to.
port
yes
""
Port number on the host machine to connect to.
timeout
no
""
The timeout, in milliseconds, to use when attaching to the target VM.
Shared Memory Attaching Connector
This connector can be used by a debugger application to attach to a currently
running target VM through the shared memory transport. It is available
only on the Microsoft Windows platform. The target VM must have been invoked with options
consistent with this connectors arguments described in the table below.
For Sun VMs, the necessary options are described below.
This connector is uniquely identified by the name "com.sun.jdi.SharedMemoryAttach".
Shared Memory Attaching Connector Arguments
name
required?
default value
description
name
yes
""
The shared memory transport address at which
the target VM is listening..
timeout
no
""
The timeout, in milliseconds, to use when attaching to the target VM
Socket Listening Connector
This connector can be used by a debugger application to accept a connection
from a separately invoked target VM through the socket transport.. The
target VM must be invoked with options consistent with this connector's
arguments described in the table below. For Sun VMs, the necessary options
are described below.
This connector can accept connections from multiple target VMs.
This connector is uniquely identified by the name "com.sun.jdi.SocketListen".
Socket Listening Connector Arguments
name
required?
default value
description
port
no
Ephemeral port number (port assigned by the TCP/IP stack)
Port number at which to listen for a connection..
localAddress
no
All addresses assigned to the host
An IP address assigned to the host
timeout
no
""
The timeout, in milliseconds, to use while waiting for the target VM to connect
Shared Memory Listening Connector
This connector can be used by a debugger application to accept a connection
from a separately invoked target VM through the shared memory transport. It
is available only on the Microsoft Windows platform. The target VM must be
invoked with options consistent with this connector's arguments described in
the table below. For Sun VMs, the necessary options are described
below.
This connector can accept connections from multiple target VMs.
This connector is uniquely identified by the name "com.sun.jdi.SharedMemoryListen".
Shared Memory Listening Connector Arguments
name
required?
default value
description
name
yes
""
A shared memory transport address at which
to listen for the target VM connection.
timeout
no
""
The timeout, in milliseconds, to use while waiting for the target VM to connect
Process Attaching Connector
This connector can be used by a debugger application to attach to a currently running target VM
that was started with the "server=y" debugging sub-option described below.
The target VM must be Java SE 6 or newer.
The Process Attaching Connector does not have an associated transport. Instead,
the transport is determined dynamically when an attach actually occurs. Because of this,
the transport().name() method for this connector returns "local".
This connector is uniquely identified by the name "com.sun.jdi.ProcessAttach".
Process Attaching Connector Arguments
name
required?
default value
description
pid
yes
""
The Process ID of a process to be debugged.
timeout
no
""
The timeout, in milliseconds, to use when attaching to the target VM.
SA Core Attaching Connector
This connector can be used by a debugger application to debug a core file.
It is not available on the Microsoft Windows platforms nor on the Linux
Itanium platform.
It is possible that the core file is corrupted to the extent
that not all available debugging operations can be performed on it.
The VirtualMachine object returned by this connector's attach() method is
'read-only'. This means that the method:
vm.canBeModified()
will return false, and that the JDI client should not call any JDI methods
that are defined to throw a VMCannotBeModifiedException in this case. The
word size (i.e. 32 bit/64 bit) and version (e.g. 5.0, 5.1) of the debugger's
Virtual Machine must be the same as that of the Virtual Machine of the process
from which the core file was produced.
This connector allows multiple debugging sessions on the same core file.
This connector is uniquely identified by the name "sun.jvm.hotspot.jdi.SACoreAttachingConnector".
SA Core Attaching Connector Arguments
name
required?
default value
description
core
no
core
Pathname of the core file to debug
javaExecutable
yes
""
Pathname of the Java executable that produced the core file.
SA PID Attaching Connector
This connector can be used by a debugger application to debug a process.
It is not available on the Microsoft Windows platforms nor on the Linux Itanium
platform.
It is possible that the process is corrupted to the extent
that not all available debugging operations can be performed on it.
The VirtualMachine object returned by this connector's attach() method is
'read-only'. This means that the method:
vm.canBeModified()
will return false, and that the JDI client should not call any JDI methods
that are defined to throw a VMCannotBeModifiedException in this case.
The process to be debugged need not have been started in debug mode(ie, with
-agentlib:jdwp or -Xrunjdwp). It is permissable for the process to
be hung. The word size (i.e. 32 bit/64 bit) and version (e.g. 5.0,
5.1) of the debugger and debuggee must be the same.
The process is suspended when this connector attaches and
resumed when this connector detaches. More than one
SAPIDAttachingConnector can not attach to a single process
simultaneously.
This connector is uniquely identified by the name "sun.jvm.hotspot.jdi.SAPIDAttachingConnector".
SA PID Attaching Connector Arguments
name
required?
default value
description
pid
yes
""
The Process ID of a process to be debugged.
SA Debug Server Attaching Connector
This connector can be used by a debugger application to debug a process or
core file on a machine other than the machine upon which the debugger is
running. It is not available on the Microsoft Windows platforms nor
on the Linux Itanium platform.
It is possible that the remote process/core file is corrupted to the extent
that not all available debugging operations can be performed on it.
The VirtualMachine object returned by this connector's attach() method is
'read-only'. This means that the method:
vm.canBeModified()
will return false, and that the JDI client should not call any JDI methods
that are defined to throw a VMCannotBeModifiedException in this case.
This connector uses RMI to communicate with a 'debug server' running on the
remote machine.
Before the attach() method on this connector is called, the debug
server must be started on the remote machine
and told what process or corefile is to be debugged. The following
must be done on the remote machine:
start the RMI registry with sa-jdi.jar in the classpath:
${JAVA_HOME}/bin/java \
-classpath ${JAVA_HOME}/lib/sa-jdi.jar \
sun.jvm.hotspot.jdi.SADebugServer \
<pathname to the java executable that produced the core file> \
<pathname of the corefile to debug> \
[uniqueID]
An alternative to the above two steps is to use the jsadebugd command to start
the RMI registry and debug-server on the remote machine.
'uniqueID' is an optional string. If more than one debug server is
to run at the same time on the same machine,
then each must have a different 'uniqueID' string.
In the above, JAVA_HOME must contain the pathname of a Java installation
that is the same bit size (i.e. 32 bit/64 bit) and the same version (e.g.
5.0, 5.1) as the version used by the debuggee. However the debugger
does not have to be the same bit size and version.
A process to be debugged need not have been started in debug mode(ie, with
-agentlib:jdwp or -Xrunjdwp). It is permissable for the process to
be hung. The process is suspended when the debug server attaches to it. When
a debug server attached to a process is killed (by ^C or other means), the
debuggee process will be resumed. Attaching more than one debug server to a
corefile is permitted, but only one debug server can be attached to a process.
This connector allows multiple debugging sessions connected to the same debug server.
This connector is uniquely identified by the name "sun.jvm.hotspot.jdi.SADebugServerAttachingConnector".
SA DebugServer Attaching Connector Arguments
name
required?
default value
description
debugServerName
yes
""
The IP address or name of the machine upon which the debug server
is running. If the machine contains multiple debug servers, this name
must be of the form
uniqueID@IPAddress
or
uniqueID@hostname
where 'uniqueID' is the string used to start the corresponding debug server.
Sun VM Invocation Options
This section describes the options necessary to invoke Sun VMs for debugging.
Sun's VM implementations require command line options to load the JDWP agent for debugging. From 5.0 onwards the -agentlib:jdwp option is used to load and specify options to the JDWP agent. For releases prior to 5.0, the -Xdebug and -Xrunjdwp options are used (the 5.0 implementation also supports the -Xdebug and -Xrunjdwp options but the newer -agentlib:jdwp option is preferable as the JDWP agent in 5.0 uses the JVM TI interface to the VM rather than the older JVMDI interface).
If your debugger application uses the JDI Sun Command
Line Launching Connector, the connector will use the -Xdebug and
-Xrunjdwp options as the Connector may be used to connect to a pre-5.0
target VM.
If the target VM is 5.0 or newer the -agentlib:jdwp option is
specified as follows:
Loads the JPDA reference implementation of JDWP. This library resides
in the target VM and uses JVM TI and JNI to interact with it. It uses a transport
and the JDWP protocol to communicate with a separate debugger application.
Specific sub-options are described below.
For releases prior to 5.0 the -Xdebug and -Xrunjdwp options
are used:
Loads the JPDA reference implementation of JDWP. This library resides
in the target VM and uses JVMDI and JNI to interact with it. It uses a transport
and the JDWP protocol to communicate with a separate debugger application.
Specific sub-options are described below.
-agentlib:jdwp and -Xrunjdwp sub-options
The -agentlib:jdwp and -Xrunjdwp option can be further qualified with sub-options. The sub-options
are specified as follows:
The table below describes the options that can be used:
-Xrunjdwp Sub-options
name
required?
default value
description
help
no
N/A
Prints a brief help message and exits the VM.
transport
yes
none
Name of the transport to use in connecting to debugger application.
server
no
"n"
If "y", listen for a debugger application to attach; otherwise, attach
to the debugger application at the specified address.
If "y" and no address is specified, choose a transport
address at which to listen for a debugger application, and print the
address to the standard output stream.
address
yes, if server=n no, otherwise
""
Transport address for the connection. If
server=n, attempt to attach to debugger application at this address. If
server=y, listen for a connection at this address.
timeout
no
""
If server=y specifies the timeout, in milliseconds, to wait for the debugger to attach. If server=n specifies the timeout, in milliseconds, to use when attaching to the debugger. Note that the timeout option may be ignored by some transport implementations.
launch
no
none
At completion of JDWP initialization, launch the process given in this
string. This option is used in combination with onthrow and/or
onuncaught
to provide "Just-In-Time debugging" in which a debugger process is launched
when a particular event occurs in this VM.
Note that the launched process is not started in its own window. In
most cases the launched process should be a small application which in
turns launches the debugger application in its own window.
The following strings are appended to the string given in this argument
(space-delimited). They can aid the launched debugger in establishing a
connection with this VM. The resulting string is executed.
The value of the transport sub-option.
The value of the address sub-option (or the generated address
if one is not given)
onthrow
no
none
Delay initialization of the JDWP library until an exception of the
given class is thrown in this VM. The exception class name must be package-qualified.Connection
establishment is included in JDWP initialization, so it will not begin
until the exception is thrown.
onuncaught
no
"n"
If "y", delay initialization of the JDWP library until an uncaught
exception is thrown in this VM. Connection establishment is included in
JDWP initialization, so it will not begin until the exception is thrown.
See the JDI specification for com.sun.jdi.ExceptionEvent for a definition
of uncaught exceptions.
suspend
no
"y"
If "y", VMStartEvent has a suspendPolicy of SUSPEND_ALL.
If "n", VMStartEvent has a suspendPolicy of SUSPEND_NONE.
Listen for a socket connection on port 8000. Suspend this VM before
main class loads (suspend=y by default). Once the debugger application connects,
it can send a JDWP command to resume the VM.
Listen for a socket connection on port 8000 on the loopback address only. Terminate if
the debugger does not attach within 5 seconds. Suspend this VM before
main class loads (suspend=y by default). Once the debugger application connects,
it can send a JDWP command to resume the VM.
Choose an available shared memory transport address and print it to
stdout. Listen for a shared memory connection at that address. Allow the
VM to begin executing before the debugger application attaches.
Wait for an instance of java.io.IOException to be thrown in this VM.
Suspend the VM (suspend=y by default). Listen for a socket connection on
port 8000. Execute the following: "/usr/local/bin/debugstub dt_socket
myhost:8000".This program can launch a debugger process in a separate
window which will attach to this VM and begin debugging it.
Wait for an uncaught exception to be thrown in this VM. Suspend the
VM. Select a shared memory transport address and listen for a connection
at that address. Execute the following: "d:\bin\debugstub.exe dt_shmem
<address>", where <address> is the selected shared
memory address.This program can launch a debugger process in
a separate window which will attach to this VM and begin debugging it.
Debugging Plug-in Applets
Beginning with version 1.2.2 of the Java Plug-in, applets running under
the Plug-in can be debugged. The required VM options described above
can be specified in the Plug-In control panel, under the "Basic" tab, in
the "Java Run-Time Parameters". The debug options under the "Advanced"
tab should not be used as they will enable the old sun.tools.debug
debug
support. In future versions of the Plug-in, these debug options will be
changed to use JPDA.
JDI launching connectors cannot be used to
debug Plug-in applets.
Connecting with JDB
The example implementation of JDB provided with the JPDA, provides an illustration
of the usage of JDI connectors. There are "shortcut" options to JDB which
assume the use of connectors known to it (that is, connectors present in
the reference implementation). It also provides a way to establish a general
connection using any connector. While JDB is hardly an example of a good
debugger interface, it does provide a simple example of connectors in use.
In JDB, the -attach option provides access to one of the attaching connectors
in the reference implementation (shared memory on Microsoft Windows,
sockets on the Solaris and Linux platforms).
The -listen option provides access to one of the listening connectors in
the reference implementation (shared memory on Microsoft Windows, sockets on
the Solaris and Linux platforms).
A class name and arguments specified directly on the command line provide
access to the Sun command line launching connector.
For example:
jdb -attach myhost:8000
is an easy way to attach to a target VM with the Socket Attaching Connector
(on the Solaris operating environment), and
jdb Hello 1 2 3
is an easy way to launch a target VM with the Sun Command Line Launching
Connector.
However, the -connect option is also provided by JDB to handle any connector
by taking an connector name and a set of arbitrary name/value argument
pairs. For example the command lines above have the following equivalents.
These command lines are more cumbersome than the ones above, but the
-connect option can be used with any connector. This kind of operation
is a primitive example of how a JDI debugger can deal with any kind of
connector while providing a simplified interface for dealing with common,
well-known connectors.
Service Provider Interfaces
JPDA includes service provider interfaces to allow the development and
deployment of connector and transport implementations. These service provider
interfaces allow debugger and other tool vendors develop new connector
implementations and provide addition transport mechanisms over and beyond the
socket and shared memory transport provided by Sun. The service provider interfaces
in JDI are specified in the
com.sun.jdi.connect.spi package.
In addition to the service provider interfaces in JDI the Sun implementation also
includes a transport library interface called the Java
TMDebug Wire Protocol Transport Interface. A transport
library is loaded by the JDWP agent in the target VM and is used to establish a
connection to the debugger and to transport JDWP packets between the debugger and the
VM.