来自 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 符号
linux 上的 JNI_CreateJavaVM 会破坏堆栈?
Mac OS、JDK1.7(和 1.8)不包含 JNI_CreateJavaVM 符号