JVM-在Visual Studio Code中调试OpenJDK8
写在前面
上次在MacOS
系统下编译并调试OpenJDK12
后,觉得现在在日常开发中都使用的JDK8
,所以就还是想主要学习OpenJDK8
的源码,然后就又萌发了调试OpenJDK8
源码的方式。
根据之前编译调试OpenJDk12
的文章(点击查看),首先想到的也是使用CLion
来调试,但是,很遗憾,OpenJDK8
不支持compilation database
,所以只有换一种方法。
查询资料的过程中,发现R大
在知乎说,他一般采用VIM
的方式进行开发,所以我也开始找相关资料,配置各种插件,最后,放弃了。因为VIM
确实学习成本过高,可能等把VIM
整明白了,就已经没有学JVM
的欲望了。
后来,又瞄上了Visual Studio Code
,因为之前也用它写Python
,也知道它可以比较方便的安装各种插件来支持不同语言的开发工作,而且目前也有很多工程师用它写C/C++
代码,所以最后,通过一系列探索,终于在Visual Studio Code
,配置好了调试OpenJDK8
的环境。
关于编译OpenJDK8
在MacOS
编译OpenJDK8
的文章,网上很多,多查几篇文章,基本都可以搞定,所以本文重点在怎么在Visual Studio Code
调试,而不是编译。
可以通过以下关键字Google
一下:MacOS Cataline OpenJDK8
,顺便也推荐一下,当时我所参考的博客:
一定要在编译成功后,在操作后续步骤哦,否则就是在浪费时间~
插件安装
在Visual Studio Code
安装两个插件就可以,具体如下:
C/C++
:为Visual Studio Code
添加C/C++
支持;CodeLLDB
:调试工具,因为在实际调试的时候,只使用C/C++
提供的Debug
功能,在调试过程中,会卡住,程序不继续执行,具体原因不知道为什么,所以我使用这个插件进行调试。
配置
c_cpp_properties.json
Command
+ Shift
+ P
,选择C/C++: Edit Configurations (JSON)
,会自动创建c_cpp_properties.json
文件,我的配置文件如下:
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"defines": [],
"macFrameworkPath": [
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "gnu++14",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
settings.json
这个文件,我的配置是主要将源码报红的部分给隐藏,代码检查的报错并不影响源码的编译与调试,我对这些代码检查的理解是,目前新版本的C/C++
可能不支持某些语法或者某些语法已经过时,还有可能是Java
虚拟机是跨平台的,所以我觉得它所引用的一些类库什么的可能是别的系统才有的。当然,这只是我的猜测,我的目的是调试OpenJDK8
的代码,而不是去找这些问题,所以我直接关闭了代码检查时的错误提示。
具体路径:Preferences
->Settings
下,按照下图进行设置:
设置完毕后,应该就可以在项目根目录下,.vscode
目录下看到settings.json
文件,我的settings.json
文件如下:
{
"git.ignoreLimitWarning": true,
"files.associations": {
"random": "cpp",
"*.tcc": "cpp"
},
"C_Cpp.errorSquiggles": "Disabled",
}
tasks.json
tasks.json
文件,可以配置一些编译的相关任务,可以通过Command
+ Shift
+ B
生成该文件。
我在这边配置了make
、clean
相关的任务。
下面是我的tasks.json
文件,字段配置可参考官方的文档,解释很详细,就不在这里赘述:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "openjdk8 slowdebug build",
"type": "shell",
"command": "make",
"args": [
"CONF=openjdk8-server-64-slowdebug-vscode",
"COMPILER_WARNINGS_FATAL=false"
],
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
}
}, {
"label": "openjdk8 slowdebug clean",
"type": "shell",
"command": "make",
"args": [
"CONF=openjdk8-server-64-slowdebug-vscode",
"clean"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
配置完成后,可以通过Command
+ Shift
+ B
快捷键执行配置的任务。
launch.json
在源码根目录.vscode
目录下的launch.json
文件,用来配置执行参数,比如你想执行java -version
或者使用java
来运行一个java
的class
文件,都需要通过该文件来配置。
下面是我的相关配置:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "java -version[CodeLLDB]",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/build/openjdk8-server-64-fastdebug-vscode/jdk/bin/java",
"args": [
"-version"
],
"cwd": "${workspaceFolder}",
"preRunCommands": [
"breakpoint set --file ${workspaceFolder}/jdk/src/share/bin/main.c --line 125 -C 'pro hand -p true -s false SIGSEGV SIGBUS' --auto-continue true"
],
"preLaunchTask": "openjdk8 slowdebug build"
}, {
"name": "HeapOOM",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/build/openjdk8-server-64-fastdebug-vscode/jdk/bin/java",
"args": [
"-XX:+UseG1GC",
"-Xms20m",
"-Xmx20m",
"-classpath",
"/Users/howieli/Work/JDK/java-source",
"HeapOOM"
],
"cwd": "${workspaceFolder}",
"stopOnEntry": false,
"preRunCommands": [
"breakpoint set --file ${workspaceFolder}/jdk/src/share/bin/main.c --line 125 -C 'pro hand -p true -s false SIGSEGV SIGBUS' --auto-continue true"
],
"preLaunchTask": "openjdk8 slowdebug build"
}
]
}
配置中,我觉得大部分都是很清晰的,对具体参数不了解的同学,可以自行使用搜索引擎,这里我主要说下四个参数:
type
:这里使用lldb
,而不是cppdbg
,cppdbg
类型,是使用的官方插件中的Debug
工具,而lldb
是使用前面安装的CodeLLDB
插件提供的Debug
工具;args
:配置参数,这个参数看起来没什么好说的,但却容易踩坑,所以着重提醒一下,这里的参数一定要一个一个的配置,之前我配置成下面这样,看上去没问题,但却怎么都无法正常执行;[ "-XX:+UseG1GC -Xms20m -Xmx20m", "-classpath /Users/howieli/Work/JDK/java-source", "HeapOOM" ]
preRunCommands
:这里是为了调试启动时自动忽略SIGSEGV
、SIGBUS
的错误提示,否则无法顺利调试,具体原因可以查看JVM-在MacOS系统上使用CLion编译并调试OpenJDK12;preLaunchTask
:运行前执行一个任务,这里所配置的值要和tasks.json
中某个任务的label
对应。这里配置的是在运行该程序前,首先执行make
,也就是编译JDK
的命令,再开始运行。
调试
我在这边选择运行一个Java
的小程序(HeapOOM
),简单的打个端点:
点击启动按钮,就可以开始调试啦。
写在最后
以上就是我折腾的一些经验,可能不是最完美的,但基本满足了我的目标,如果有错误,麻烦提出,共同进步,如果有更好的调试经验,也欢迎大佬一起交流,谢谢。
参考资料
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!