大家也可以看我的博客: openjdk7之编译和debug,这里格式更好。

为了更好的学习JDK、HotSpot等源码,需要能debug JDK、HotSpot等源码。本文主要讲述,怎么编译openjdk并debug相关源码。

在本文中,要编译的openjdk:openjdk-7u40-fcs-src-b43-26_aug_2013.zip

系统环境为ubuntu 16.04,uname -a:

Linux ddy-Aspire-V5-573G 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

编译

  1. 下载源代码

    openjdk的源码可以通过hg方式下载。  

    也可以从此处下载:openjdk源码  
  2. 安装引导JDK

    因为JDK中有很多代码是Java自身实现的,所以还需要一个已经安装在本机上可用的JDK,叫做“Bootstrap JDK”。我所选用的Bootstarp JDK是JDK1.6.0_45。  

java version "1.6.0_45"

Java(TM) SE Runtime Environment (build 1.6.0_45-b06)

Java HotSpot(TM) Server VM (build 20.45-b01, mixed mode)

JDK1.6.0_45下载地址:[jdk1.6.0_45.tar.gz][3] 3. 安装编译前的依赖环境 安装gcc、g++、make等   ``sudo apt-get install build-essential``   安装ant 1.7以上    ``sudo apt-get install ant``   安装XRender    ``sudo apt-get install libxrender-dev``    ``sudo apt-get install xorg-dev``    安装alsa    ``sudo apt-get install libasound2-dev``   Cups    ``sudo apt-get install libcups2-dev``    安装零碎的工具包    ``sudo apt-get install gawk zip libxtst-dev libxi-dev libxt-dev``   4. 配置编译脚本   将你的openjdk解压后,并进入该文件夹。比如我的是在/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk 下。新建一个build.sh,并添加如下内容:   bash

export LANG=C

#将一下两项设置为你的BootstrapJDK安装目录

export ALT_BOOTDIR=/home/ddy/jdk1.6.0_45

export ALT_JDK_IMPORT_PATH=/home/ddy/jdk1.6.0_45

#允许自动下载依赖包

export ALLOW_DOWNLOADS=true

