编译调试openjdk

上传人:wt****50 文档编号:39737827 上传时间:2018-05-19 格式:DOCX 页数:8 大小:29.77KB
返回 下载 相关 举报
编译调试openjdk_第1页
第1页 / 共8页
编译调试openjdk_第2页
第2页 / 共8页
编译调试openjdk_第3页
第3页 / 共8页
编译调试openjdk_第4页
第4页 / 共8页
编译调试openjdk_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《编译调试openjdk》由会员分享,可在线阅读,更多相关《编译调试openjdk(8页珍藏版)》请在金锄头文库上搜索。

1、在 Linux 下编译 OpenJdk 并调试 Hotspot 分类: java 2011-11-24 12:16 4979 人阅读 评论(1) 收藏 举报 linuxnetbeansjavamakefilex86compiler目录(?)+1.背景背景对于大多数 Java 程序员来说,JVM 就是一个黑盒子,我们一般不必关心它内部是怎么运 作的。但是万一碰到 JVM bug 导致的 Crash 呢,又或者只是因为好奇想了解 JVM 的内部 世界,那么就需要编译和调试 JVM。概念概念1. JVM(Java Virtual Machine)翻译过来就是 Java 虚拟机,所谓虚拟机是相对传统的

2、计算机而言的。传统的计算机有很多体系架构,比如 x86,Sparc 等等;一个体系架构一般有类似的 指令集,比如 586 兼容所有 386 的指令集,但是又有自己扩充的指令。在 Java 出现之前, 大部分编译型语言(我不知道是不是所有的)都会由编译器把源代码编译成特定机器下特 定指令集的机器指令。从理论上来说所有的机器的表达能力都是一样的,等价于图灵机这 个理论模型。但是就具体实现而言,在不同机器实现同一个逻辑的机器指令是不同的,这 就导致在一台机器编译的二进制文件可能无法在另一台机器上运行(这里不考虑操作系统 的差异)。当然写得比较好的 c 代码是可以在不同平台编译,但是一般不太可能把一个

3、 windows 下的 exe 程序让 linux 运行。(当然除了机器指令的差别,不同系统的二进制格 式也是不能兼容的,比如 windows pe 和 linux elf)。即使同一个操作系统,比如 linux, 在 x86 下编译的程序也是没办法在 Sparc 下跑的,因为 Sparc 根本不认识 x86 的指令。JVM 就是一个虚拟机,它定义了自己的指令集(Java 字节码),所有的 Java 程序编 译成统一的字节码,然后 JVM 负责在不同的硬件和操作系统下解释或者编译字节码。JVM 本身只是一个概念,一种抽象2. JRE(Java Runtime Environment)Java

4、运行时环境,首先必须实现实现 JVM 规范规范,实现同样的 JVM 规范可以有很多方法, 比如 Sun 有 Sun 的实现,IBM 有 IBM 的实现。JVM 当然得实现 Java 语言,也就是 java.lang.*,认识 int,知道 class,方法,.但是如果你发现没有 java.util.* 或者没有 java.io.*时,是不是会发现没法写 Java 程序 了呢?没有 util,你当然可以自己实现那些常见的数据结构,这可以用 java 实现;那没有 io 呢?那似乎没法写出跨平台的代码了。所以除了实现语言本身,Java 还定义了很多跨平台的 API,比如 java.awt java

5、.io 等等。 这些可能是我们非常常用的,所以 Sun 把它们叫作了 Java Standard Edition(Java SE)。 一般以 java 开头另外有些 API,比如 JDBC,这是连接数据库的 API。这些组成了 Java Enterprise Edition(Java EE)。一般以 javax 包开头这些 API 有些是用 Java 实现,但很多不跨平台的必须由 C 实现(JVM 通过 JNI 规范 来实现 Java 和 c 的数据传递),所以 JRE 必须实现这些3. JDK(Java Development Kit)* *开发者的工具,最常用的就是 javac 编译器。和

6、 vc 或者 gcc 一样,必须要有工具把 源代码编译成目标代码,c 的目标代码是机器相关的,而 Java 的目标代码就是字节码。* *当然实现 javac 就是实现一个传统的编译器,词法分析,语法分析和语义分析,然 后翻译成字节码。这本身不是件简单的事情,所以编译器的开发者也开发了一些帮助开发 编译器的工具,比如我们熟悉的 lex/flex,yacc/bison。java 也实现了类似的 JavaCC 和 JFlex。除了 javac,javadoc 和 javah 也是很常用的工具。此外 Java 的新特性,比如范型 (Generics)和注解(Annotations),这些也需要由编译器

7、来处理。(范型只影响编译,编译 后被擦除了,但是 Annotation 可能会运行时能通过反射获取)。这些代码一般都是 Java 实现,打包到 tools.jar。所以如果你需要动态编译 Java 代码(比如 JSP),那么你可能要 用到 tools.jarLinux 下下 Build Open Jdk 7 和和 Debug Hotspot下面的内容大部分参考下面两篇文章:http:/ NetBeans 调试 Hotspot 时碰到了一些问题(可能是我用了比较新的 netbeans 的缘故),之前问过作者,不过没有得到满意的解答,后来自己使用了一些 trick 的手段。1. 获取源代码获取源代

