Now Reading
Degree-up your Java Debugging Expertise with on-demand Debugging

Degree-up your Java Debugging Expertise with on-demand Debugging

2023-10-03 04:27:16

Debugging is likely one of the commonest duties in software program growth, so one would assume that every one options of debuggers have ample protection in tutorials and guides. But there are three hidden gems of the Java Debugging (JDWP) agent that permit you to delay the beginning of the debugging session until

  • you gave orders through jcmd (onjcmd=y choice)
  • this system threw a particular exception (onthrow=<exception>)
  • this system threw an uncaught exception (onuncaught=y)

Earlier than I let you know extra concerning the particular choices, I wish to begin with the fundamentals of the right way to apply them:

Choice Utility

While you debug remotely in your IDE (IntelliJ in my case), the “Debug Configurations” dialog tells you which ones choices it’s best to go to your distant JVM:

Simply append extra choices by including them to the -agentlib choice, or by setting the _JAVA_JDWP_OPTIONS atmosphere variable, which is comma-appended to the choices.

All choices solely work accurately within the server mode (server=y) of the JDWP agent (droop=y or droop=n appear to exhibit the identical habits with onjcmd).

I’m now exhibiting you ways the three hidden gems work:

JCmd triggered debugging

There are sometimes instances the place the code that you simply wish to debug is executed later in your program’s run or after a particular subject seems. So don’t waste time working the debugging session from the beginning of your program, however use the onjcmd=y choice to inform the JDWP agent to attend with the debugging session until it’s triggered through jcmd:

 ➜ java "-agentlib:jdwp=transport=dt_socket,server=y,droop=y,tackle=*:5005,onjcmd=y" src/take a look at/java/OnThrowAndJCmd.java &
 ➜ echo $! # get pid
 # wait a while after which begin debugging on demand
 ➜ jcmd $! VM.start_java_debugging
jcmd 97145 VM.start_java_debugging
97145:
Debugging has been began.
Transport : dt_socket
Handle : *:5005

jps is your buddy if you wish to discover the method id of an already working JVM.

I created a pattern class in my java-dbg repository on GitHub with a small sample program for this text. To make use of JCmd triggered with our IDE, we first need to create a distant debug configuration (see earlier part); we are able to then begin the pattern program within the shell and set off the beginning of the debugging session. Then, we begin the distant debug configuration within the IDE and debug our program:

The same characteristic long existed in the SAPJVM. In 2019 Christoph Langer from SAP determined to add it to the OpenJDK, the place it was carried out in JDK 12 and has been there ever since. It is likely one of the many significant contributions of the SapMachine staff.

Disclaimer: I’m a part of this magnificent staff, albeit not in 2019.

Exception triggered debugging

Far older than jcmd triggered are exception-triggered debugging classes. There are two varieties:

  1. The throwing of a particular exception (byte-code or regular title, interior courses with $) can begin the debugging session through the use of onthrow=<exception>. That is particularly good if you wish to debug the reason for this particular exception. This characteristic can simply be utilized in mixture together with your favourite IDE.
  2. The existence of an uncaught exception can set off the beginning of a debugging session through the use of onuncaught=y. The debugging context is your outermost fundamental technique, however it’s nonetheless useful if you wish to examine the exception or the state of your utility. An issue is that you simply can’t use the debuggers from IntelliJ or NetBeans to discover the context; it’s important to use the command line debugger jdb as a substitute.

On account of historic causes, you even have to provide a command that’s executed when the debugging session begins through the launch choice, however setting it to exit works simply high-quality.

Utilizing each set off varieties is much like the JCmd triggered debugging:

 ➜ java "-agentlib:jdwp=transport=dt_socket,server=y,droop=y,tackle=*:5005,onthrow=Ex,launch=exit" src/take a look at/java/OnThrowAndJCmd.java
# or
 ➜ java "-agentlib:jdwp=transport=dt_socket,server=y,droop=y,tackle=*:5005,onuncaught=y,launch=exit" src/take a look at/java/OnThrowAndJCmd.java

