先声明环境:
可以在docker里面编译,利用ubuntu的镜像,然后安装相关依赖也不会影响到宿主机。
其实我们搜索openjdk进入到jdk11特性列表页面时,左边有个Mercurial链接,从那就可以进入源码列表了,在源码列表选择jdk->jdk11即进入了源码页面。
最终源码链接在此 https://hg.openjdk.java.net/jdk/jdk11/。
打开后选择左边的bz2或zip或gz格式的下载文件即可。
这里我们选择bz2(总共87MB)格式的文件,即最终下载链接在此 https://hg.openjdk.java.net/jdk/jdk11/archive/tip.tar.bz2。
特意提供百度网盘链接 https://pan.baidu.com/s/1w91BX7-rF-6F1Dd_zly7dA 提取码: 7a7k
之后就是解压到特定无特殊字符名的文件夹了,就不再赘述了。
解压后目录结构大致就是这样
.
├── ADDITIONAL_LICENSE_INFO
├── ASSEMBLY_EXCEPTION
├── bin
├── build
├── configure //利用bash configure来做编译前的准备工作
├── doc //里面有各种帮助文件,可以教你怎么编译jdk
├── LICENSE
├── make
├── Makefile
├── README
├── src //主要源码
└── test
我们用clion打开解压后的目录(src目录的父目录),等待扫描后,就可以利用Ctrl+Shift+N
或Ctrl+Shift+F
等快捷键快速搜索文件名或特定字符串。
.
├── bsd
├── demo
├── hotspot
├── java.base
├── java.compiler
├── java.datatransfer
├── java.desktop
├── java.instrument
├── java.logging
....同类省略
├── jdk.accessibility
├── jdk.aot
├── jdk.attach
├── jdk.charsets
...同类省略
├── linux
├── sample
├── solaris
└── utils
其中hotspot 就是Java虚拟机的Cpp源码了,我们调试就只需要利用这个目录下的文件即可。
如果想查看Java类中的本地方法是怎么实现的,只需打开相应的文件夹找到相应的类名.c文件即可。
例如:查看String类的intern方法的实现。利用Ctrl+Shift+N
打开文件名搜索string.c
,即可看到src/java.base/share/native/libjava/String.c
中的intern实现。
JNIEXPORT jobject JNICALL
Java_java_lang_String_intern(JNIEnv *env, jobject this)
{
return JVM_InternString(env, this);
}
官方的编译jdk的文档在doc/building.md
,通过这个可以了解很多信息。
实际上到这你就可以在解压目录下执行bash configure --disable-warnings-as-errors
(后面的选项一定要加上,否则编译不通过)。然后你会发现总是报错不通过并提示未安装相应文件,只需根据提示安装即可。如:
configure: error: Could not find alsa! You might be able to fix this by running 'sudo apt-get install libasound2-dev'
重复步骤直到成功即可。
实际上可以执行
make help
,会显示编译帮助
执行make
。
.....
Stopping sjavac server
Finished building target 'default (exploded-image)' in configuration 'linux-x86_64-normal-server-release'
编译成功后的显示如上。
编译好的jdk文件会在build/linux-x86_64-normal-server-release/jdk
目录下,根我们平时下的jdk目录结构是一样的。
之前我们已经利用clion在解压目录下(src目录的父目录)打开了项目。现在我们close project
,然后再次file->open
打开src/hotspot
目录。
以前的Clion好像会自动生成CMakeLists.txt
,我用的Clion2019.2不会。
CMakeLists.txt
,然后写入如下内容:cmake_minimum_required(VERSION 3.14) # 这个设置不需要严格对应,自己建个测试项目复制过来这段即可
project(hotspot)
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.hpp" "*.c" "*.h")
add_executable(hotspot ${SOURCE_FILES})
CMakeLists.txt
就会自动生成一个名称为hotspot的Run Configuration
,类型为CMake Application。但是这样是不够的,无法启动,我们需要修改Run configuration
。
build/linux-x86_64-normal-server-release/jdk/bin/java
程序
现在就可以利用这个配置进行调试了,可以利用Program arguments像平时一样给java命令传递参数。
打开share/prims/jni.cpp
,给JNI_CreateJavaVM
函数打断点。以调试模式运行:
我们可以像平时调试一样单步进入、查看调用栈、查看运行线程、查看参数信息等
我们的调试之旅就到这里了,有什么问题欢迎留言