openjdk-8 -- 使用Clion调试源码

终端中gdb断点进入源码调试hotspot

1 编译class

1
2
3
4
5
6
7
8
9
10
vim ~/Test.java
# 输入以下内容
public class Test{
public static void main(String[] args){
System.out.println("hello world !");
}
}
/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/javac Test.java
/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test
hello world

2 进入gdb测试

1
2
3
4
5
6
7
8
9
10
# 第一步,启动gdb
gdb --args /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java ~/Test
# 第二步,设置断点
(gdb) break init.cpp:95
# 第三步,开始debug
(gdb) run
# debug会在断点处停止,可以查看断点处代码
(gdb) l
# 最后,退出gdb
(gdb) quit

整个操作如下图所示:

在IDE中调试,这里选择Clion

1 导入项目

打开clion,选择 File->ImportProject,选择到 ~/ClionProjects/openjdk-8/hotspot作为jvm源码的根目录,这里导入的过程无脑点击next即可

对于可能遇到的头文件不包含问题,解决如下:

clion导入源码之后遇到头文件找不到的问题,而实际上这些头文件在源码里面是存在的,只不过在某些源文件里面是以相对路径的方式来搜索,可以在CMakeLists.txt里面添加一些根路径

1
2
3
4
include_directories(./src/share/vm)
include_directories(./src/cpu/x86/vm)
include_directories(./src/share/vm/precompiled)
include_directories(./src/share/vm/utilities)

另外,如果某些头文件依然找不到,可以手工导入,然后把导入的头文件加到
hotspot/src/share/vm/precompiled/precompiled.hpp里,因为大多数源文件都会包含这个源文件

1
2
3
4
5
6
7
8
# include <cstdlib>
# include <cstdint>
# include "register_x86.hpp"
# include "assembler_x86.hpp"
# include "globalDefinitions.hpp"
# include "globalDefinitions_x86.hpp"
# include "assembler_x86.hpp"
#include <stubRoutines_x86.hpp>

2 配置debug

右上角,点击Edit Configuration

进入如下界面,添加Application:jdk-8,Execuable中选择~/CLionProjects/openjdk-9/build/linux-x86_64-normal-serverANDclient-slowdebug/jdk/bin

Before lauch: Activate tool window 下的预build项一定要去掉,我的已经去掉了

3 设置断点,开始debug

断点选在jni.cpp的创建vm处,然后开始debug

这里如果报错,如下图所示:

可以在点击LLDB,输入process handle SIGSEGV --stop=false即可,这里告诉编译器忽略错误

一般Clion默认使用GDB进行debug,可以根据如下所示进行切换

同理,若为GDB的话,点击输入handle SIGSEGV pass noprint nostop即可

动图如下:

参考资料

深入jvm内部掌握java线程的运行原理