In case you’re okay with utilizing jdb, you too can use the launch choice to name a script that begins jdb in a brand new tmux session, in our case, tmux_jdb.sh:

#!/bin/sh
tmux new-session -d -s jdb -- jdb -attach $2

We run our utility utilizing the JDWP agent with the onthrow=Ex,launch=sh tmux_jdb.sh choice to begin the jdb the primary time the Ex exception is thrown and fix to the tmux session:

➜ java "-agentlib:jdwp=transport=dt_socket,server=y,droop=y,tackle=*:5005,onthrow=Ex,launch=sh tmux_jdb.sh" src/take a look at/java/OnThrowAndJCmd.java
# in one other console after the exception is thrown
➜ tmux connect -t jdb

The place we are able to discover the present state of the appliance:

See Also

Debugging a particular exception has by no means been simpler.

jdb and the JDWP on* choices aren’t as broadly used as graphical debuggers, so that you would possibly nonetheless discover some bugs. I don’t know whether or not the stack hint within the second-to-last screenshot is a bug. Be at liberty to remark if you already know the reply.

The best way to uncover these options

You may both be like me and simply drop into the JDK supply and look into the debugInit.c file, the official documentation, otherwise you use assist choice, which prints the next with JDK 21:

➜ java "-agentlib:jdwp=assist"
               Java Debugger JDWP Agent Library
               --------------------------------

  (See the "VM Invocation Choices" part of the JPDA
   "Connection and Invocation Particulars" doc for extra info.)

jdwp utilization: java -agentlib:jdwp=[help]|[<option>=<value>, ...]

Choice Identify and Worth            Description                       Default
---------------------            -----------                       -------
droop=y|n                      wait on startup?                  y
transport=<title>                 transport spec                    none
tackle=<hear/connect tackle>  transport spec                    ""
server=y|n                       hear for debugger?              n
launch=<command line>            run debugger on occasion             none
onthrow=<exception title>         debug on throw                    none
onuncaught=y|n                   debug on any uncaught?            n
onjcmd=y|n                       begin debug through jcmd?             n
timeout=<timeout worth>          for hear/connect in milliseconds n
includevirtualthreads=y|n        Record of all threads contains digital threads in addition to platform threads.
                                                                   n
mutf8=y|n                        output modified utf-8             n
quiet=y|n                        management over terminal messages    n

Out of date Choices
----------------
strict=y|n
stdalloc=y|n

Examples
--------
  - Utilizing sockets connect with a debugger at a particular tackle:
    java -agentlib:jdwp=transport=dt_socket,tackle=localhost:8000 ...
  - Utilizing sockets hear for a debugger to connect:
    java -agentlib:jdwp=transport=dt_socket,server=y,droop=y ...

Notes
-----
  - A timeout worth of 0 (the default) isn't any timeout.

Warnings
--------
  - The older -Xrunjdwp interface can nonetheless be used, however will likely be eliminated in
    a future launch, for instance:
        java -Xrunjdwp:[help]|[<option>=<value>, ...]

After all, this solely offers you a look on the choices, so studying the supply code nonetheless revealed a lot of what I had earlier than.

Conclusion

Hidden gems are in every single place within the Java ecosystem, even in broadly used instruments like debugging brokers. Particularly onthrow and onjcmd can enhance the efficiency of on-demand debugging, as this permits us to set off the beginning of the debugging session from outdoors the debugger.

I hope you’ll be able to apply your newly gained data the following time you could have a fancy downside to debug. Nonetheless inquisitive about debugging? Come again subsequent week for one more weblog publish.

This text is a part of my work within the SapMachine staff at SAP, making profiling and debugging simpler for everybody. Due to Thomas Darimont, with whom I found the hidden options whereas getting ready for my talks on Java Debugging. I wrote this text on the practice to Devoxx Belgium.

Source Link

What's Your Reaction?
Excited
0
Happy
0
In Love
0
Not Sure
0
Silly
0
View Comments (0)

Leave a Reply

Your email address will not be published.

2022 Blinking Robots.
WordPress by Doejo

Scroll To Top