Centos6.5编译openjdk7

一、环境准备

1、Centos6.5:VMware上面安装Centos6.5,可以联网用来下载,需要注意内存最好要大于1G,我设置的为2G,之前设置的512M内存,编译源码时出现各种问题;

2、apache-ant-1.7.1-bin.zip :下载地址:http://archive.apache.org/dist/ant/binaries/,或者https://pan.baidu.com/s/1kUYa1bp,解压安装路径为:/usr/java/apache-ant-1.7.1;

3、jdk1.7 :下载路径安装路径为https://pan.baidu.com/s/1qZ52wTe,安装路径: /usr/java/jdk1.7;

4、openjdk源码: http://download.java.net/openjdk/jdk7u40/promoted/b43/openjdk-7u40-fcs-src-b43-26_aug_2013.zip?q=download/openjdk/jdk7u40/promoted/b43/openjdk-7u40-fcs-src-b43-26_aug_2013.zip,或者https://pan.baidu.com/s/1o7PMZB8,下载后解压到路径 /home/lxz/openjdk;


PS:

调试一段时候,才知道openjdk是C++变写的代码或者叫源码,可以理解为java代码,可以在VS、NetBeens等工具上调试;

而编译好的代码,类似于java中的class,可以直接在linux上面运行,可以代替安装好的jdk;

所以可以通过VS、NetBeens工具查看、调试openjdk源码,通过查看openjdk源码可以看到JVM调优的一些参数,这些参数可以想象成java代码方法参数;

也可以直接在linux上面调试编译好的代码;


二、下载安装依赖包

[plain]  view plain  copy
 print ?
  1. #配置更新源  
  2. cd /etc/yum.repos.d/  
  3. curl http://mirrors.163.com/.help/CentOS6-Base-163.repo > CentOS6-Base-163.repo   
  4.   
  5. #当前wget还不能用  
  6. wget http://mirrors.163.com/.help/CentOS6-Base-163.repo  
  7. mv CentOS-Base.repo CentOS-Base.repo.bak  
  8. mv CentOS6-Base-163.repo CentOS-Base.repo  
  9. yum makecache  
  10.   
  11. yum -y groupinstall 'base'  
  12. yum -y install make  
  13.   
  14. #安装jdk必备软件包:  
  15. yum -y install alsa-lib-devel  
  16. yum -y install cups-devel  
  17. yum -y install libXi-devel  
  18. yum -y install gcc gcc-c++  
  19. yum -y install libX*  

三、编译源码
编译源码前需要先做执行配置:


[plain]  view plain  copy
 print ?
  1. export LANG=C  
  2. export ALT_BOOTDIR=/usr/java/jdk1.6.0_45  
  3. export ALT_JDK_IMPORT_PATH=/usr/java/jdk1.6.0_45  
  4. export ANT_HOME=/usr/java/apache-ant-1.7.1  
  5.    
  6. #允许自动下载依赖  
  7. export ALLOW_DOWNLOADS=true  
  8.    
  9. #并行编译的线程数(设置和CPU内核一样就好,在VMware安装时可以设置)  
  10. export HOTSPOT_BUILD_JOBS=4  
  11. export ALT_PARALLEL_COMPILE_JOBS=1  
  12.    
  13. #64位jdk  
  14. export ARCH_DATA_MODEL=64  
  15.    
  16. #不比较本次build出来的映像与先前版本的差异  
  17. export SKIP_COMPARE_IMAGES=true  
  18.    
  19. #使用预编译头文件  
  20. export USE_PRECOMPILED_HEADER=true  
  21.    
  22. #要编译的内容  
  23. export BUILD_LANGTOOLS=true  
  24. export BUILD_HOTSPOT=true  
  25. export BUILD_JDK=true  
  26. export BUILD_JAXWS=true  
  27. export BUILD_JAXP=true  
  28. export BUILD_CORBA=true  
  29. export SKIP_DEBUG_BUILD=false  
  30. export SKIP_FASTDEBUG_BUILD=false  
  31. EXPORT DEBUG_NAME=debug  
  32.    
  33. BUILD_DEPLOY=false  
  34. BUILD_INSTALL=false  
  35.    
  36. export ALT_OUTPUTDIR=/home/lxz/openjdk/build  
  37. unset CLASSPATH  
  38. unset JAVA_HOME  
  39.    
  40. #用来检查前面做做的设置是否正确  
  41. make sanity  
  42.    
  43. #编译,编译成功后在 /home/lxz/openjdk 会有build-debug、build-fastdebug两个目录  
  44. make 2>&1 | tee $ALT_OUTPUTDIR/build.log  


四、编译过程中出现的问题

1、时间问题

[plain]  view plain  copy
 print ?
  1. Error: time is more than 10 years from present: 1120165200000      
  2. java.lang.RuntimeException: time is more than 10 years from present: 1120165200000      
  3.         at build.tools.generatecurrencydata.GenerateCurrencyData.makeSpecialCaseEntry(GenerateCurrencyData.java:285)      
  4.         at build.tools.generatecurrencydata.GenerateCurrencyData.buildMainAndSpecialCaseTables(GenerateCurrencyData.java:225)      
  5.         at build.tools.generatecurrencydata.GenerateCurrencyData.main(GenerateCurrencyData.java:154)      
  6. make[4]: *** [/root/openjdk6/build/lib/currency.data] Error 1  <strong>  </strong>  

