Digging into Java debugger

Pavel Vasilev
2 min readOct 11, 2020

I think most of Java developers use debugger embedded into IntelliJ Idea or Eclipse. Have you ever wonder how this works? In this article we will debug simple Java application. First we try JDB, then we will write simple debugger using Java APIs. Here is code for application that we will debug.

Java debugger (JDB)

If you have installed JDK on your PC, you already have JDB, its located under $JAVA_HOME/bin folder. We can start our application using JDB or connect to already running application. I will show second approach, but before connecting we need start application in special way. Instead of standard command java HelloWorld, we will runjava -agentlib:jdwp=transport=dt_socket,server=y,suspend=n HelloWorld , to attach to our application we run jdb -attach <pid> Now we can inspect our HelloWorld app, add breakpoints, view debug information, evaluate expressions. If you know line for which you want to add breakpoint, you can use command similar to this stop at HelloWorld:5 , when app hits breakpoint you can view local variables with print i (app needs to be compiled with -g flag to preserve debug information), in order to resume application run cont , to clear breakpoint run clear HelloWorld:5

Java debugging interface (JDI)

JDK contain classes for working with debug interface, they are located under com.sun.jdi package, this classes are in $JAVA_HOME/lib/tools.jar

Main classes of this package are:

  • VirtualMachineManager
  • VirtualMachine
  • Connector
  • EventRequestManager
  • EventQueue

VirtualMachineManager manage connections to target VirtualMachine, EventRequestManager handle registration of user requests(create breakpoint, add watch for variable, listen for method enter or exit), Connector represents connection to target VirtualMachine, EventQueue is used to process events that were triggered by target VirtualMachine.

In the example below, we connect to java process with ProcessAttachingConnector specifying its pid, then registering breakpoint for class HelloWorld line 6, after it we listen for incoming events. If we hit breakpoint, we get main thread reference, get first stack frame (because we only in main function) and lookup variable value, then resume remote process.

Conclusion

We looked at high level APIs and tools for debugging Java apps. Hope now you understand how debug tab in your IDE is implemented.

--

--