Skip to content
kherink edited this page Aug 21, 2014 · 1 revision

ZeroEffort JDWP Analyzer Project home page

Project Mission:

The main goal of this tool is to make it easier to analyze issues with a JVM or a debugger during a debugging session.

Project Description:

The ZeroEffort JDWP Analyzer is a GUI tool for monitoring JDWP packets during a Java debugging session. It can be used to help with the following tasks:

  • Track down problems with the debuggee VM
  • Track down problems with the debugger
  • Monitor the amount of traffic during debug session

It is compliant with Java 1.5 JDWP

Running standalone:

1. Run the JDWP Analyzer:

java -jar JDWPAnalyzer.jar inport outaddress indelay outdelay [log_dir]

inport = the port to which debugger connects

outaddress = the address (as host:port) on which the debuggee VM is waiting for debug connection. Only the port is required for localhost VMs.

indelay = amount of time in MS to wait before passing a packet to the debuggee VM

outdelay = amount of time in MS to wait before passing a packet to the debugger

log_dir = OPTIONAL log directory path for writing debugging session JDWP packets

2. Execute the remote VM in debug mode as a suspended server (in this example we use WTK) on the same port as the outaddress specified in the JDWP Analyzer:

WTK2.2/bin/emulator -classpath MobileApplication.jar -Xdebug -Xrunjdwp:transport=dt_socket,address=6666,server=y  -Xdescriptor:MobileApplication.jad

3. Open your favorite debugger and attach it via a socket connection to the inport specified for the JDWP analyzer. As soon as the analyzer recieves a connection from the debugger it will connect to the remove VM using the outaddress specified and keep track of the traffic.

To replay a debugging session from log:

java -jar JDWPAnalyzer.jar log_dir

log_dir = log directory path for replaying a debugging session

Running as an ant task from NetBeans:

The task can be used with the following attributes:

  • inport - specifies number of the port on which the jdwp analyzer will wait for debugger, if omitted then a free port is found and it's number is stored in the 'inportproperty' attribue
  • outaddress - specifies the host and port to which the jdwp analyzer will connect once it receives debugger connection (usually the address at which the remote VM is listening). An address is specified as "host:port" (without the quotes). For local addresses (where host is 'locahost'), just the port can be specified.
  • requestdelay - number of ms to delay before passing on packets from the debugger
  • responsedelay - number of ms to delay before passing on packets from the VM
  • inportproperty - name of the attribute in which the 'inport' value is stored once it is determined
  • logdir - OPTIONAL directory where the packet stream is logged, file called seq.log is created in the 'logdir' directory and all JDWP packets are logged in the file. To replay the debugging session start the JDWP analyzer manually with 'logdir' as the only argument.

The usual way of using the task is to either explicitly supply the 'inport' value or to supply the 'inportproperty' value and then retrieve the attribute from it, examples of this would be:

either:

    <parallel>
        <jdwpproxy inport="2222" outaddress="3333" logdir="c:\jdwp_log"/>
        <sequential>
            <sleep seconds="1"/>
            <debug port="2222"/>
        </sequential>
    </parallel>

or:

    <parallel>
        <jdwpproxy inportproperty="jpda.port" outaddress="3333" logdir="c:\jdwp_log"/>
        <sequential>
            <sleep seconds="1"/>
            <debug port="${jpda.port}"/>
        </sequential>
    </parallel>

Running as a task from within NetBeans has the advantage that it only requires one-time setup of the debugged project. Add the task and override the default netbeans debug target - for mobility I use this in the build.xml of project.

    <taskdef name="jdwpproxy" classname="com.cotopia.jdwpanalyzer.ant.JDWPTask" classpath="/path/to/JDWPAnalyzer.jar"/>
&lt;target name="debug" description="Debug project." depends="init,clean,jar"&gt;
    &lt;delete file="${preprocessed.dir}/.timestamp"/&gt;

    &lt;parallel&gt;
        &lt;!--start emulator in debug mode, notice that this task must set wtk.debug.port attribute 
            to the port number on which the emulator VM is listening for debugger connection. 
            for that reason the next parallel action starts after 5 seconds - to give the emulator
            enough time to start up --&gt;
        &lt;nb-run debug="true" debugsuspend="true" debugserver="true" debuggeraddressproperty="wtk.debug.port" platformtype="${platform.type}" 
            platformhome="${platform.home}" device="${platform.device}" jadfile="${dist.dir}/${dist.jad}" execmethod="${run.method}" 
            securitydomain="${evaluated.run.security.domain}" commandline="${platform.debugcommandline}"/&gt;
        &lt;sequential&gt;
            &lt;sleep seconds="5"/&gt;
            &lt;parallel&gt;
                &lt;!--
                    start the jdwp analyzer with 2 attributes:
                    'inportproperty' is the name of the attribute in which the task will store number 
                                     of the incomming port - the port to which the debugger connects
                    'outaddress'     is the host:port to which the jdwp analyzer will connect once it receives 
                                     a connection from the debugger, this port was determined by the nb-run task 
                                     above
                --&gt;
                &lt;jdwpproxy inportproperty="jpda.port" outaddress="${wtk.debug.port}"/&gt;
                &lt;sequential&gt;
                    &lt;!--give the jdwpproxy task above a little time to set up the value of the jpda.port--&gt;
                    &lt;sleep seconds="1"/&gt;
                    &lt;!--nbdebug task will read the jpda.port property and connect the debugger to the port it
                        specifies--&gt;
                    &lt;antcall target="nbdebug"/&gt;
                &lt;/sequential&gt;
            &lt;/parallel&gt;
        &lt;/sequential&gt;
    &lt;/parallel&gt;
&lt;/target&gt;