All About HackingBlackhat Hacking ToolsFree CoursesHacking

Debugging Java Applications Using JDB 2023

In this article we will review about Debugging Java Applications Using JDB.

Introduction[Debugging Java Applications ]

This article guides the reader through debugging Java programs using a command-line tool called JDB. Although this article does not touch on Android concepts, it is a prerequisite to understanding the next article in the series, “Using Debug Android Apps”.

What is JDB?

JDB is a Java debugger, a simple command line debugger for Java classes. It comes with a pre-installed JDK.

I’m using an Ubuntu machine for this article, so we can find JDB by going to the /usr/bin directory as shown below:

cd /usr/bin

ls | grep jdb

Note: If you are using a Windows machine, it will be available in the bin directory of the Java path. This article is written for an Ubuntu computer, but all the techniques here are almost the same, even on Windows.


In this article, instead of blindly typing JDB commands and watching the usage, we will take a sample Java application to understand how to use JDB commands based on the scenario. The whole idea is to understand JDB and its use in debugging Java programs.

Below is the sample code I took as an example:

Source code file name:

Generated class file: Debug.class

The code snippet shown above has two methods which are called from the Debug class main method and when we run it after compilation it shows the output as shown in the image below which is expected.

We compiled our Java program with the “–g” option to get some additional debugging information in the generated class file.

Starting JDB

To debug Java applications, there must be a communication channel between the JDB and the JVM because our Java program would be running inside the Java Virtual Machine.

There are several ways to connect JDB to JVM as shown below.

Method 1

In this method we can directly load our class file into JDB. JDB automatically starts the JVM and the connection is established.

Debug is the class file generated after compiling the source code.

Method 2

In this method, we first launch the JVM using the following command so that JVM will start listening on port 54321.

java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=54321 Debug

Then start JDB using the following command to connect to the JVM on port 54321.

jdb -attach 54321

This second method can also be used for remote debugging. We will use remote debugging in the next article to use debuggable Android apps. In this article, we will use method 1 to cover both flavors.

Related article:Ethical Hacking Interview Questions 2023

Starting with debugging

Let’s start debugging the sample Java application using method 1 by invoking the JVM directly with JDB. But to start the JVM we have to explicitly give the “run” command as shown in the following figure.

The above image shows that the JVM has started and the program has finished executing and the application has been terminated. To stop the flow and manually run each line, we need to set breakpoints before running the application.

We can set the breakpoints at the beginning of the method using the “stop in” command. We can do this as shown in the following image.

We can see that we have set a breakpoint in the main method which is in the Debug class. The type of the parameters is also specified.

Now we start the JVM and run the program to reach the breakpoint. We will use the “run” command as mentioned above.

As expected, a breakpoint was found and JDB also displays the next line to execute, which is:

System.out.println(“We are in the main method”);

To look at the source code around the current location, we can execute the “list” command as shown below.

To see all the breakpoints set, we can use the command “clear” as shown below.

As we set, it is showing the place where we set the breakpoint.

To see all the thread groups, we can run the command threadgoups.

As we can see, there are two thread groups available: “system” and “main”.

We can see all the thread, by running the command “threads” as shown below.

If you notice the image above, we have three threads in the system thread group and one thread named “main” in the main thread group in the running state. This is what we are going to debug in this article.

We can see information about all the classes loaded in the JVM using the “classes” command as shown below.

The above figure shows all the classes loaded in JVM currently (the output is truncated to save space).

To see more information about a particular class, we can use the following command.

class <classname>

The below screenshot shows specific details of our current class “Debug“.

Similarly, we can see the information about any class. As an example, let’s inspect The output looks as shown below.

To see the list of methods loaded, we can use the command “methods <classname>” as shown below.

The above commands are few important commands that one may need. Now let’s start looking at the program flow and see how JDB can help us in debugging the application.

To execute the next line which is System.out.println(“We are in the main method”); we can enter the command “next”.

As expected, execution completes and JDB shows the next line to execute, which is a call to the “test” method.

Here, if we enter the “next” command, it will complete the execution of the definition and control will return to the next line, which in our case is called the “passCheck” method. This is shown in the image below.

As explained, it has finished executing the test method definition and is now waiting to execute the next line passCheck(“srini0x00);

Now, if we want to get inside the method definition and control the flow inside the definition, we should run the “step” statement rather than “next”.

I restarted my program and now I give the command “stethep” on the same line as shown in the picture.

Now, we can run the “next” command to continue to the next line as shown below.

At this point, for some reason if we want to get out of the method definition, rather than executing the rest of the lines inside the definition, we can run the command “step up” as shown below.

As expected, it exited the definition and the control is now in the main method, waiting for the next line to be executed.

The next few lines will be interesting because we will see commands to display secret messages stored in variables. Before I go there, I’d like to explain one more interesting command called “where”.

The “where” command displays the current call stack. So let’s run it in the main method and look at the current call stack. Later we will run the same statement in the method definition to understand its functionality.

As we can see, we are currently inside the method Debug.main.

Let’s now, give a “step” command and get into the method definition and check the current call stack inside the method. This is shown in the following figures.

The above image shows the current location as “Debug.passCheck” and is called from “Debug.main”.

We are now inside the passCheck method. So let’s see if there are any interesting local variables containing any sensitive information. We can see all local variables using the “locals” command. (This does not work unless the code is compiled with the “-g” option).

As we can see, the call passed the password as an argument to the method definition and this is displayed. The above image only shows the method arguments as they are not yet assigned to the local variable declared in the definition. We can run the next line and see the value of the local variable “password”.

We can print the value of a particular variable using the print command as shown below.


This article explains the basics of JDB, the various JDB commands, and how to use them to debug Java applications. It also provided the necessary information to understand the next article in the series.


Leave a Reply

Your email address will not be published. Required fields are marked *