来自 JNI_CreateJavaVM (jvm.dll) 的异常 0xC0000005

Posted

技术标签:

【中文标题】来自 JNI_CreateJavaVM (jvm.dll) 的异常 0xC0000005【英文标题】:Exception 0xC0000005 from JNI_CreateJavaVM (jvm.dll) 【发布时间】:2016-03-27 17:14:12 【问题描述】:

我正在使用以下 C++ 代码初始化 Java VM。 JNI_CreateJavaVM 抛出 0xC0000005 异常,但如果我忽略它,它仍然会成功。

“Jni.exe”(Win32):已加载“C:\Tools\Java\Jdk8.77x86\jre\bin\zip.dll”。无法找到或打开 PDB 文件。

在 Jni.exe 中的 0x02900282 处引发异常:0xC0000005:访问冲突读取位置 0x00000000。

“Jni.exe”(Win32):已加载“C:\Windows\SysWOW64\shell32.dll”。无法找到或打开 PDB 文件。

我是忘记设置或做某事还是这是“正常”行为?

#include <array>
#include "jni.h"

int main( int argc, char const* args[])

    JavaVM* jvm;
    JNIEnv* env;
    
    std::array<JavaVMOption,1> options;
    options[0].optionString = "-Djava.class.path=C:/Users/Thomas/Documents/Visual Studio 2015/Projects/Jni/x64/Debug";
    options[0].extraInfo = nullptr;

    JavaVMInitArgs vm_args;
    vm_args.version = JNI_VERSION_1_8;
    vm_args.options = options.data();
    vm_args.nOptions = options.size();
    vm_args.ignoreUnrecognized = false;

    auto rc = JNI_CreateJavaVM( &jvm, reinterpret_cast<void**>(&env), &vm_args );
    if( rc == JNI_OK )
    
        jvm->DestroyJavaVM();        
    

Release 和 Debug 以及 x86 和 x64 构建都会发生这种情况。

【问题讨论】:

如果你独立运行程序,而不是在 MSVC 中运行,是否会发生异常? @apangin 异常在 jvm.dll 内部处理。程序不会崩溃。它工作正常。如果没有 MSVC,我将如何检测异常?如果我在 Win32 异常下禁用 C00000005,则消息只会显示在输出控制台中并且没有中断 【参考方案1】:

JVM 主动使用操作系统信号(或 Windows 术语中的例外)用于其自身目的:

用于隐式空指针检查和堆栈溢出检查; 用于安全点轮询; 用于远程内存屏障; 等

SEGV(或异常 0xC0000005)也会在 JVM 启动时有意生成,以验证某些 CPU/OS 功能。一些操作系统或虚拟机管理程序有一个错误,即 AVX 寄存器在信号处理后没有恢复。因此,JVM 需要检查(the source) 是否是这种情况。所以它会通过写入零地址产生一个异常,然后处理它。

这就是您的情况。是的,这很正常。

【讨论】:

那么我怎样才能让 Visual Studio 调试器跳过这个? 不幸的是,我不知道这个答案的 Visual Studio 版本,但是这个答案***.com/a/23363628/159658 有一个适用于 GDB 的策略(程序在段错误时中断,向 GDB 发送“信号 0”命令,然后继续执行),以防它帮助目前正在进入这个兔子洞的其他人。【参考方案2】:

这很正常,就像@apangin 说的那样。如果您想在 VisualStudio (2017) 中关闭所有 0xC0000005 异常,您可以这样做:

    异常设置 - Ctrl+Alt+E 从 Win32 异常下的“0xc0000005 访问冲突”中删除勾选

【讨论】:

以上是关于来自 JNI_CreateJavaVM (jvm.dll) 的异常 0xC0000005的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse:JVM 共享库不包含 JNI_CreateJavaVM 符号

JNI_CreateJavaVM 上的段错误

linux 上的 JNI_CreateJavaVM 会破坏堆栈?

Mac OS、JDK1.7(和 1.8)不包含 JNI_CreateJavaVM 符号

架构 x86_64 的未定义符号:JNI_CreateJavaVM OS-X Xcode

对 `JNI_CreateJavaVM' linux 的未定义引用