需要修改源码目录中的CurrencyData.properties文件(/home/lxz/openjdk/jdk/src/share/classes/java/util/CurrencyData.properties),我们需要做的是把文件中以下的时间改为10年内的一个时间(搜索200),比如:2005-12-31-20-00-00中2005改为2015;

2.

遇到错误Error:./gamma: relocation error: /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/libjava.so: symbol JVM_FindClassFromCaller, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference   

修改文件:hotspot/make/linux/Makefile   

去掉文件中所有的test_gamma即可

五、

2、gdb断点进入源码调试hotspot

2-1、编译class

[plain]  view plain  copy
  1. [root@localhost test]# vim Test.java  
  2. [root@localhost test]# cat Test.java  
  3.     public class Test{  
  4.     public static void main(String[] args){  
  5.         System.out.println("hello world !");  
  6.      }  
  7.     }  
  8. [root@localhost test]# /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/javac Test.java  
  9. [root@localhost test]# /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test  
  10.     hello world !  

2-2、进入gdb测试

      用gdb测试上面编译的class文件;

      然后在 init.cpp的第95行打个断点,

      接着运行,可以看到停在了/root/openjdk/hotspot/src/share/vm/runtime/init.cpp:95;

      执行过程如下: 

[plain]  view plain  copy
  1. [root@localhost test]# gdb --args /root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test  
  2.  (gdb) break init.cpp:95      
  3.  (gdb) run  
  4.  (gdb) l  
  5.  (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

调试步骤

可调试的虚拟机位置:

  • openjdk7:源代码目录

  • build-debug:编译后的二进制文件位置

  • build-debug/hotspot/outputdir/linux_i486_compiler1/jvmg:虚拟机位置

  • 如果按照Java虚拟机(HOTSPOT)源代码编译步骤进行代码编译,下面的操作之前,请切换到root用户。

解压缩调试符号:

务必要把虚拟机目录下的libjvm.diz里的内容解压到虚拟机所在目录,做一次就可以,不需要每次调试都解压
/home/zxf/openjdk7/build-debug/hotspot/outputdir/linux_i486_compiler1/jvmg的libjvm.diz解压到当前目录中,否则只能进行表层调试,像Threads::create_vm无法break into进去

调试前导入变量:
请将下面shell中/home/zxf/换成你自己的openjdk7源代码目录

export LD_LIBRARY_PATH=/home/zxf/openjdk7/build-debug/hotspot/outputdir/linux_i486_compiler1/jvmg/ 
export JAVA_HOME=/home/zxf/openjdk7/build-debug/j2sdk-image/
export CLASSPATH=.:/home/zxf/openjdk7/build-debug/j2sdk-image/lib:/home/zxf/openjdk7/build-debug/j2sdk-image/jre/lib

开始调试:
jvmg目录下的gamma文件就是虚拟机程序

设置断点:
注意下面这个断点设置一定要让gdb开始调试了即r命令后才能设置上。

b Threads::create_vm

进入核心函数cream_vm

GDB调试命令  http://www.linuxidc.com/Linux/2017-01/139028.htm

强大的C/C++ 程序调试工具GDB  http://www.linuxidc.com/Linux/2016-09/135171.htm

Linux GDB调试 详述 http://www.linuxidc.com/Linux/2016-11/137505.htm

使用 GDB 恢复堆栈信息  http://www.linuxidc.com/Linux/2017-07/145508.htm

使用GDB命令行调试器调试C/C++程序 http://www.linuxidc.com/Linux/2014-11/109845.htm

GDB调试命令总结  http://www.linuxidc.com/Linux/2016-08/133988.htm

GDB调试工具入门  http://www.linuxidc.com/Linux/2016-09/135168.htm

使用GDB调试Python程序  http://www.linuxidc.com/Linux/2017-11/148329.htm

GDB 的详细介绍请点这里
GDB 的下载地址请点这里

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-12/149083.htm



3、在eclipse上调试hotspot源码

3-1、下载eclipse,安装C/C++插件

      到官网选择一个合适的eclipse下载:https://www.eclipse.org/downloads/eclipse-packages/?osType=linux&release=undefined

      这里下载的是eclipse-java-neon-1a-linux-gtk-x86_64.tar.gz:https://www.eclipse.org/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文件,测试程序如下:

[java]  view plain  copy
  1. package com.hotspot.test;  
  2. public class Test {  
  3.      public static void main(String[] args){  
  4.          System.out.println("hotspot test!");  
  5.      }  
  6. }  

      而运行正常,生成了Test.class文件,如下图:

4-2、修改hotspot工程调试参数

      在前面的5-3配置源码调试的配置上作如下修改;

      Arguments选项卡:

      com.hotspot.test/Test(注意在前面加上包名,然后是运行类)

      Environment选项卡, 修改变量:

      CLASSPATH=.:/root/workspace/TestHotspot/bin (java工程生成的bin目录,不包括包名目录) 

      保存后,点击调试运行hotspot工程,可以看到正常运行了上面的java工程文件,如下:


     

注意,如果有包名情况下,配置不对,调试运行会报"错误: 找不到或无法加载主类 **";

到这里,我们可以对hotspot虚拟机源码进行调试了……

 

【参考资料】

1、openjdk文档:openjdk/README-builds.html

2、在Ubuntu14下构建Hotspot并使用Eclipse调试:http://blog.csdn.net/faadfafasd/article/details/50539615



参考链接:

点击打开链接 :http://www.linuxidc.com/Linux/2015-05/117248.htm

点击打开链接 :http://www.cnblogs.com/ACFLOOD/p/5528035.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值