Debugging OpenJDK 8 with NetBeans on Ubuntu

In this post we will learn how to download, compile and debug OpenJDK 8 using Ubuntu and NetBeans IDE.

Downloading and compiling OpenJDK 8

OpenJDK project uses Mercurial for source code versioning. To get sources using Mercurial follow instructions described in this SO answer.

To get OpenJDK sources using Git, we need to clone OpenJDK repository mirror provided by AdoptOpenJDK project. To speed things up we will only clone master branch without commit history:

$ git clone \
	--depth 1 \
	-b master \
	git@github.com:AdoptOpenJDK/openjdk-jdk8u.git

Now when we have sources, its time to compile OpenJDK. First we need to install all required dependencies:

$ sudo apt install \
        libx11-dev \
        libxext-dev \
        libxrender-dev \
        libxtst-dev \
        libxt-dev \
        libcups2-dev \
        libfreetype6-dev \
        libasound2-dev

Then we must run configure script:

$ cd openjdk-jdk8u/
$ chmod +x ./configure
$ ./configure \
	--with-debug-level=slowdebug \
	--with-target-bits=64

We call configure with two options:

  • --with-debug-level=slowdebug - enables generating debug information when compiling OpenJDK
  • --with-target-bits=64 - we will generate 64-bit binaries

It may happen than configure will return error telling you that you need to install some additional tool/library. This is something to be expected, just follow instructions printed by configure. You may need to do this several times until you will have all required dependencies installed on your system.

Now it’s time to actually build OpenJDK:

$ make

This may take some time…

----- Build times -------
Start 2017-06-24 17:45:26
End   2017-06-24 17:48:53
00:00:12 corba
00:01:25 hotspot
00:00:08 jaxp
00:00:12 jaxws
00:01:13 jdk
00:00:17 langtools
00:03:27 TOTAL
-------------------------
Finished building OpenJDK for target 'default'

Now we may use our newly built java to run “Hello, world!” program:

$ ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java \
	-cp "/home/me/dev/java/helloWorld/" \
	App
Hello, world!

Creating project for OpenJDK 8 in NetBeans

You need to download and install NetBeans IDE. Since HotSpot is written in C++ we will need NetBeans with C/C++ support.

Now it is time to create project for OpenJDK in NetBeans. Select File->New Project…->C/C++ Project with Existing Sources… New project dialog window.

Then select “Custom” configuration mode: New project dialog window 2 step.

We must use the same configure arguments that we used on command line: Configure options.

Now click “Next” a few more times and then click “Finish”. NetBeans should now run configure and build OpenJDK, you should see compiler output in Build tab: Build window.

After build ends you should see output similar to:

----- Build times -------
Start 2017-06-24 18:07:15
End   2017-06-24 18:11:17
00:00:14 corba
00:01:45 hotspot
00:00:08 jaxp
00:00:13 jaxws
00:01:22 jdk
00:00:20 langtools
00:04:02 TOTAL
-------------------------
Finished building OpenJDK for target 'default'

BUILD SUCCESSFUL (total time: 4m 2s)

Now we should try to run our “Hello, World!” program from NetBeans. Click on project and then select “Properties”: Run command. Then go to “Run” category and click on “…” next to “Run command”, then write any command that you want to run. Assume that "${OUTPUT_PATH}" refers to java binary: Run command step 2.

Now select Run->Run Project, NetBeans will ask you what binary you want to run, select java: Run command step 3.

Now you should see “Hello, world!” written in Output window: Run command step 4.

Debugging with NetBeans

Call to System.out.println(...) in Java will ultimately be handled by writeBytes function in jdk/src/share/native/java/io/io_util.c file (this is only valid for Linux builds of OpenJDK).

Lets put a breakpoint inside that function and see what will happen when we try to debug Hello world program: Debug step 1.

Select Debug->Debug Main Project. After executing this command you may see window: Debug step 2. JVM uses SIGSEGV for its internal purposes, from our point of view we may just ignore it (select “Don’t Catch this Singla Again” and “Forward and Continue”). After a few seconds we should be able to catch a breakpoint and see what JVM is doing: Debug step 3.

And that’s it! Now you will be able to check and understand how JVM is working under cover.

References

marcin-chwedczuk

A Programmer, A Geek, A Human