编绎整个OpenJDK要很久,而且有很多东西是不需要的。研究HotSpot的话,其实只要下HotSpot部分的代码就可以了。

下面简单记录下编绎调试HotSpot一些步骤。

一、编绎

进入hotsopt的make目录下:

1
cd code/cpp/openjdk/hotspot/make/

用make help可以看到有很多有用的信息。当然查看Makefile文件,里面也有很多有用的注释。

make help会输出当前的一些环境变量的设置,如果不对,自然编绎不过去。

设置环境变量:

1
2
3
4
5
unset JAVA_HOME
export ARCH_DATA_MODEL=64
export JDK_IMPORT_PATH=/usr/lib/jvm/java-7-oracle
export ALT_BOOTDIR=/usr/lib/jvm/java-7-oracle
export ZIP_DEBUGINFO_FILES=0                      //这个貌似不起作用。。这些变量的定义貌似都在def.make文件里。还有一个这样的参数:FULL_DEBUG_SYMBOLS

用make all_beug来编绎。

编绎后好,到目录下openjdk/hotspot/build/Linux/linux_amd64_compiler2/jvmg,执行 unzip libjvm.diz,解压得到调试信息文件

这个算是个坑,默认情况下,会压缩调试信息文件,这样用gdb调试时,就会出现下面的提示:

1
no debugging symbols found

从编绎的输出信息来看,是有一个ZIP_DEBUGINFO_FILES的参数,但是设置了环境变量却不起效。

二、调试

在 openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg 目录下,有一个hotspot的脚本,只要执行这个脚本,就可以启动Java进程了。

用 ./hotspot -gdb 就会自动进入gdb调试,并停在main函数入口。

后面还可以加一些jvm的启动参数等。

这个./hotsopt 脚本是怎么工作的?

用 sh -x ./hotspot 来查看这个脚本的执行过程,可以发现实际上是设置了 LD_LIBRARY_PATH的环境变量,再调用了一个./gamma 的程序。

1
2
3
4
5
6
7
8
9
10
+ LD_LIBRARY_PATH=/home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg:/usr/lib/jvm/java-7-oracle/jre/lib/amd64
+ export LD_LIBRARY_PATH
+ JPARMS=
+ LAUNCHER=/home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg/gamma
+ [ ! -x /home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg/gamma ]
+ GDBSRCDIR=/home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg
+ cd /home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg/../../..
+ pwd
+ BASEDIR=/home/hengyunabc/code/cpp/openjdk/hotspot/build
+ LD_PRELOAD= exec /home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg/gamma

实际上是通过设置LD_LIBRARY_PATH 环境变量,去优先加载编绎好的libjvm.so。hotsopt jvm的代码都编绎链接在libjvm.so这个文件里。

查看./hotspot里的这个函数init_gdb,就知道它是怎么启动并设置好gdb的了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
init_gdb() {
# Create a gdb script in case we should run inside gdb
    GDBSCR=/tmp/hsl.$$
    rm -f $GDBSCR
    cat >>$GDBSCR <<EOF
cd `pwd`
handle SIGUSR1 nostop noprint
handle SIGUSR2 nostop noprint
set args $JPARMS
file $LAUNCHER
directory $GDBSRCDIR
# Get us to a point where we can set breakpoints in libjvm.so
break InitializeJVM
run
# Stop in InitializeJVM
delete 1
# We can now set breakpoints wherever we like
EOF
}

所以,其实也可以这样开始调试。

1
2
export LD_LIBRARY_PATH=/home/hengyunabc/code/cpp/openjdk/hotspot/build/linux/linux_amd64_compiler2/jvmg:/usr/lib/jvm/java-7-Oracle/jre/lib/amd64
gdb

在gdb里执行file ./gamma,然后就可以调试了。

三、使用Eclipse来调试

尽管gdb功能强大,命令丰富,但是在查看调试的变量时,十分的不方便。特别是hotsopt里,很多东西都是用指针来存放的,有时要跳转好几层才能查看到想要的信息。

下载Eclipse的CDT版,新视觉影院6080或者安装CDT的插件。

导入Eclipse工程:

“File”, “Import”, “C/C++”, “Existing Code as Makefile Project”:

先择Linux GCC:

然后,就可以把项目导到Eclipse里了。会有很多错误提示,但是不影响我们的调试。

在Eclipse里调试:

首先,要设置要调试的文件的路径:

设置LD_LIBRARY_PATH:

然后就可以调试了。还有一个地方比较重要:

想在运行时输入gdb指令,可以在console view,在右边的下拉里,可以发现有一个gbd的console,还有一个gdb trace的console。 

四、一些有用的东东

jvmg1目录下是O1优化下的,fastdebug目录下是O3优化的。

java 进程的main入口在:openjdk/hotspot/src/share/tools/launcher/java.c 文件里。

在gdb里,用info sharedlibrary 命令查看实际使用到的是哪些so文件。

用file命令来判断一个可执行文件,so是32位的还是64位的。

查看一个so文件是否包含调试信息,可以用readelf -S xxx.so 命令来查看是否有debug相关的段。这个方法不一定准确,因为调试信息有可能放在外部文件里。

