JNI在printf()上得到EXCEPTION_ACCESS_VIOLATION

JNI, getting EXCEPTION_ACCESS_VIOLATION on printf()

本文关键字:EXCEPTION ACCESS VIOLATION printf JNI      更新时间:2023-10-16

我有用于测试的JNI代码(c++):

JNIEXPORT void JNICALL Java_zontwelg_Natives_kekTest__ (JNIEnv *env, jclass) {
    printf("Kek test!n");
}

当我在应用程序中调用这个时:

public static native void kekTest();

Java get crash with message

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000000006d12, pid=16652, tid=5520
#
# JRE version: Java(TM) SE Runtime Environment (7.0_79-b15) (build 1.7.0_79-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.79-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  0x0000000000006d12
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:workmc_clientnbprojectZontWelg Minecrafths_err_pid16652.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

完整的崩溃日志可以在这里找到:http://pastebin.com/5UhV7NUm

怎么了?使用jdk1.7.0_79从NetBeans 8.0.2运行应用程序。


更新:

c++

JNIEXPORT void JNICALL Java_zontwelg_Natives_kekTest__ (JNIEnv *env, jclass) {
    std::cout << "kek testn" << endl;
}

输出错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff6cadf2869, pid=11168, tid=8776
#
# JRE version: Java(TM) SE Runtime Environment (8.0_60-b27) (build 1.8.0_60-b27)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [zmcload_64.exe+0x2869]  std::operator<<<std::char_traits<char> >+0x49
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:workmc_clientnbprojectZontWelg Minecrafths_err_pid11168.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

完全登录pastebin。错误指的是zmcload_64.exe+0x2869,这里是反汇编代码:

000000014000282F: 48 89 5C 24 50     mov         qword ptr [rsp+50h],rbx
0000000140002834: 48 89 6C 24 58     mov         qword ptr [rsp+58h],rbp
0000000140002839: 48 89 74 24 60     mov         qword ptr [rsp+60h],rsi
000000014000283E: 48 89 7C 24 68     mov         qword ptr [rsp+68h],rdi
0000000140002843: 4C 8B F2           mov         r14,rdx
0000000140002846: 48 8B F9           mov         rdi,rcx
0000000140002849: 33 ED              xor         ebp,ebp
000000014000284B: 40 38 2A           cmp         byte ptr [rdx],bpl
000000014000284E: 75 04              jne         0000000140002854
0000000140002850: 33 F6              xor         esi,esi
0000000140002852: EB 15              jmp         0000000140002869
0000000140002854: 48 83 CE FF        or          rsi,0FFFFFFFFFFFFFFFFh
0000000140002858: 0F 1F 84 00 00 00  nop         dword ptr [rax+rax]
                  00 00
0000000140002860: 48 FF C6           inc         rsi
0000000140002863: 40 38 2C 32        cmp         byte ptr [rdx+rsi],bpl
0000000140002867: 75 F7              jne         0000000140002860
0000000140002869: 48 8B 01           mov         rax,qword ptr [rcx]
000000014000286C: 48 63 48 04        movsxd      rcx,dword ptr [rax+4]
0000000140002870: 48 8B 5C 39 28     mov         rbx,qword ptr [rcx+rdi+28h]
0000000140002875: 48 85 DB           test        rbx,rbx
0000000140002878: 7E 0A              jle         0000000140002884
000000014000287A: 48 3B DE           cmp         rbx,rsi
000000014000287D: 7E 05              jle         0000000140002884
000000014000287F: 48 2B DE           sub         rbx,rsi
0000000140002882: EB 02              jmp         0000000140002886
0000000140002884: 33 DB              xor         ebx,ebx
0000000140002886: 48 89 7C 24 28     mov         qword ptr [rsp+28h],rdi
000000014000288B: 48 8B 4C 39 48     mov         rcx,qword ptr [rcx+rdi+48h]
0000000140002890: 48 85 C9           test        rcx,rcx
0000000140002893: 74 07              je          000000014000289C
0000000140002895: 48 8B 01           mov         rax,qword ptr [rcx]
0000000140002898: FF 50 08           call        qword ptr [rax+8]
000000014000289B: 90                 nop

好了,我明白了。

我试图从可执行文件调用本机函数。作为DLL重新编译项目解决了此错误。似乎是标准输出尝试写入文本到本地exe文件,而不是jvm(或类似的东西)。

您可能忘记在从Java代码调用本机方法之前调用System.loadLibrary

在使用本机方法之前,必须首先在内存中加载实现该方法的动态库。在windows中,它将是通过编译调用printf的C/c++代码生成的。dll。