Connection and Invocation
Details
Contents
Transports
Connectors
Sun VM Invocation Options
Debugging Plug-in Applets
Connecting with JDB
Service Provider
Interfaces
Transports
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 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/rmiregistry \
-J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar
- start the 'debug-server' on the remote machine, specifying the
process or corefile to be debugged:
${JAVA_HOME}/bin/java \
-classpath ${JAVA_HOME}/lib/sa-jdi.jar \
sun.jvm.hotspot.jdi.SADebugServer \
<pid> \
[uniqueID]
or
${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:
- -agentlib:jdwp=<sub-options>
- 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:
- -Xdebug
- Enables debugging
- -Xrunjdwp:<sub-options>
- 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:
-agentlib:jdwp=<name1>[=<value1>],<name2>[=<value2>]...
or
-Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...
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. |
Examples
-
-agentlib:jdwp=transport=dt_socket,server=y,address=8000
- 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.
-
-agentlib:jdwp=transport=dt_socket,server=y,address=localhost:8000,timeout=5000
- 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.
-
-agentlib:jdwp=transport=dt_shmem,server=y,suspend=n
- 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.
-
-agentlib:jdwp=transport=dt_socket,address=myhost:8000
- Attach to a running debugger application via socket on host
myhost at port 8000. Suspend this VM before the main class
loads.
-
-agentlib:jdwp=transport=dt_shmem,address=mysharedmemory
- Attach to a running debugger application via shared memory at
transport address "mysharedmemory". Suspend this VM before
the main class loads.
-
-agentlib:jdwp=transport=dt_socket,server=y,address=8000,onthrow=java.io.IOException,launch=/usr/local/bin/debugstub
- 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.
-
-agentlib:jdwp=transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe
- 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.
jdb -connect
com.sun.jdi.SocketAttach:hostname=myhost,port=8000
jdb -connect "com.sun.jdi.CommandLineLaunch:main=Hello 1 2
3"
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.
Further information on the service provider interfaces can be in
the document JavaTM Platform Debugger Architecture - Service
Provider Interfaces.