JDK源码编译与调试
参考《深入理解Java虚拟机》及其他资料编译和debug。
编译
注:JDK是一个大型项目,也就是说其配套的东西已经很完善了,首先应该阅读参考文档与构建支持文档。
jdk需要在一个POSIX操作系统的执行环境,故MacOS与linux可以直接支持,windows是唯一的支持的非POSIX操作系统。所以Windows在编译的时候需要构建这样一个POSIX支持层,你可以使用cygwin也可以通过WSL(Windows Subsystem for Linux,windows的Linux子系统)。我这里使用cygwin。
1.构建环境
cygwin下载安装,以下是你需要的一些库:
autoconf
make
zip
unzip
注:正如开头所说,这是一个大型项目,功能完善,所以如果你不知道需要哪些库,那可以先安装然后执行configure的时候会有缺少的依赖的提示。
C++环境下载安装,这一步你需要合适的版本,我这边编译的是Jdk17,在make/autoconf/toolchain_microsoft.m4文件可以看到对应版本是2019,为了不必要的配置我这边直接安装Visual Studio 2019。
VS_VERSION_INTERNAL_2019=142
VS_MSVCR_2019=vcruntime140.dll
VS_VCRUNTIME_1_2019=vcruntime140_1.dll
VS_MSVCP_2019=msvcp140.dll
VS_ENVVAR_2019="VS160COMNTOOLS"
VS_USE_UCRT_2019="true"
VS_VS_INSTALLDIR_2019="Microsoft Visual Studio/2019"
VS_EDITIONS_2019="BuildTools Community Professional Enterprise"
VS_SDK_INSTALLDIR_2019=
VS_VS_PLATFORM_NAME_2019="v142"
VS_SDK_PLATFORM_NAME_2019=
VS_SUPPORTED_2019=true
VS_TOOLSET_SUPPORTED_2019=true
注:安装的时候选择为 使用C++的桌面开发 ,然后去掉中文语言包选择英文的。
bootstrap jdk安装,这个就没什么好说的了,下载一个jdk 16(前文提到本文编译)然后解压配置环境变量就行。
编译测试
拉取代码:
git clone git@github.com:openjdk/jdk.git
注:从java 16开始,jdk项目已经全部托管到github了,你要编译哪个版本直接切换对应的release tag就OK了。
git checkout jdk-17+35
我们需要在crywin终端编译jdk,打开你的终端然后切换到jdk的源码目录。值得注意的是windows的盘符是挂载到/cygdrive下面的对应子目录的。做法和WSL是一致的。
检查配置,配置构建环境。
./configure --with-debug-level=release --disable-warnings-as-errors
注: --disable-warnings-as-errors可以关闭make时将警告(warn)作为错误(error)的处理方式。问题处理在build文档里面有写,在编译提示里面也有写。我这边sscanf函数报了个警,所以关掉了。
注:如果你在linux运行configure发现如下面提示:
configure: error: Could not find alsa!
可以运行类似下面的命令安装对应的库:
sudo apt install libalsa*
configure后会提供以下版本的jdk构建环境:
Available configurations in /cygdrive/d/C/jdk/build:
* windows-x86_64-server-release
Please retry building with CONF=<config pattern> (or SPEC=<spec file>).
假如你构建了多次环境,则会有多个版本,你需要通过CONF参数指定版本(或者make all ,不过非常耗时):
make images CONF=windows-x86_64-server-release
等待编译完成。
去build目录下查看jdk,校验版本。
./java --version
openjdk 17-internal 2021-09-14
OpenJDK Runtime Environment (fastdebug build 17-internal+0-adhoc.lee.jdk)
OpenJDK 64-Bit Server VM (fastdebug build 17-internal+0-adhoc.lee.jdk, mixed mode)
DEBUG
上面已经成功编译打包了jdk了。我们将项目导入到IDE,我这边用Clion,当然也可以直接使用上文安装的Visual Studio。我这边是直接源码通过Clion从git拉下来然后才做的上面的编译操作。我这里的调试设置与书中是不一样的,建议使用我这种方式。
配置Clion debug环境
在jetbrains有篇官方博客专门讲这个。
首先配置toolchains,这里是Visual Studio,需要注意的是,我们的make程序使用的是crywin的(你使用Visual Studio默认的也可以),其他都保持默认:
然后配置自定义Target:
注意这里依然使用的是crywin的bash去执行:
--login
-c
"cd /cygdrive/d/C/jdk; make CONF=windows-x86_64-server-fastdebug"
最后设置自定义Run Configutation:
注意选择选择Custom Build Application,Target 和 执行程序(我这里使用fastdebug版本的) 都是自定义的:
-version
-XX:TraceBytecodes
-XX:StopInterpreterAt=<n>
debug调试
上面,我们已经环境准备好了,debug运行就可以断点调试了,在入口文件java.c的JavaMain方法添加一行:
JavaMain(void* _args)
{
printf("hello world\n");
点击Debug,等待编译完成然后运行会得到以下结果:
D:\C\jdk\build\windows-x86_64-server-fastdebug\jdk\bin\java.exe -version -XX:TraceBytecodes -XX:StopInterpreterAt=<n>
hello world
openjdk version "17-internal" 2021-09-14
OpenJDK Runtime Environment (fastdebug build 17-internal+0-adhoc.lee.jdk)
OpenJDK 64-Bit Server VM (fastdebug build 17-internal+0-adhoc.lee.jdk, mixed mode)
断点调试如下:
注:C与C++有一个特点,那就是很大的灵活性。老一辈开发者会使用Vim + GDB调试C应用,我的意思是多种方式debug。周志明博士甚至提供了一个懒人包供使用。
注:就阅读JDK源码来说,已经完全足够了。
总结
过程不复杂,就是网上被CSDN的的垃圾信息充满了。人心浮躁。
至此,从虚拟机到java应用,你都可以自己调试了。