#使用预编译头文件,以提升便以速度
export USE_PRECOMPILED_HEADER=true #要编译的内容,我只选择了LANGTOOLS、HOTSPOT以及JDK
export BUILD_LANGTOOLS=true
export BUILD_JAXP=false
export BUILD_JAXWS=false
export BUILD_CORBA=false
export BUILD_HOSTPOT=true
export BUILD_JDK=true #要编译的版本
export SKIP_DEBUG_BUILD=false
export SKIP_FASTDEBUG_BUILD=true
export DEBUG_NAME=debug #避免javaws和浏览器Java插件等的build
BUILD_DEPLOY=false #不build安装包
BUILD_INSTALL=false #包含全部的调试信息
export ENABLE_FULL_DEBUG_SYMBOLS=1
#调试信息是否压缩,如果配置为1,libjvm.debuginfo会被压缩成libjvm.diz,将不能被debug。
export ZIP_DEBUGINFO_FILES=0
#用于编译线程数
export HOTSPOT_BUILD_JOBS=3 #设置存放编译结果的目录
#export ALT_OUTPUTDIR=/home/ddy/openjdk/7/build unset CLASSPATH
unset JAVA_HOME
make sanity
DEBUG_BINARIES=true make 2>&1
```

5.开始编译

在openjdk目录下,运行build.sh

bash chmod +x build.sh ./build.sh

最后编译耗时将近2分钟。编译完成输出如下信息:



此时openjdk就编译完成了,编译的输出在/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/下。

进入/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2re-image/bin n,执行

./java -version

输出的java版本信息将是带着你的机器用户名,我的输出是:

bash openjdk version "1.7.0-internal-debug" OpenJDK Runtime Environment (build 1.7.0-internal-debug-ddy_2017_06_10_22_30-b00) OpenJDK 64-Bit Server VM (build 24.0-b56-jvmg, mixed mode)

debug

编译完成了之后,就可以对JDK源码和HotSpot源码等进行debug了。

JDK

首先是JDK源码,在build目录下编译生成的jdk里面的jar包都是可编译的了,直接把eclipse的JDK或者JRE换成编译成功的JDK或者JRE即可。

HotSpot

注意,如果不能进入断点,出现以下类似信息:

Missing separate debuginfo for/root/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/lib/amd64/server/libjvm.so

是因为在编译时因为编译配置项不正确而没有生成调试的符号信息,或生成后被压缩为"libjvm.diz"了,所以无法找到。如果是因为没有编译时没有生成调试信息,需要修改编译配置并重新编译。对于被压缩的情况,可以去到"libjvm.so"所在目录

  • 然后解压:unzip libjvm.diz
  • 解压出来:libjvm.debuginfo

如果在编译时,把配置信息修改如下,则不会出现不能上述问题。

#包含全部的调试信息
export ENABLE_FULL_DEBUG_SYMBOLS=1
#调试信息是否压缩,如果配置为1,libjvm.debuginfo会被压缩成libjvm.diz,将不能被debug。
export ZIP_DEBUGINFO_FILES=0

使用GDB

参考:CentOS上编译OpenJDK8源码 以及 在eclipse上调试HotSpot虚拟机源码

使用eclipse

  1. 生成要运行的JAVA类

    首先在/home/ddy/src/java-src目录下建立要运行的FileChannelTest.java,这个类在写文件时调用了JDK的native方法,其代码如下:  

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.RandomAccessFile;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

public class FileChannelTest {

public static void main(String[] args) throws IOException {

FileChannel channel=new RandomAccessFile("test.txt","rw").getChannel();

ByteBuffer buffer=ByteBuffer.allocate(1000);

channel.write(buffer);

}

}

然后对其进行编译,运行:   bash

ddy@ddy-Aspire-V5-573G ~ $ cd src/java-src/

ddy@ddy-Aspire-V5-573G ~/src/java-src $ pwd

/home/ddy/src/java-src

ddy@ddy-Aspire-V5-573G ~/src/java-src $ /home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image/bin/javac FileChannelTest.java

```

  1. 下载eclipse,安装C/C++插件 

    到官网选择一个合适的eclipse下载,因为本人主要进行JAVA开发,所以下载的是j2EE版本,这个版本没有C/C++的功能。不过可以安装插件使其支持C/C++功能。"help -> Eclipse Maketplace",搜索"c++"找到Eclipse C++ IDE..安装。安装后,就可以转到C++开发视图界面了。

  2. 导入hotspot工程

    File-> New -> Makefile Project With Existing Code

    在界面中:

    Project Name:openjdk(这个可以自己选择)

    Existing Code Location:/root/openjdk

    Toolchain:选Linux GCC,然后按Finish.

  3. 配置源码调试

    1. 右键工程 -> Debug As -> Debug Configurations -> 右键左边的C/C++ Application -> New -> 进入Main选项卡;

      在选项卡中:

      Project: openjdk(选择导入的openjdk工程)

      C/C++ Application: /home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image/bin/java(编译生成的openjdk虚拟机入口)

      Disable auto build:因为不再在eclipse里面编译hotspot源码,所以这里选上它;
    2. 然后切换到Arguments选项卡, 输入Java参数, 这里填上 "FileChannelTest"也就是我们要执行的JAVA程序。
    3. 然后切换到Environment选项卡, 添加变量

      JAVA_HOME=/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/build/linux-amd64-debug/j2sdk-image(编译生成JDK所在目录)

      CLASSPATH=.:/home/ddy/src/java-src (FileChannelTest.java文件所在目录)

      点击下面的Apply保存;
    4. 断点Debug

       下面分别在源码上打两个断点:
    • init.cpp(/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/hotspot/src/share/vm/runtime目录下) 95行
    • FileDispatchImpl.c(/home/ddy/openjdk-compile/openjdk-7u40-fcs-b43-26/openjdk/jdk/src/solaris/native/sun/nio/ch目录下) 107行
  4. 然后开始debug。

    首先是第一个断点:

    F8进行到下一个断电点:

    从上图可以看到,FileChannel.write()最后调用的是write()操作系统调用。

    所以,大家现在可以随便debug HotSpot的源码和JDK的native源码了。酷!

参考资料

openjdk之编译经常出现的问题

openjdk8的编译和debug

编译主要参考:ubuntu14.04 编译openjdk7

debug主要参考:CentOS上编译OpenJDK8源码 以及 在eclipse上调试HotSpot虚拟机源码