8、码两种方法1.1 使用 Mercurial 获取最新代码(其实就是 svn git 这样的 scm 工具)http:/ 直接下载压缩的源代码包http:/ sh ./getSource.sh 更新1.3 源代码结构hotspothotspot 的源代码,完整的工程,包括 makefile,文件按平台分类,比如 hotspot/src 下有 4 个目录:os cpu os_cpu share很明显,share 放的是于平台无关的代码,os 里放的是特定 os 的代码,cpu 放的是特定 cpu 的代码,os_cpu 放的是特定 os 和 cpu 的代码jdk java api 的代码,如果我们对

9、 jdk 的代码感兴趣,比如想看 ConcurrentHashMap 的实现,那么可以去 src/share/classes/java/util/concurrent/ConcurrentHashMap.java它的目录结果是 share,linux,solaris 和 windows,和前面类似,share 放的是 操作系统无关的代码,一般是用 Java 实现。Windows 当然放的是 windows 的实现,不过 *nix 的都是放到 solaris 下实现的,不同的操作系统通过不同的#define 区别,所以大部分 代码都在 solaris 下,linux 目录下只有一些文档。大部分代

10、码都是 c 实现,然后通过 JNI 让 java 调用,所以大部分代码都在 native 下而不是 classes 下。langtool编译器工具,比如 javac,javah,apt 等等工具make makefile其它比如 jaxp,corba 等等,暂时不感兴趣 ./share/classes/java/util/concurrent/ConcurrentHashMap.java2. 编译和调试编译和调试大部分应该都装好了,比如 gcc,make,ant,bootstrap jdk,还有一些需要安装, 比如 cups 等 Sun 没有版权的代码,你必须自己从网上下载(或者通过 Linu

11、x 发行版的仓 库安装)由于我的机器很早以前编译的,当时编译时少一个装一个,所以忘了要装哪些了,碰 到问题的可以 google,也可以找我讨论(我也可能解决不了,我对 Linux 也不是很熟悉)可以使用 make sanity 测试,请设置如下的环境变量(我的是 bash): export LANG=Cunset JAVA_HOMEexport ALT_BOOTDIR=/home/lili/java/jdk1.6.0_26/export ALLOW_DOWNLOADS=trueexport USE_PRECOMPILED_HEADER=trueexport SKIP_DEBUG_BUILD=f

12、alseexport SKIP_FASTDEBUG_BUILD=trueexport DEBUG_NAME=debug 2.1 编译编译 JDK如果 make sanity 通过,那么直接运行 make,如果你想保留日志,那么可以 make 2&1 |tee /buildopenjdk7.log可能会碰到问题,需要你解决。如果顺利的话,几个小时后应该能编译好。2.2 编译结果编译结果费了这么大的力气,我们看看编译的成果。编译的结果放到了 build/linux-i586-debug 下,bin编译后的二进制文件,比如 java,javac 等等libjar 包,比如 tools.jarhots

13、pot我们最感兴趣的 jvm,具体运行和调试会在下面介绍classesjava api 部分,包括按包组织的 java 类2.3 运行一下自己编译的运行一下自己编译的 jdk lililili-desktop:/media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-image$ ./bin/java -version openjdk version “1.7.0-internal-debug“ OpenJDK Runtime Environment (build 1.7.0-internal-debug-lili_2011_11_14

14、_12_30-b00) OpenJDK Server VM (build 21.0-b17-jvmg, mixed mode) lililili-desktop:/media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-image$2.4 编译编译 hotspot 前面说过了,我们感兴趣的是 hotspot。如果想学习 util 里的实现,直接能看 java 代 码,如果想学习 io 或者 nio,那么可以直接看 native c 的实现(java 通过 JNI 调用)。比如我们修改了 hotspot 的代码,当然可以重新编译整个 JD

15、K,但这太慢,我们可以 只重新编译 hotspot 自己环境变量和前面一样,需要 ALT_BOOTDIR 和 ALT_OUTPUTDIR使用:cd hotspot/make & make jvmg jvmg1 target jvmg 会编译 Server 版本的 Hotspot,并且是带调试符号的,jvmg1 会编译 Client 版本的,同样也是带调试符号的。因为优化可能会调整代码顺序或者去掉一些无用 的代码等,这会给调试带来困难,所以如果我们是为了学习的话,用这两个 target 就好了。如果需要优化的版本可以用 target optimized 或者 optimized1,同样后面有 1 的表示 Client;产品的 target 是 product 和 product12.5 运行运行 hotspot* *需要增加两个环境变量 LD_LIBRARY_PATH 和 JAVA_HOME,前者参考下面,里 面包含我们编译好的 libjvm.so,后者可以用

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号