编绎调试HotSpot JVM及在Eclipse里调试

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

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

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

一、编绎

进入hotsopt的make目录下:

cd code/cpp/openjdk/hotspot/make/

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

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

设置环境变量:

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调试时,就会出现下面的提示:

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 的程序。

+ 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的了:

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
}

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

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版,或者安装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相关的段。这个方法不一定准确,因为调试信息有可能放在外部文件里。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
2月前
|
存储 缓存 安全
深入理解JVM - Hotspot算法细节
深入理解JVM - Hotspot算法细节
36 0
|
9月前
|
算法 Oracle Java
HotSpot 算法实现在 JVM 中的应用
HotSpot 算法实现在 JVM 中的应用
113 0
|
5月前
|
Oracle Java 关系型数据库
深入理解JVM系列教程(01) - HotSpot VM
深入理解JVM系列教程(01) - HotSpot VM
122 0
|
7月前
|
Java Android开发
在用 Eclipse 搭建 SAP Commerce Cloud 调试环境时,错误和正确的 buildfile
在用 Eclipse 搭建 SAP Commerce Cloud 调试环境时,错误和正确的 buildfile
43 0
|
7月前
|
Android开发
SAP Hybris Commerce Cloud Accelerator Storefront 在 Eclipse 中的调试
SAP Hybris Commerce Cloud Accelerator Storefront 在 Eclipse 中的调试
30 0
|
存储 算法 安全
JVM:HotSpot虚拟机----对象的创建简单介绍及对象内存布局详解
JVM:HotSpot虚拟机----对象的创建简单介绍及对象内存布局详解
146 0
JVM:HotSpot虚拟机----对象的创建简单介绍及对象内存布局详解
|
10月前
|
运维 监控 数据可视化
JVM调试命令与调试工具
JVM调试命令与调试工具
173 0
|
10月前
|
NoSQL IDE 开发工具
Eclipse配合GDB和jlinkGDBServer仿真调试STM32
Eclipse配合GDB和jlinkGDBServer仿真调试STM32
|
10月前
|
存储 缓存 安全
《深入理解Java虚拟机》读书笔记(六)--HotSpot的算法细节实现
《深入理解Java虚拟机》读书笔记(六)--HotSpot的算法细节实现
174 0
《深入理解Java虚拟机》读书笔记(六)--HotSpot的算法细节实现
|
11月前
|
存储 缓存 安全
深入理解JVM - Hotspot算法细节
​ 这一节来专门讨论一下HotSpot的算法的细节内容,内容说难也不难,说容易也确实不容易,有很多要理解的内容,个人在写这次文章的时候,有了更深的理解。
307 0

推荐镜像

更多