preface

We all know that Java programs are run in the JVM virtual machine, JDK in many native methods are implemented in the JVM source code. So how does the JVM load classes, how does it create objects, and what is the nature of thread synchronization? What do invisible native methods do? These questions may be understood by baidu. But through Baidu to obtain the knowledge, if they did not digest, just temporarily solve a problem, or recite the interview. I think it’s pointless. Because after a while, you forget about it. I don’t even remember it at all. So how to put these knowledge deeply engraved in my mind. Actually, I don’t think it’s necessary. Why memorize these rigid knowledge points. For example, you may be asked how many system calls are involved in the underlying Epoll mechanism that Java NIO relies on. The answer is epoll_create, epoll_ctl, and epoll_wait. But I don’t really need to remember them. I think it will probably be used in the interview. And it’s usually asked in an interview for a development position. In fact, find the next JDK source will not know, there is no need to deliberately remember these things. In the next few articles, I will explain how to set up a debugging environment for native JVMS and how to debug native methods. How to debug the JVM startup process. Of course these are just the keys to the JVM door. It takes a little bit of accumulation to understand.

Environment to prepare

My operating system: MAC OS Big Sur Version 11.4

  1. downloadclionMy version is2019.3.6
  2. git clone openjdk12
  3. Install jdk11, compile JDk12 need to use the boot JDK, otherwise will promptYour Boot JDK version must be one of 11,12

Compile the JDK

Go to the openJDK root directory and run it

bash configure --disable-warnings-as-errors --with-debug-level=slowdebug --with-jvm-variants=server
make images
#The disable-warnings-as-errors option disallows warning as error
#- with - debug - level = slowdebug. This is used to set the compile level. The options are release, fastDEBUG, and slowde-bug. The default value is release. Slowdebug contains the most extensive debugging information, without which many of the executions might be tuned out, and we might not see the values of some variables when we step. So it is best to specify slowDebug as compilation level.
#Optional values: Server, Client, minimal, Core, Zero and Custom
Copy the code

The configure command is responsible for checking dependencies, configuring parameters, and constructing the output directory structure. If a required tool chain or dependency is missing during compilation, a prompt is displayed after the command is executed, and the dependency installation command is provided.

After a long wait, a JDK of its own was born. Its directory structure looks like this

Debug hotspot VIRTUAL machine using Clion

The following main reference this blog blog.jetbrains.com/clion/2020/…

Cmake is used by clion by default, but openJDK compilation is done by make

If you are working with a project which is not based on CMake, Gradle, or Makefiles, you can still benefit from the advanced IDE features that CLion provides. One way is to import a non-CMake project and let CLion convert it into a simple CMake structure. Another option is to open a project by loading its compilation database

Generate the file compile_commands.json

make compile-commands
Copy the code

Use CLion File=> Open => select the File

/jdk12/build/macosx-x86_64-server-slowdebug/compile_commands.json

Select Open as Project

You will find that you cannot see the source code, so you need to Change the Root directory of your Project by using Tools -> Compilation Database -> Change Project Root to select your source directory, that is jdk12

Custom Build Targets

Run/Debug configurations

Set breakpoints and debug

This is just a brief demonstration of how java-version can be debugged. How do you debug a normal Java program?

Write a test program as follows:

public class Demo {
    public static void main(String[] args) throws Exception { LockSupport.park(); }}Copy the code

Looking at the source code, the park method actually calls the Park method of the Unsafe class. And the native method source code in/jdk12 / SRC/hotspot/share/runtime/park. The HPP, its implementation class is/jdk12 / SRC/hotspot/OS/posix/os_posix CPP. Configure the parameters of the debugger.

Set a breakpoint in OS_POSIX.cpp.

You can see that the system call pthread_cond_wait is finally called and the thread is waiting there.

This is just a simple example of how to debug Java programs using Clion. Follow this method to perform single step debugging on any native method.

IDEA with Clion remote debugging

Above we implemented the debug hotspot virtual machine. What if I want to debug Java programs with the hotspot VIRTUAL machine? This requires the use of the JVM’s remote debug functionality.

For example, create a simple Spring Boot project and use Maven to generate executable JARS.

Clion configuration is as follows:

Idea configuration is as follows:

In this way, breakpoints can be set under Clion or IDEA, and can be single-step debugging.

conclusion

This article provides a brief introduction to the environment and tools for debugging the OpenJDK. There will be several in-depth hotspot source parsing tutorials for the features. Stay tuned.