编绎调试HotSpot JVM及在Eclipse里调试HotSpot一些步骤的更多相关文章

  1. windows Service 之调试过程(附加到进程里调试,而且启动时间不能超过30秒)

    最近第一次用C#写了一个windows service ,其实实现的内容比较简单.就是启动remoting 连接,但是调试相对初次写windws service 的我来说,比较烦.没有经验,而且没办法 ...

  2. 怎么在eclipse里调试WebDriver的源代码(转)

    当你看完WebDriver的工作原理这篇博客以后,是不是也跃跃欲试想印证文章里的理论是不是正确,想自己也看下webdriver的源代码,并且调试下,通过代码来更深入的了解WebDriver的工作原理. ...

  3. 怎么在eclipse里调试WebDriver的源代码

    当你看完WebDriver的工作原理这篇博客以后,是不是也跃跃欲试想印证文章里的理论是不是正确,想自己也看下webdriver的源代码,并且调试下,通过代码来更深入的了解WebDriver的工作原理. ...

  4. Eclipse远程调试Java代码的三种方法

    Eclipse远程调试Java代码的三种方法, 第1种方法是用来调试已经启动的Java程序,Eclipse可以随时连接到远程Java程序进行调试, 第2种方法可以调试Java程序启动过程,但是Ecli ...

  5. HotSpot JVM常用参数设置

    转自:https://www.zybuluo.com/jewes/note/57352 选项的分类 Hotspot JVM提供以下三大类选项: 1. 标准选项:这类选项的功能是很稳定的,在后续版本中也 ...

  6. HotSpot JVM常用参数(选项)设置

    本文讨论的选项是针对HotSpot虚拟机的. 1.选项分类及语法 HotspotJVM提供以下三大类选项: 1.1.标准选项 这类选项的功能是很稳定的,在后续版本中也不太会发生变化. 运行java或者 ...

  7. HotSpot JVM 常用配置设置

    本文讨论的选项是针对HotSpot虚拟机的. 1.选项分类及语法 HotspotJVM提供以下三大类选项: 1.1.标准选项 这类选项的功能是很稳定的,在后续版本中也不太会发生变化. 运行java或者 ...

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

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

  9. Android动态方式破解apk前奏篇(Eclipse动态调试smail源码)

    一.前言 今天我们开始apk破解的另外一种方式:动态代码调试破解,之前其实已经在一篇文章中说到如何破解apk了: Android中使用静态方式破解Apk  主要采用的是静态方式,步骤也很简单,首先使用 ...

随机推荐

  1. 如何在cmd查看文件内容的md5值

    在cmd下进入 要查看的文件目录 默认目录是c,切换到其他盘符例如: C:\D: 就会切换到D盘 D:\ 然后输入命令 certutil -hashfile  文件名称.文件类型 MD5 如 cert ...

  2. 如何变更站点 AD 域服务器IP地址

    在 winserver 2012  单森林单域,多站点环境中,想把某一个站点AD 域服务器IP地址更改,要如何操作,才能保证客户端正常运行,不影响客户端的运行.有些朋友也经常提出类似问题. 想在不影响 ...

  3. 洛谷 P2905 [USACO08OPEN]农场危机Crisis on the Farm

    题目描述 约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每一堆里,30只奶牛一只踩在另一只的背上,叠成一座牛塔.牧场 里还有M(1 < ...

  4. Zero to One书摘

    之所以叫书摘,是因为翻译不像翻译,书评不像书评,更像是把觉得有意义的部分摘抄下来. 第一章,未来的挑战 如何定义未来? 大部分人定义的未来都只是现在的简单延伸而已,其实技术的改变是人们无法预料的.   ...

  5. Python-OpenCV——Image inverting

    通常我们将读入的彩色图转化成灰度图,需要将灰度图反转得到掩码,如何正确快速的得到某个图像的反转图呢? 首先看一种看似很正确的写法,对其中每个像素进行如下处理: img[x,y] = abs(img[x ...

  6. python_81_标准库_时间模块

    ''' 标准库: 1.time 时间的三种表示方法:a:时间戳(timestamp) b:格式化的时间字符串 c:元组(struct_time)共九个元素 time.struct_time(tm_ye ...

  7. VueJS坎坷之路111---_self.$scopedSlots.default is not a function

    VueJs + Element 话不多说,直接贴错: _self.$scopedSlots.default is not a function <el-table stripe border r ...

  8. hash 哈希查找复杂度为什么这么低?

    hash 哈希查找复杂度为什么这么低? (2017-06-23 21:20:36) 转载▼   分类: c from: 作者:jillzhang 出处:http://jillzhang.cnblogs ...

  9. 201621123080《Java程序设计》第9周学习总结

    作业09-集合与泛型 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1. List中指定元素的删除(题集题目) 1.1 实 ...

  10. Python学习笔记:xlrd和xlwt(Excel读写)

    xlrd模块 Python的三方库xlrd用于对excel文件进行读取,可以是“.xls”或“.xlsx”格式(旧版本可能不支持“.xlsx”). 下载安装:https://pypi.org/proj ...