本篇文章大量参考来源于 JVM(一) OpenJDK1.8源码在Ubuntu16.04下的编译 和 在Ubuntu14下构建Hotspot并使用Eclipse调试 除此之外记录自己遇到的问题并且给出解决方案,废话不多说,直接开始。
一.环境准备:
1. 安装Bootstrap JDK,这里我们使用OpenJDK7,运行如下命令
sudo apt-get install openjdk-7-jre
sudo apt-get install openjdk-7-jdk
遇到如下问题:package is not available
解决方案:添加repository,update后重新安装
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-7-jre
sudo apt-get install openjdk-7-jdk
安装完成后使用java -version验证是否安装成功
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ java -version
java version "1.7.0_95"
OpenJDK Runtime Environment (IcedTea 2.6.4) (7u95-2.6.4-3)
OpenJDK 64-Bit Server VM (build 24.95-b01, mixed mode)
PS:我第一次安装时没有发现ubuntu上有一个OpenJDK,从而导致后面出现了各种问题,因此建议先卸载系统中的其他JDK
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ sudo apt-get remove openjdk*
2. 下载OpenJDK源码
链接: https://pan.baidu.com/s/1cpwYpacqVsFuR5_2twEhZw 提取码: t9yp
3. 安装相关依赖包
可以在运行./configure时缺什么安装什么,下面提到的依赖包仅供参考
sudo apt-get install libx11-dev libxext-dev libxrender-dev libxtst-dev libxt-dev
sudo apt-get install libcups2-dev
sudo apt-get install libfreetype6-dev
sudo apt-get install libasound2-dev
二. 进行编译
1. 解压OpenJDK源码后进入根目录
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ ls
ASSEMBLY_EXCEPTION hotspot LICENSE README-builds.html
common jaxp make test
configure jaxws Makefile THIRD_PARTY_README
corba jdk nashorn
get_source.sh langtools README
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$
2.运行根目录下的configure脚本,注意:此处不加参数configure出的OpenJDK为release版本,按照教程推进到后面时出现了不可预知的错误,因此加上参数:
--with-debug-level=slowdebug 表示构建debug版本, openjdk8去掉了jvmg版本的构建
--enable-debug-symbols 和 ZIP_DEBUGINFO_FILES=0 主要是方便调试
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ bash ./configure --with-debug-level=slowdebug --enable-debug-symbols ZIP_DEBUGINFO_FILES=0
f
3.查找是否有环境变量JAVA_HOME和CLASSPATH,有的话要去掉
添加系统环境变量LANG,设定语言选项
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ $echo $JAVA_HOME
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk$ $echo $CLASSPATH
#如果有的话
unset JAVA_HOME
unset CLASSPATH
#set language
export LANG=C
4. 运行make all
make all CONF=linux-x86_64-normal-server-slowdebug ZIP_DEBUGINFO_FILES=0
遇到问题:操作系统不支持,可以看到从错误中容易看出,应该是内核版本和JDK要求的内核版本不一致造成的。
根据错误找到Makefile
zmx@ubuntu:~$ gedit ~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/hotspot/make/linux/Makefile
进入Makefile,在SUPPORTED_OS_VERSION某尾添加4%
5. 编译完成
6.验证编译成功后的JDK
zmx@ubuntu:~/nju/openjdk-8u40-src-b25-10_feb_2015/openjdkildnux-x86_64-normal-server-slowdebugk/bin$ ./java -version
openjdk version "1.8.0-internal-debug"
OpenJDK Runtime Environment (build 1.8.0-internal-debug-zmx_2019_02_23_10_38-b00)
OpenJDK 64-Bit Server VM (build 25.40-b25-debug, mixed mode)
在bin目录下新建一个Main.java
public class Main{
public static void main(String[] args){
System.out.println("hello world !");
}
}
编译并运行
./javac Main.java
./java Main
hello world !
7. 使用gdb调试
设置环境变量LD_LIBRARY_PATH,用于指定查找共享库(动态链接库)时除了默认路径以外的其他路径,如果这个变量没有设置或者设置错误,在调试时将会出现No source file named thread.cpp.错误(可根据自己编译的OpenJDK路径进行设置)
export LD_LIBRARY_PATH=/home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/hotspot/linux_amd64_compiler2/debug/
echo $LD_LIBRARY_PATH
/home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/hotspot/linux_amd64_compiler2/debug/
开始gdb调试
gdb --args ./java Main
#进入gdb,打断点然后运行
(gdb) break thread.cpp:219
No source file named thread.cpp.
#从future shared library中找到thread.cpp,如果LD_LIBRARY_PATH没有配置则无法找到thread.cpp
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (thread.cpp:219) pending.
(gdb) run
Starting program: /home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Main
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff7fd9700 (LWP 14628)]
[Switching to Thread 0x7ffff7fd9700 (LWP 14628)]
Thread 2 "java" hit Breakpoint 1, Thread::Thread (this=0x7ffff000c800)
at /home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/hotspot/src/share/vm/runtime/thread.cpp:219
219 set_stack_base(NULL);
# 查看当前代码
(gdb) l
214 // JavaThread
215
216
217 Thread::Thread() {
218 // stack and get_thread
219 set_stack_base(NULL);
220 set_stack_size(0);
221 set_self_raw_id(0);
222 set_lgrp_id(-1);
8.安装Eclipse IDE for C/C++ Developers进行调试(不推荐直接使用命令 sudo apt-get install eclipse,因为这样为安装上许多不必要的插件)
下载地址:https://www.eclipse.org/downloads/packages/release
我下载的是 eclipse-cpp-kepler-SR1-linux-gtk-x86_64.tar.gz
解压:
sudo tar xzvf xxxx.tar.gz -C ./
点击import后选择existing code as makefile project
出现问题:点击Next之后无反应,一直卡在上述界面,同时eclipse打开时报错信息包含以下两个内容:
1. Generating Library Hover help for installed devhelp documentation
2. Load C/C++ library hover data
解决方案:
1.不要用eclipse第一次打开自带的workspace,我的方法是在包含eclipse的目录下新建一个workspace文件夹,
选择它做workspace,具体原因未知。
2. 参考链接 https://blog.csdn.net/luonanqin/article/details/7862069 中的方法将JDK改成ICU
导入编译后的工程:
结果如下图所示:
8.准备调试,参考链接:https://blog.csdn.net/wangemperor/article/details/80715952
将/hotspot/src目录加入源码索引方便代码搜索
设置启动类
C/C++ Application:/home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java
选择Disable auto build
Arguments选择Main
这些变量都按照链接 https://my.oschina.net/haogrgr/blog/414825 中的操作进行设置
LD_LIBRARY_PATH = /home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/hotspot/linux_amd64_compiler2/debug/
CLASSPATH = .:/home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin
JAVA_HOME = /home/zmx/nju/openjdk-8u40-src-b25-10_feb_2015/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk
找到thread.cpp,在219行打一个断点
进行debug操作,可以看到程序顺利跳至到断点