




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在Linux下编译OpenJdk并调试Hotspot 分类: java 2011-11-24 12:16 4979人阅读 评论(1) 收藏 举报 linuxnetbeansjavamakefilex86compiler目录(?)+1. 背景2. 概念3. Linux下Build Open Jdk 7和Debug Hotspot背景对于大多数Java程序员来说,JVM就是一个黑盒子,我们一般不必关心它内部是怎么运作的。但是万一碰到JVM bug导致的Crash呢,又或者只是因为好奇想了解JVM的内部世界,那么就需要编译和调试JVM。概念1. JVM(Java Virtual Machine) 翻译过来就是Java虚拟机,所谓虚拟机是相对传统的计算机而言的。 传统的计算机有很多体系架构,比如x86,Sparc等等;一个体系架构一般有类似的指令集,比如586兼容所有386的指令集,但是又有自己扩充的指令。在Java出现之前,大部分编译型语言(我不知道是不是所有的)都会由编译器把源代码编译成特定机器下特定指令集的机器指令。从理论上来说所有的机器的表达能力都是一样的,等价于图灵机这个理论模型。但是就具体实现而言,在不同机器实现同一个逻辑的机器指令是不同的,这就导致在一台机器编译的二进制文件可能无法在另一台机器上运行(这里不考虑操作系统的差异)。当然写得比较好的c代码是可以在不同平台编译,但是一般不太可能把一个windows下的exe程序让linux运行。(当然除了机器指令的差别,不同系统的二进制格式也是不能兼容的,比如windows pe和linux elf)。即使同一个操作系统,比如linux,在x86下编译的程序也是没办法在Sparc下跑的,因为Sparc根本不认识x86的指令。 JVM就是一个虚拟机,它定义了自己的指令集(Java字节码),所有的Java程序编译成统一的字节码,然后JVM负责在不同的硬件和操作系统下解释或者编译字节码。 JVM本身只是一个概念,一种抽象2. JRE(Java Runtime Environment) Java运行时环境,首先必须实现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.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编译器。和vc或者gcc一样,必须要有工具把源代码编译成目标代码,c的目标代码是机器相关的,而Java的目标代码就是字节码。* *当然实现javac就是实现一个传统的编译器,词法分析,语法分析和语义分析,然后翻译成字节码。这本身不是件简单的事情,所以编译器的开发者也开发了一些帮助开发编译器的工具,比如我们熟悉的lex/flex,yacc/bison。java也实现了类似的JavaCC和JFlex。 除了javac,javadoc和javah也是很常用的工具。此外Java的新特性,比如范型(Generics)和注解(Annotations),这些也需要由编译器来处理。(范型只影响编译,编译后被擦除了,但是Annotation可能会运行时能通过反射获取)。这些代码一般都是Java实现,打包到tools.jar。所以如果你需要动态编译Java代码(比如JSP),那么你可能要用到tools.jarLinux下Build Open Jdk 7和Debug Hotspot 下面的内容大部分参考下面两篇文章: /blog/simonis/archive/2008/01/hotspot_develop.html /blog/simonis/archive/2008/01/hotspot_develop_1.html 不过在用NetBeans调试Hotspot时碰到了一些问题(可能是我用了比较新的netbeans的缘故),之前问过作者,不过没有得到满意的解答,后来自己使用了一些trick的手段。1. 获取源代码 两种方法 1.1 使用Mercurial 获取最新代码(其实就是svn git这样的scm工具) /jdk7/build/raw-file/tip/README-builds.html 速度比较慢,可能要花几个小时吧,如果你需要最新代码又不想等,可以找我 1.2 直接下载压缩的源代码包 /openjdk/jdk7/ 解压后就可以了,如果想更新代码,也可以运行 sh ./getSource.sh更新 1.3 源代码结构 hotspot hotspot的源代码,完整的工程,包括makefile,文件按平台分类,比如 hotspot/src下有4个目录:os cpu os_cpu share 很明显,share放的是于平台无关的代码,os里放的是特定os的代码,cpu放的是特定cpu的代码,os_cpu放的是特定os和cpu的代码 jdk java api的代码,如果我们对jdk的代码感兴趣,比如想看ConcurrentHashMap的实现,那么可以去src/share/classes/java/util/concurrent/ConcurrentHashMap.java 它的目录结果是 share,linux,solaris和windows,和前面类似,share放的是操作系统无关的代码,一般是用Java实现。Windows当然放的是windows的实现,不过*nix的都是放到solaris下实现的,不同的操作系统通过不同的#define区别,所以大部分代码都在solaris下,linux目录下只有一些文档。大部分代码都是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没有版权的代码,你必须自己从网上下载(或者通过Linux发行版的仓库安装) 由于我的机器很早以前编译的,当时编译时少一个装一个,所以忘了要装哪些了,碰到问题的可以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=falseexport 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等等 lib jar包,比如tools.jar hotspot 我们最感兴趣的jvm,具体运行和调试会在下面介绍 classes java api部分,包括按包组织的java类 2.3 运行一下自己编译的jdk lililili-desktop:/media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-image$ ./bin/java -versionopenjdk version 1.7.0-internal-debugOpenJDK Runtime Environment (build 1.7.0-internal-debug-lili_2011_11_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的代码,当然可以重新编译整个JDK,但这太慢,我们可以只重新编译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和product1 2.5 运行hotspot* *需要增加两个环境变量LD_LIBRARY_PATH和JAVA_HOME,前者参考下面,里面包含我们编译好的libjvm.so,后者可以用我们自己编译的jdkexport LD_LIBRARY_PATH=/media/d/openjdk7zip/openjdk/build/hotspot_debug/linux_i486_compiler1/jvmgexport JAVA_HOME=/media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-imagecd /media/d/openjdk7zip/openjdk/build/hotspot_debug/linux_i486_compiler1/jvmglililili-desktop:/media/d/openjdk7zip/openjdk/build/hotspot_debug/linux_i486_compiler1/jvmg$ ./gamma -versionlililili-desktop:/media/d/openjdk7zip/openjdk/build/hotspot_debug/linux_i486_compiler1/jvmg$ ./gamma -versionUsing java runtime at: /media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-image/jreopenjdk version 1.7.0-internal-debugOpenJDK Runtime Environment (build 1.7.0-internal-debug-lili_2011_11_14_12_30-b00)OpenJDK Client VM (build 21.0-b17-internal-jvmg, mixed mode)Using java runtime at: /media/d/openjdk7zip/openjdk/build/linux-i586-debug/j2sdk-image/jreopenjdk version 1.7.0-internal-debugOpenJDK Runtime Environment (build 1.7.0-internal-debug-lili_2011_11_14_12_30-b00)OpenJDK Client VM (build 21.0-b17-internal-jvmg, mixed mode2.6 使用gdb调试hotspot 前面我们编译出来的hotspot已经是带有调试符号,所以可以使用gdb来调试了。gdb ./gammaGNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2.(gdb) break main(gdb) rStarting program: /media/d/openjdk7zip/openjdk/build/hotspot_debug/linux_i486_compiler1/jvmg/gammaThread debugging using libthread_db enabledBreakpoint 1, main (argc=1, argv=0xbffff1a4) at /media/d/openjdk7zip/openjdk/hotspot/src/share/tools/launcher/java.c:228228 (gdb) (gdb) 可以看到,gamma测试程序的入口是hotspot/src/share/tools/launcher/java.c。 2.7 使用Netbeans调试hotspot 对于习惯GNU/Linux环境开发的c程序员来说,有源代码和Makefile,再配合vim或者emacs,使用它们的插件比如cscope来阅读代码,gdb来调试程序,是件很自然的事情。 不过对于习惯的IDE的Java程序员来说,这确实有的不爽。估计Sun的人也是这样的,所以他们内部是使用Netbeans来调试hotspot的。 HotSpot development on Linux with NetBeans - Part 2这篇blog是基于Netbeans6,里面很多都是为了解决nb的bug,我使用的是Netbeans7,所以很多bug已经修正。 2.7.1 NB项目设置 新建项目-C/C+-基于现有源代码的C/C+项目 指定包含源代码的目录:/media/d/openjdk7zip/openjdk/hotspot,由于makefile不在这个目录下,而是在它的子目录下,所以选择“定制”模式。 然后选择好Makefile的位置。下一步进入build的配置 make的工作目录是make, 生成命令是$MAKE-f Makefile jvmg, 清理命令是$MAKE-f Makefile clean, 生成结果填写一个目录就可以了。 然后点击确定就会buildhotspot,不过这样会出现问题,因为缺少ALT_BOOTDIR环境变量,但是Netbeans好像只能设置运行时的环境变量,而不能设置build时的环境变量,参考这篇文章/post-40251.html。我折腾了好久也没有搞定,最后也没搞定。最后只能使了个毛招: 因为它默认去/java/re/j2se/1.6.0/latest/binaries/linux-i586找jdk,所以可以建个符号链接lililili-desktop:/java/re/j2se/1.6.0/latest/binaries$ ll linux-i586lrwxrwxrwx 1 lili lili 28 Nov 14 18:14 linux-i586 - /home/lili/java/jdk1.6.0_26/ 这下可以点击确定,让它build。 2.7.2 删除“无用”的文件 因为hotspot是跨平台的项目,前面可以看到针对不同的平台会有不同的实现,但是很多文件是相同的,比如文件名相同,因此同一个方法可能在linux里有个实现,windows有个实现, 这样NB就不知道到底会是哪个了,这会对Code Assistance带来影响,另外我们查看定义也会带来问题。所以针对Linux平台,我们可以在NB里删除不需要的文件(这不是删除磁盘上的文件,而是在NB里删除) 可以删除的目录: hotspot/agent/src/os/solarishotspot/agent/src/os/win32hotspot/agent/src/share/native/jvmdihotspot/src/cpu/sparchotspot/src/os/solarishotspot/src/os/windowshotspot/src/os_cpu/solaris_sparchotspot/src/os_cpu/solaris_x86hotspot/src/os_cpu/windows_x86hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpphotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp 可以删除的文件(我的机器是x86,所以把x86-64的那些文件可以删掉): hotspot/src/cpu/x86/vm/assembler_x86_64.cpphotspot/src/cpu/x86/vm/assembler_x86_64.hpphotspot/src/cpu/x86/vm/assembler_x86_64.inline.hpphotspot/src/cpu/x86/vm/dump_x86_64.cpphotspot/src/cpu/x86/vm/interp_masm_x86_64.cpphotspot/src/cpu/x86/vm/interp_masm_x86_64.hpphotspot/src/cpu/x86/vm/interpreterRT_x86_64.cpphotspot/src/cpu/x86/vm/interpreter_x86_64.cpphotspot/src/cpu/x86/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 石大学前儿童保育学课件1-7眼睛耳神经
- 云安全与边缘计算的协同防护-洞察阐释
- 遗传学课程内容更新与跨学科融合的创新模式
- 激励社会力量参与老年助餐服务的可行路径
- 心理健康课思维导图
- 2025至2030年中国波导合分路器行业投资前景及策略咨询报告
- 2025至2030年中国水瓶座图案拼图行业投资前景及策略咨询报告
- 2025至2030年中国气密测试机行业投资前景及策略咨询报告
- 2025至2030年中国橙柑桔清洗打蜡机行业投资前景及策略咨询报告
- 2025至2030年中国木炭烘干机行业投资前景及策略咨询报告
- 植物拓染非物质文化遗产传承拓花草之印染自然之美课件
- TD/T 1044-2014 生产项目土地复垦验收规程(正式版)
- 雾化吸入团体标准解读
- MOOC 质量工程技术基础-北京航空航天大学 中国大学慕课答案
- 【数字人民币对货币政策的影响及政策探究12000字(论文)】
- 江苏省盐城市大丰区2023-2024学年八年级上学期期中数学试题(解析版)
- 内分泌系统疾病教学设计教案1
- 卫生监督协管培训课件
- 2.3.5 重力坝扬压力计算示例讲解
- 高校资助育人系列活动方案
- 售票员岗前培训
评论
0/150
提交评论