# 在2024年使用Clion编译、debug、开发Java虚拟机(Mac版本)

# 目的

有时候我们想看一些jdk的原理,比如某个gc参数的作用是什么,在网上可能查不到准确详细的资料,我会更习惯亲自debug jdk查看代码运行结果。

在之前我也总结过jdk的编译debug方法,不过之前的方法不是很好用,比如有很多方法字段定义无法跳转,今天我们来学习 一下最新的jdk构建debug开发方法,完美而且优雅。

# 下载代码

git clone git@github.com:JetBrains/JetBrainsRuntime.git
1

# 编译

为了构建虚拟机、以及debug调试,需要对代码进行编译。

# 编译依赖

编译依赖Xcode,通过AppStore搜索下载安装就可以。 安装完成后执行下

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
1

编译jdk需要一个jdk作为boot jdk,先到jdk官网 (opens new window) 下载安装和当前版本相同(或低一两个版本)的jdk。

比如当前的是jdk20,则允许的boot jdk版本是18 19 20

然后安装编译需要的一些依赖包

brew install autoconf freetype ccache
1

# 开始编译

#首先cd到代码目录中
cd jdk
# 进行configure
bash configure --with-debug-level=slowdebug --enable-dtrace --with-jvm-variants=server --with-target-bits=64 --with-num-cores=8 --with-memory-size=8000 --disable-warnings-as-errors
# 进行make,这个过程稍久一些
make
1
2
3
4
5
6

如果提示This might be fixed by explicitly setting --with-boot-jdk (Your Boot JDK version must be one of: 18 19 20),则bash configure增加--with-boot-jdk参数配置成自己的jdk的路径, 比如我的Java Home是/Library/Java/JavaVirtualMachines/jdk-18.0.1.1.jdk/Contents/Home 则configure命令如下

bash configure --with-debug-level=slowdebug --enable-dtrace --with-jvm-variants=server --with-target-bits=64 --with-num-cores=8 --with-memory-size=8000 --disable-warnings-as-errors --with-boot-jdk=/Library/Java/JavaVirtualMachines/jdk-18.0.1.1.jdk/Contents/Home
make
1
2

make成功

通过调用java -version验证下build出来jdk

./build/macosx-x86_64-server-slowdebug/jdk/bin/java -version
1

img.png

# 导入IDE

目前JDK可以compile-commands导入,在项目文件夹执行

openjdk中的代码包含了Java(jdk各种jar包)和C++(hotspot虚拟机部分),本文主要针对hotspot部分。 现代化的IDE是阅读、开发、调试代码的好工具,这里推荐使用Jetbrains公司(也是开发IntelliJ Idea的)提供的CLion (opens new window)

调用make compile-commands,为Clion生成compile_commands.json文件

make compile-commands
1

执行完这条命令后会在build目录下的构建出来的文件里生成一个compile_commands.json文件。

打开CLion,点击File -> Open打开这个compile_commands.json文件,选择Open as Project。

打开项目后,通过CLion的Tools -> Complilation Database -> Change Project Root 更换项目的root为jdk代码的根目录

然后就可以在CLion中愉快的进行函数、字段跳转了。

# CLion debug

下面我们要在CLion中运行、debug jdk。

在CLion中通过快捷键Command + 逗号,打开Preference,在Build, Execution, Deploy -> Custom Build Targets 中,添加一个新的Custom Build Target, Name填macosx-x86_64-server-slowdebug,

然后点击Build 右边的三个点的按钮,添加一个External Tools。

Name 填make macosx-x86_64-server-slowdebug, Program填make, Argument填CONF=macosx-x86_64-server-slowdebug, Working directory选择jdk代码根目录。

然后clean也是类似的配置,Argument填CONF=macosx-x86_64-server-slowdebug clean

然后点击Apply, Ok。

点击Add Configuration

添加一个Custom Build Application, Name 改成debug jdk, Target会自动选择我们刚创建的macosx-x86_64-server-slowdebug, Executable选择构建出来build文件夹里的macosx-x86_64-server-slowdebug/jdk/bin/java

# 解决sigsegv问题

在jdk源码根文件目录内,创建一个.lldbinit文件,内容为

br set -n main -o true -G true -C "pro hand -p true -s false SIGSEGV SIGBUS"
1

然后在创建一个 ~/.lldbinit文件(也就是在home文件夹下创建.lldbinit文件),内容为

settings set target.load-cwd-lldbinit true
1

# debug

然后在arguments.cpp文件中添加几个断点,点击debug,就能构建运行并停在我们设置的断点上。

跳过断点后,可以看到熟悉的java -version的结果

# 总结

上述部分就是编译、debug、开发openjdk的方法,授人以鱼不如授人以渔,有了这些方法就可以更方便的查看实现以及排查问题了。 但是最后也要提醒大家不忘初心、不要过于沉溺于底层实现、不要盲目崇拜开发虚拟机认为是什么高深莫测的工作。这里引用王垠 (opens new window)的一段话

每当有人向我表示编译器高深莫测,向往却又高攀不上,我都会给他打一个比方:做编译器就像做菜刀。你可以做出非常好的菜刀,然而你终究只是一个铁匠。铁匠不知道如何用这菜刀做出五花八门,让人心旷神怡,米其林级别的菜肴,因为那是大厨的工作。要做菜还是要打铁,那是你自己的选择,并没有贵贱之分。

# 其他参考