调试HotSpot源代码(配视频)
本文将详细介绍在Ubuntu16.04 LTS上对OpenJDK8进行编译,为了方便大家快速搭建起OpenJDK8的调试开发环境,我还录制了对应的视频放到了B站上,大家可以参考。
视频地址:https://space.bilibili.com/27533329
下面我们开始环境的搭建过程。
之前的文章在Ubuntu 16.04上编译OpenJDK8的源代码 已经介绍过在Ubuntu上编译OpenJDK8的源代码,这一篇将介绍在Ubuntu上调试OpenJDK8源代码的2种方式。
1、GDB调试源代码
在Linux上常用GDB调试C/C++源代码。使用GDB运行如上实例生成的Class文件,具体命令如下:
gdb --args ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test
进入GDB后,输入如下命令:
break java.c:JavaMain
continue
第一条命令表示在源文件java.c的JavaMain函数入口处设置断点;第二条命令表示让中断的程序继续运行,直到运行完程序后退出GDB,并在终端打印”Hello World!“信息。
下面介绍一些常用的GDB命令,如下表所示。
命令 |
描述 |
backtrace(bt) |
查看各级函数调用及参数 |
finish |
连续运行到当前函数返回为止,然后停下来等待命令 |
frame(f) n |
从当前栈帧移到到n栈帧 |
info(i) locals |
查看当前栈帧局部变量的值 |
list(l) |
列出源代码,接着上次的位置往下列,每次列10行ll |
list(l) 行号 |
列出从指定行开始的源代码 |
list(l) 函数名 |
列出指定的函数的源代码 |
next(n) |
执行下一行语句 |
print(p) |
打印表达式的值,通过表达式可以修改变量的值或者调用函数 |
quit(q) |
退出gdb调试环境 |
step(s) |
执行下一行语句,如果有函数调用则进入到函数中 |
start |
开始执行程序,停在main函数第一行语句前面等待命令 |
break(b) 行号 |
在指定行设置断点 |
break 函数名 |
在指定函数的开头设置断点 |
break ... if ... |
设置条件断点 |
continue(c) |
从当前位置开始连续运行程序 |
delete breakpoints 断点号 |
删除断点 |
display 变量名 |
跟踪查看指定变量名的变量,每次停下来都显示它的值 |
disable breakpoints 断点号 |
禁用断点 |
enable 断点号 |
启用断点 |
info(i) breakpoints |
查看当前设置了哪些断点 |
run(r) |
从头开始连续运行程序 |
undisplay 跟踪显示号 |
取消跟踪显示 |
watch |
设置观察点 |
info(i) watchpoints |
查看当前设置了哪些观察点 |
x |
从某个位置开始打印存储单元的内容,全部当成字节来看, 而不区分哪个字节属于哪个变量 |
2、在Eclipse中调试源代码
1.下载安装Eclipse并安装C/C++插件
在 https://www.eclipse.org/downloads 网站上下载支持Ubuntu 64位版本操作系统的Eclipse,笔者下载的压缩包名称为eclipse-java-neon-3-linux-gtk-x86_64.tar.gz,通过如下命令解压后得到eclipse目录。命令如下:
tar -zxvf eclipse-java-neon-3-linux-gtk-x86_64.tar.gz
在运行Eclispe之前还需要配置环境变量,如下:
export JAVA_HOME=/home/mazhi/workspace/jdk1.7.0_72
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib在
切换到eclipse目录后,运行如下命令启动Eclipse。命令如下:
./eclipse &
启动Eclipse后,单击help菜单项,选择Eclipse Marketplace选项后,弹出Eclipse Marketplace对话框,搜索"c++"找到Eclipse C++ IDE..安装。安装完成后就可以创建及导入C/C++项目到Eclipse中了。
或者下载专门开发C/C++的Eclipse集成环境,例如笔者下载的压缩包名称为eclipse-cpp-helios-SR1-linux-gtk-x86_64.tar.gz,解压后以类似的方式启动。不过在启动Eclipse之前,需要指定JDK路径,编译安装目录下的eclipse.ini文件,如下:
openFile
-vm
/home/mazhi/workspace/jdk1.7.0_72/bin
-vmargs
-Dosgi.requiredJavaVersion=1.5
-XX:MaxPermSize=256m
-Xms40m
-Xmx384m
在openFile和-vmargs之间配置-vm和/home/mazhi/workspace/jdk1.7.0_72/bin即可。不过通过eclipse-java-neon-3-linux-gtk-x86_64.tar.gz压缩包安装的Eclispe需要jdk1.8版本,只需要换个1.8的版本即可。
2.导入HotSpot源代码
单击help菜单项,选择new->Other...后,在弹出的New对话框中选择Makefile Project with Existing Code,然后单击“Next”,添写相关的信息,如下图所示。
设置完成后单击“Finish”即可。
3.配置及调试源代码
在HotSpot项目上右击,选择Debug As -> Debug Configurations...,在弹出的Debug Configurations对话框中,选择C/C++ Application后,右击,在弹出的菜单中选择New Configuration后,在右侧的Main选项卡中配置相关的信息,如下图所示。
切换到Arguments选项卡, 在Program arguments文本框中输入虚拟机运行时的参数,这里运行之前的实例,具体参数如下:
com.test/Test
切换到Environment选项卡, 添加变量:
JAVA_HOME=/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/
CLASSPATH=.:/home/mazhi/workspace/project/bin
CLASSPATH指定Test.class文件所在的目录。设置完相关信息后,单击Apply进行保存。
3、在Visual Studio Code中调试源代码
在https://code.visualstudio.com官网上下载Visual Studio Code,笔者下载的是"code_1.51.0-1604600753_amd64.deb"版本。安装完成后通过单击File -> OpenFolder选项,选中hotspot文件夹,点击左侧导航栏中的Run(Ctrl+Shift+D)图标切换到对应选项栏,单击add configuration选项后选中c/c++: (gdb) 启动,修改lauch.json文件,所有的配置都通过这个文件完成,笔者的配置文件详细内容如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "HotSpot Linux Debug",
"type": "cppdbg",
"request": "launch",
"program": "/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java",
"args": ["com.test/Test"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{"name":"JAVA_HOME","value":"/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk"},
{"name":"CLASSPATH","value":".:/home/mazhi/workspace/projectjava/projectjava01/bin"}
],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
主要关注"configurations"中的"program"、"args"、"environment"配置项,这几个其实在Eclipse中都指定过,"program"就是指定C/C++应用程序的位置,而"environment"就是配置的环境变量,"args”是为虚拟机运行配置参数。
可以在hotspot/src/share/vm/prims/jni.cpp文件下的JNI_CreateJavaVM()函数上打个断点,然后在run(Ctrl+Shift+D)选项栏中选中"HotSpot Linux Debug"进行调试即可。
推荐文章:
1、在Ubuntu 16.04上编译OpenJDK8的源代码(配视频)
搭建过程中如果有问题可直接评论留言或加作者微信mazhimazh。
作者持续维护的个人博客 classloading.com。
关注公众号,有HotSpot源码剖析系列文章!
调试HotSpot源代码(配视频)的更多相关文章
- 调试HotSpot源代码
之前的文章在Ubuntu 16.04上编译OpenJDK8的源代码 已经介绍过在Ubuntu上编译OpenJDK8的源代码,这一篇将介绍在Ubuntu上调试OpenJDK8源代码的2种方式. 1.GD ...
- HotSpot的启动过程(配视频进行源码分析)
本文将详细介绍HotSpot的启动过程,启动过程涉及到的逻辑比较复杂,细节也比较多,为了让大家更快的了解这部分知识,我录制了对应的视频放到了B站上,大家可以参考. 第4节-HotSpot的启动过程 下 ...
- 在ASP.NET 5项目中使用和调试外部源代码包
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:由于在ASP.NET 5中,项目依赖都是通过"包"来引用,所以使用 ...
- 调试 ms 源代码
如果需要调试 WPF 源代码或框架源代码,那么需要使用 DotPeek. 首先需要下载 dotPeek ,可以到官网下载 dotPeek: Free .NET Decompiler & Ass ...
- 调试Java源代码时变量的值无法追踪怎么办?
问题:调试Java源代码时,只能看到源代码,却无法查看源代码中的变量的即时值 原因:jre为了节省空间,在打包时去掉了class文件中的调试信息. 思路:使用jdk里的src.zip源码重新编译生成完 ...
- C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案
C#调试含有源代码的动态链接库遇见there is no source code available for the current location提示时的解决方案: 1.首先试最常规的方法:Cle ...
- 编绎调试HotSpot JVM及在Eclipse里调试HotSpot一些步骤
编绎整个OpenJDK要很久,而且有很多东西是不需要的.研究HotSpot的话,其实只要下HotSpot部分的代码就可以了. 下面简单记录下编绎调试HotSpot一些步骤. 一.编绎 进入hotsop ...
- 调试 Hadoop 源代码
环境是 64bit Ubuntu 14.04 系统, jdk 1.7 以及 Eclipse Mars (4.5) 这里介绍两种调试 Hadoop 源代码的方法: 利用 Eclipse 远程调试工具和打 ...
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
常量,字段,构造方法 常量 1.什么是常量 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...
随机推荐
- 多测师讲解selenium _滚动条定位_高级讲师肖sir
from selenium import webdriverfrom time import sleepdrvier=webdriver.Chrome()drvier.get('http://www. ...
- C#数据结构-链栈
上一篇我们通过数组结构实现了栈结构(准确的说是栈的顺序存储结构),现在我们通过链(单链)存储栈,也就是链栈. 通常对于正向单链表来说,是从头节点开始,在链的尾部附加节点,前一个节点的指针指向附加节点: ...
- java中文件是否为空
在File类中并没有提供判断文件是否为空的方法,但可以借助length()方法的返回值进行判断.如果文件不存在或文件为空时,length()方法返回0. File file = new File(&q ...
- PS文字
点文本 直接单击鼠标可输点文字 输完后在离文字较远的地方出现白色箭头单击可结束输入,也可选择其他图层结束输入 再次修改文字可双击文字缩览图 出现黑色小箭头可以在输入到的情况下拖动文字,文字工具下按Ct ...
- go读取excel表格数据
go读取excel表格数据 使用工具 github.com/Luxurioust/excelize 百度到的都是使用这个 实际上已经改名了 github.com/360EntSecGroup-Skyl ...
- 【Azure 环境】连接到微软云Azure中国区 By VS 2019, VS Code, Powershell
问题情形 最近,在使用最新的VS Code插件连接到中国区的Azure时候,出现了依旧是global版的登录连接.这个问题是当前Azure Account插件最新版的问题,可以使用V0.8.11版本登 ...
- C++ std::thread 多线程中的异常处理
环境: VS2019 包含头文件: #include <iostream>#include<thread>#include<exception> 线程函数采用try ...
- c#封装ActiveX接口实践分析
ActiveX接口 是一个开放的集成平台,为开发人员.用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内容的方法. 使用 ActiveX, 可轻松方 ...
- 基于Spring读写分离
为什么是基于Spring的呢,因为实现方案基于Spring的事务以及AbstractRoutingDataSource(spring中的一个基础类,可以在其中放多个数据源,然后根据一些规则来确定当前需 ...
- Redis集群环境搭建实践
0 Redis集群简介 Redis集群(Redis Cluster)是Redis提供的分布式数据库方案,通过分片(sharding)来进行数据共享,并提供复制和故障转移功能.相比于主从复制.哨兵模式, ...