碰到调试JNI_CreateJavaVM时SIGSEGV fault错误的解决方案

本文介绍在JNI_CreateJavaVM中遇到SIGSEGV错误的解决方案。通过在openjdk根目录下创建.gdbinit文件并配置GDB,使调试器在程序信号处理器前捕获信号,避免调试中断。

调试时出现 Signal received: SIGSEGV (Segmentation fault) 比较烦。在 jni.cpp 的 JNI_CreateJavaVM 设置断点调试。不同 jdk 版本路径不同。(编译调试 openjdk 的惨痛经历 - 简书)

这是因为:

测试本来就是要触发SIGSEGV的。而GDB在调试的时候会在程序注册的signal handler之前先获取到signal,要continue才会跑到应用注册的signal handler去。

解决方法

在openjdk的根目录上创建一个.gdbinit,这个文件的作用是为gdb在运行前提供配置信息

在Netbeans里面设置,右键项目->属性->调试,在“Gdb初始化文件”里面设置刚创建的文件

handle SIGSEGV pass noprint nostop
handle SIGUSR1 pass noprint nostop
handle SIGUSR2 pass noprint nostop
set logging on
set breakpoint pending on
set print pretty on

为了方便其他国家的程序员,我翻译英文如下:

It is annoying to encounter "Signal received: SIGSEGV (Segmentation fault)" when you make a breakpoint at JNI_CreateJavaVM in jni.cpp.

Reason:

Because the purpose of debuging is to trigger SIGSEGV, and gbd must catch the signal before the program registers signal handler.

Solution:

Create a .gdbinit in the root of openjdk, this is for providing configuring infomation for gdb running.

In Netbeans, right click the project that you made, select "properties", select "debug", fill in the .gdbinit file path and the name in the "Gdb initial file"

handle SIGSEGV pass noprint nostop
handle SIGUSR1 pass noprint nostop
handle SIGUSR2 pass noprint nostop
set logging on
set print pretty on
### JNI_CreateJavaVM 的用法与配置 #### 背景说明 `JNI_CreateJavaVM` 是 Java Native Interface (JNI) 提供的一个函数,用于初始化一个新的 Java 虚拟机实例。该函数通常由 C/C++ 应用来调用,以便嵌入式运行 Java 程序。 在 Windows 平台上使用 Visual Studio 2022 配置 `JNI_CreateJavaVM` 函数,需要注意以下几个方面: --- #### 1. JDK 安装与环境变量设置 为了成功调用 `JNI_CreateJavaVM`,需要确保已安装合适的 JDK 版本,并将其路径正确配置到系统的环境变量中。具体来说: - 将 `%JAVA_HOME%\bin` 和 `%JAVA_HOME%\lib` 添加到系统 PATH 变量中。 - 确认 `libjvm.dll` 文件存在于 `%JAVA_HOME%\bin\server` 或其他子目录下[^1]。 如果缺少上述 DLL 文件,则会引发错误提示:“未定义的引用‘JNI_CreateJavaVM’”。 --- #### 2. 配置项目属性 在 Visual Studio 2022 中开发支持 JNI 的应用程序,需完成以下步骤来链接必要的库文件和头文件: - **包含路径**: 在项目的“属性 -> C/C++ -> 常规 -> 附加包含目录”中添加 JDK 的 include 目录及其平台特定子目录。例如: ``` %JAVA_HOME%\include %JAVA_HOME%\include\win32 ``` - **库依赖项**: 在“属性 -> 链接器 -> 输入 -> 附加依赖项”中指定所需的动态链接库名称(无需扩展名)。对于 Windows,默认情况下不需要显式链接静态库,因为 `libjvm.dll` 已经包含了所需的功能实现[^3]。 --- #### 3. 初始化 Java VM 示例代码 以下是通过 `JNI_CreateJavaVM` 创建并启动 Java 虚拟机的一段典型代码示例: ```cpp #include <jni.h> #include <iostream> int main() { JNIEnv* env; JavaVM* jvm; JavaVMInitArgs vm_args; // 设置 JVM 参数 memset(&vm_args, 0, sizeof(vm_args)); vm_args.version = JNI_VERSION_1_8; // 使用 JDK 8 标准版本 vm_args.nOptions = 0; vm_args.ignoreUnrecognized = false; jint res = JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &vm_args); if (res != JNI_OK || !env) { // 如果失败则退出程序 std::cerr << "Failed to create JVM." << std::endl; return -1; } // 执行一些操作... std::cout << "JVM created successfully!" << std::endl; // 关闭虚拟机 jvm->DestroyJavaVM(); return 0; } ``` 此代码片段展示了如何利用 `JNI_CreateJavaVM` 来创建一个简单的 Java 虚拟机实例。 --- #### 4. 解决常见问题 当遇到类似于“The JVM shared library ‘…’ does not contain the JNI_CreateJavaVM symbol”的错误消息,可以尝试以下方法排查问题: - 检查所使用的 JDK 是否兼容当前操作系统架构(如 x64 vs x86)。 - 确保加载的是正确的共享库文件 (`libjvm.so` 对于 Linux/MacOS;`libjvm.dll` 对于 Windows)[^2]。 - 更新至最新版 JDK,某些旧版本可能不完全支持最新的 API 接口标准。 --- ####
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值