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

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

时间: 2024-08-03 01:42:06

编绎调试HotSpot JVM及在Eclipse里调试的相关文章

在Eclipse里调试JSP文件

在Eclipse里你可以调试java类文件,有时你也会需要调试JSP文件,但Eclipse并不支持,尽管在JSP源文件中调试JSP代码是一件非常方便的事. 现在有一种好的解决方法,在你告之应用服务器把你的Eclipse工程作为工作目录后,Lomboz可以让你对在应用服务器上的JSP文件所生成的.java文件进行调试. 注意:Lomboz只支持对能够在Eclipse源代码目录中保存一份servlet源代码(.java)的拷贝的应用服务器上进行JSP的调试. 建立实例 Lomboz在你的工程中为你建

Eclipse远程调试出现“JDWP Transport dt_socket failed to initialize”如何解决

工作中经常需要使用Eclipse远程连接Tomcat,调试Web应用程序. eclipse远程调试Tomcat方法 1.Linux中配置tomcat在catalina.sh中添加如下 CATALINA_OPTS="-Xdebug  -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"(不要换行,要在同一行) 2.Window中修改 catalina,bat文件,添加: Set  "CATALINA_OPT

在Eclipse中调试Maven项目

使用maven的一个方便之处是可以使用Jetty Plugin来运行web项目. 只要maven jetty:run就可以把web项目跑起来了.只是很多时候我们都需要在IDE中进行调试. 那如何在Eclipse中调试使用jetty Plugin的web项目呢? 下面我们就来配置一下. 首先在Run->Externel Tools->Open Externel Tools Dialog.. 打开配置对话框,选中左边的Program节点,右键选择New然后再右边的配置里面输入Name信息, 在Ma

使用Eclipse远程调试Java应用程序

远程调试对应用程序开发十分有用.例如,为不能托管开发平台的低端机器开发程序,或 在专用的机器上(比如服务不能中断的 Web 服务器)调试程序.其他情况包括:运行在内存 小或 CUP 性能低的设备上的 Java 应用程序(比如移动设备),或者开发人员想要将应用程 序和开发环境分开,等等. 先决条件 启动配置类型 启动配置 保存一 组用于启动程序的属性.启动配置类型是一种可以在 Eclipse 平台上启动的独特程序. 如果您还没安装该程序,请下载 Eclipse V3.4(Ganymede).在 G

Eclipse远程调试WebSphere Application Server

我们用 Eclipse 开发 Web 项目时,多会用某个插件(如 MyEclipse) 来对 Tomcat 中的应用进行单步调试.而要调试 WAS 下的应用,MyEclipse 也是可以的,但在 MyEclipse 中启动 WAS 比较慢,且需要在本地安装一个 WAS.再有便捷点的方法是用 WSAD (Websphere Studio Application Developer) 或它的升级版 RAD (Rational Application Developer),它们内置了对 WAS 很好的

编绎OpenJDK

因为对于Java里的vtable,itable,有个地方还没搞明白,不得已去下个OpenJDK来研究下. 本来很不愿意去编绎OpenJDK,因为很有可能做的只是无用功,还有可能要去解决各种找不到链接库的问题. 不过,没想到虽然有些麻烦,但是出人意料的顺利. 环境:ubuntu 13.10,已经安装了oracle jdk7. 首先下载: wget http://download.java.net/openjdk/jdk7u40/promoted/b43/openjdk-7u40-fcs-src-b

我的通过eclipse来调试jsp的过程

js|过程     当你不知道的时候,觉得一切都是正常的.直到有一天得知(但忘了是从哪儿知道的了,或者是谁告诉我的?),eclipse可以调试jsp,那一刻的心情就像久陷囹圄的囚犯获得了自由,于是马不停蹄的上网,从每个网页寻找有用的资料.     简要说一下,我们的开发环境是jsp+servlet+tomcat+oracle,对页面的操作也特别多,所以我们每个人都有两大痛处:javascript和jsp.在js里的调试就是alert,在jsp以及servlet里就靠writelog了.编译不通过

如何使用Eclipse PDT调试PHP程序

本文主要介绍的是如何用eclipse pdt调试PHP 代码. 1. 下载eclipse,从官网上找就可以了,并确认当前系统中有java环境,即jdk和jre. 2. 安装pdt了,采用的是在线安装,更新地址在默认中已经包含了.只是更新起来比较麻烦.(如果直接下载 携带PDT的 Eclipse版本,可省略) 3. 下载调试器,调试器有两种,一种时xdebug,另一种时zenddebug,本文采用 xdebug. 下载下来的应该是源代码包.解压缩,然后cd到目录,然后phpize,有的时候可能没有

Eclipse远程调试Weblogic运行的源代码

web|源代码 看过许多远程调试的例子,大多数都是针对tomcat或者jboss服务器的,很少能搜索到weblogic服务器的远程调试例子和文章,前些天在项目开发的时候尝试了一下,感觉十分得不错,拿出来跟大家分享一下,不过我要多罗嗦几句. 远程调试的好处:我们现在开发的模式大多是本机用eclipse集成source管理环境,集成ant的编译环境,用weblogic插件集成运行环境,基本上一个eclipse又当爹又当妈的,这样的好处就是开发环境配置集中,普通的程序员只要按步骤做就可以了,开发步骤简