openjdk7之编译和debug的更多相关文章

  1. openjdk8之编译和debug

    系统环境为ubuntu 16.04,uname -a: Linux ddy-Aspire-V5-573G 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:3 ...

  2. vs2010 创建预编译头 Debug 正常 Release Link Error问题解决

    问题:创建预编译头 Debug 正常 Release Link Error Main.obj : error LNK2005: ___@@_PchSym_@00@UmfilkilqUdrmzkkUki ...

  3. 创建预编译头 Debug 正常 Release Link Error:预编译头已存在,使用第一个 PCH

    创建预编译头 Debug 正常 Release Link Error Main.obj : error LNK2005: ___@@_PchSym_@00@UmfilkilqUdrmzkkUkilqU ...

  4. VS2015 dlib编译 x64 Debug .lib生成

    VS2015 dlib编译 x64 Debug >------ 已启动生成: 项目: ZERO_CHECK, 配置: Debug x64 ------ > Checking Build S ...

  5. 如何在其他电脑上运行VS2005编译的DEBUG版应用程序

    做项目的过程中,遇到这样的问题:在自己的电脑上用VS2005编译好的DEBUG版程序在其它的没有安装VS2005的电脑上没有办法运行,郁闷至极啊. 直 接拷贝文件后,错误信息如下:"This ...

  6. 在用VC编译下debug和release的什么区别

    DEBUG和RELEASE 版本差异及调试相关问题:.         内存分配问题 1.          变量未初始化.下面的程序在debug中运行的很好. thing * search(thin ...

  7. Keil中使用宏编译来定义DEBUG输出

    使用宏编译来格式化调试信息,是一个不错的方法,即可以在需要的时候打印出信息,还可以格式化我们所需要的输出. #define DEBUG 1 #if (DEBUG == 1) #define DBG(A ...

  8. windows下vc编译和debug nginx

    总体来说,各个步骤以及版本参考官方文档http://nginx.org/en/docs/howto_build_on_win32.html一点没错,有些细节没说清楚. To build nginx: ...

  9. JVM源码分析-JVM源码编译与调试

    要分析JVM的源码,结合资料直接阅读是一种方式,但是遇到一些想不通的场景,必须要结合调试,查看执行路径以及参数具体的值,才能搞得明白.所以我们先来把JVM的源码进行编译,并能够使用GDB进行调试. 编 ...

随机推荐

  1. 多个git账号的SSH配置

    一般使用git都只需要维持一个默认的git账户就可以打天下了. 但如果自己确实需要多个git账号的需求的话,就有必要配置多个ssh key了. 首先为生成多个ssh key ssh-keygen -t ...

  2. 【原】Unity Shader VS UDK Material Editor

    UDK 的材质编辑器十分好用,毕竟是所见即所得的.虽然unity也有类似第三方插件,但易用性还是差很多,下面主要是,把一些常见表达式概念对应起来. 1. UDK CameraVector (相机位向量 ...

  3. LinkCode 第k个排列

    http://www.lintcode.com/zh-cn/problem/permutation-sequence/# 原题 给定 n 和 k,求123..n组成的排列中的第 k 个排列. 注意事项 ...

  4. Javascript中变量作用域(2)

    多层函数调用取变量时,无论在哪里调用,要到创建此函数的作用域中取值,如果找不到再往上一级,直到全局变量. 外面定义了很多的全局的变量,下面我们来一个个理一下. 定义三个变量a,b,c;将A1函数赋值给 ...

  5. js表白心形特效

    好久没有仔细钻研技术了,闲下来借鉴一下做出一些效果 友情链接: http://tiepeng.applinzi.com/love_you/ ;;background:#ffe;font-size:12 ...

  6. bzoj4817 [Sdoi2017]树点涂色

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  7. DCalendar增加月份选择功能--简单jQuery日期选择器插件改动

    做时间插件的时候,很多都会遇到要做选择月份的插件,但是DCalendar提供的api只支持日期选择,最近遇到这个问题,所以调整了一下源码,话不多说,先看效果吧 点击日期插件,出现上图,再点击月份就直接 ...

  8. Adline网络的LMS算法与梯度下降

    LMS算法,即为最小均方差,求的是误差的平方和最小. 利用梯度下降,所谓的梯度下降,本质上就是利用导数的性质来求极值点的位置,导数在这个的附近,一边是大于零,一边又是小于零的,如此而已... 而这个里 ...

  9. 关于使用JavaScript实现图片点击切换(附带改变导航图片 方案二)

    具体需求见方案一. 这种方案相比方案一更加专业. <!DOCTYPE html> <html> <head lang="en"> <met ...

  10. jQuery选择器---基本选择器总结

    今天要跟大家分享一下jQuery选择器的使用方法,它的选择器分为四大类 如图: 基本选择器的使用: 1.id选择器 案例: <div id="notMe"><p& ...