想深入了解Java的运行机制,我们有必要了解HotSpot虚拟机;下面我们先在CentOS6.4 64位系统上编译OpenJDK8源码,然后用gdb断点调试hotspot源码,最后再配置在eclipse上调试hotspot源码;
1、编译OpenJDK8源码
1-1、获取OpenJDK8源码
最新OpenJDK8源码下载页面:
http://download./openjdk/jdk8
这里下载openjdk-8-src-b132-03_mar_2014.zip:
http://www./download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip
在CentOS上解压:
unzip openjdk-8-src-b132-03_mar_2014.zip
1-2、配置编译环境
解压后看到,构建编译说明:README-builds.html
1)、make版本
OpenJDK8可以使用"config && make"编译构建,不再使用Ant和ALT_ *环境变量来配置构建;
不过需要GNU make 3.81或更新的版本(查看:make -version);
2)、安装引导JDK:
构建JDK8需要使用JDK7 Update 7或更高版本的版本作为引导(Bootstrap)JDK,但不应使用JDK8作为引导JDK;
JDK7下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
这里下载jdk-7u80-Linux-x64.rpm;
下载放到主机上后,直接:
yum localinstall jdk-7u80-linux-x64.rpm
安装的目录:/usr/java/jdk1.7.0_80/
3)、安装编译工具类库:
yum groupinstall "Development Tools"
yum install libXtst-devel libXt-devel libXrender-devel
yum install cups-devel
yum install freetype-devel
yum install alsa-lib-devel
yum install epel-release(提示:没有可用软件包 ccache时先安装这个)
yum install ccache
还可以再安装ccache,能加快编译速度,特别是需要多次编译时;
这些在configure时,都有提示,缺什么就安装什么;
1-3、构建编译
--with-boot-jdk:指定引导JDK所在目录,以防其他安装的JDK影响(本机上以前安装了JDK8,并配置了JAVA_HOME指向JDK8);
--with-target-bits:指定编译64位系统的JDK;
为可以进行源码调试,再指定下面三个参数:
--with-debug-level=slowdebug:指定可以生成最多的调试信息;
--enable-debug-symbols ZIP_DEBUGINFO_FILES=0:生成调试的符号信息,并且不压缩;
命令如下:
cd openjdk
bash ./configure --with-target-bits=64 --with-boot-jdk=/usr/java/jdk1.7.0_80/ --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
make all ZIP_DEBUGINFO_FILES=0
命令结果如下:
生成的文件都在openjdk/build目录,测试:
./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java -version
2、gdb断点进入源码调试hotspot
2-1、编译class
[root@localhost test]# vim Test.java
[root@localhost test]# cat Test.java
public class Test{
public static void main(String[] args){
System.out.println("hello world !");
}
}
[root@localhost test]# /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/javac Test.java
[root@localhost test]# /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test
hello world !
2-2、进入gdb测试
用gdb测试上面编译的class文件;
然后在 init.cpp的第95行打个断点,
接着运行,可以看到停在了/root/openjdk/hotspot/src/share/vm/runtime/init.cpp:95;
执行过程如下:
[root@localhost test]# gdb --args /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test
(gdb) break init.cpp:95
(gdb) run
(gdb) l
(gdb) quit
可以对比init.cpp源码文件:
2-3、注意,如果不能进入断点
出现以下类似信息:
Missing separate debuginfo for /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.so
因为前面configure没指定"--enable-debug-symbols ZIP_DEBUGINFO_FILES=0"没生成调试的符号信息,或生成后被压缩为"libjvm.diz"了,所有无法找到;
可以去到"libjvm.so"所在目录,然后解压:unzip libjvm.diz
解压出来:libjvm.debuginfo
更多详情见请继续阅读下一页的精彩内容: http://www./Linux/2017-06/144713p2.htm
3、在eclipse上调试hotspot源码
3-1、下载eclipse,安装C/C++插件
到官网选择一个合适的eclipse下载:https://www./downloads/eclipse-packages/?osType=linux&release=undefined
这里下载的是eclipse-java-neon-1a-linux-gtk-x86_64.tar.gz:https://www./downloads/download.php?file=/technology/epp/downloads/release/neon/1a/eclipse-java-neon-1a-linux-gtk-x86_64.tar.gz&mirror_id=1207
这个还没有开发C++的功能,所有解压打开eclipse后,还需要到"help -> Eclipse Maketplace",搜索"c++"找到Eclipse C++ IDE..安装;
安装后,就可以转到C++开发视图界面了,如下:
3-2、导入hotspot工程
File-> New -> Existing Code as Makefile Project
在界面中:
Project Name:hotspot(这个可以自己选择)
Existing Code Location:/root/openjdk/hotspot
Toolchain:选Linux GCC,然后按Finish.
3-3、配置源码调试
右键工程 -> Debug As -> Debug Configurations -> 右键左边的C/C++ Application -> New -> 进入Main选项卡;
在选项卡中:
Project:hotspot(选择导入的hotspot工程)
C/C++ Application:/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java(编译生成的openjdk虚拟机入口)
Disable auto build:因为不再在eclipse里面编译hotspot源码,所以这里选上它;
然后切换到Arguments选项卡, 输入Java的参数, 我们这里运行上面的Main类, 于是这里填上 "Test"也就是我们要执行的Java程序
然后切换到Environment选项卡, 添加变量:
JAVA_HOME=/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/(编译生成JDK所在目录)
CLASSPATH=.:/root/test (Test类文件所在目录)
点击下面的Apply保存;
3-4、断点Debug
在hotspot源码工程中找到init.cpp, 在95行打个断点;
运行上面配置的Debug, 可以看到顺利调到了断点;
如图:
注意,如果不能进入断点看前面"2-3";
4、配置hotspot调试运行eclipse的java工程
4-1、新建java工程(测试)
新建java工程,在工程新建包,在包中新建Test.java文件,测试程序如下:
01.package com.hotspot.test;
02.public class Test {
03. public static void main(String[] args){
04. System.out.println("hotspot test!");
05. }
06.}
而运行正常,生成了Test.class文件,如下图:
4-2、修改hotspot工程调试参数
在前面的5-3配置源码调试的配置上作如下修改;
Arguments选项卡:
com.hotspot.test/Test(注意在前面加上包名,然后是运行类)
Environment选项卡, 修改变量:
CLASSPATH=.:/root/workspace/TestHotspot/bin (java工程生成的bin目录,不包括包名目录)
保存后,点击调试运行hotspot工程,可以看到正常运行了上面的java工程文件,如下:
注意,如果有包名情况下,配置不对,调试运行会报"错误: 找不到或无法加载主类 **";到这里,我们可以对hotspot虚拟机源码进行调试了……