JNI 在 windows 7 中使 java 崩溃
JNI is crashing the java in windows 7
我正在将代码从 linux 移植到 windows,因为 Java 中不支持 Linux 共享内存段。因此,我们使用 Java 本机接口 (JNI) 访问共享 memory.It 在 linux 平台上工作正常。
shmget 代码:
JNIEXPORT jint JNICALL Java_emulatorinterface_communication_shm_SharedMem_shmget
(JNIEnv * env, jobject jobj, jint COUNT,jint MaxNumJavaThreads,jint EmuThreadsPerJavaThread,
jlong coremap, jint pid) {
uint64_t mask = coremap;
int size;//=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;
char str[50];
int ptr;
#ifdef _WIN32
HANDLE hMapFile;
#endif
printf("hello");
size=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;
/*if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
perror("sched_setaffinity");
}*/
//set the global variables
gCOUNT = COUNT;
gMaxNumJavaThreads = MaxNumJavaThreads;
gEmuThreadsPerJavaThread = EmuThreadsPerJavaThread;
//size1 is the number of packets needed in the segment.
#ifdef _WIN32
_itoa(pid,str,10);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,32, str);
if (hMapFile == NULL)
{
exit(1);
}
CloseHandle(hMapFile);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,size, str);
if (hMapFile == NULL)
{
printf("Unable to create a shared mem file.");
exit(1);
}
if (hMapFile < 0)
{
return (-1);
}
/*
if((hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,size, str))<0)
{
printf("error window %d\n",size);
return (-1);
}
*/
ptr=*((int*)(hMapFile));
return ptr; ///////////////error in return type
#else
如果我尝试在 JNI 中使用任何其他函数,我的 java 会崩溃。
错误
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007feedf911be, pid=4696, tid=4216
#
# JRE version: Java(TM) SE Runtime Environment (8.0_77-b03) (build 1.8.0_77-b03)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.77-b03 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [JNIShm.dll+0x11be]
#
# 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:
# D:\workspace\tejasMinor\hs_err_pid4696.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.
#
谁能指出问题出在哪里?
您不能将 HANDLE
取消引用到文件映射对象。只需让你函数 return 句柄,如:
return (int)hMapFile;
在 64 位 Windows 上(使用 64 位 JRE/JNI),HANDLE
类型是 64 位宽,但只有较低的 32 位是有效的,所以没关系。
旁注:
- 不要使用
hMapFile < 0
。如果 API 失败,则 return 值为 NULL
.
- 您确定要先尝试使用 32 字节的文件,然后关闭它吗?为什么?
- 您可能需要调用
GetLastError
并针对 ERROR_ALREADY_EXISTS
测试结果(如果您希望能够检测到该条件)
我正在将代码从 linux 移植到 windows,因为 Java 中不支持 Linux 共享内存段。因此,我们使用 Java 本机接口 (JNI) 访问共享 memory.It 在 linux 平台上工作正常。
shmget 代码:
JNIEXPORT jint JNICALL Java_emulatorinterface_communication_shm_SharedMem_shmget
(JNIEnv * env, jobject jobj, jint COUNT,jint MaxNumJavaThreads,jint EmuThreadsPerJavaThread,
jlong coremap, jint pid) {
uint64_t mask = coremap;
int size;//=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;
char str[50];
int ptr;
#ifdef _WIN32
HANDLE hMapFile;
#endif
printf("hello");
size=sizeof(packet)*(COUNT+5)*MaxNumJavaThreads*EmuThreadsPerJavaThread;
/*if (sched_setaffinity(0, sizeof(mask), (cpu_set_t *)&mask) <0) {
perror("sched_setaffinity");
}*/
//set the global variables
gCOUNT = COUNT;
gMaxNumJavaThreads = MaxNumJavaThreads;
gEmuThreadsPerJavaThread = EmuThreadsPerJavaThread;
//size1 is the number of packets needed in the segment.
#ifdef _WIN32
_itoa(pid,str,10);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,32, str);
if (hMapFile == NULL)
{
exit(1);
}
CloseHandle(hMapFile);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,size, str);
if (hMapFile == NULL)
{
printf("Unable to create a shared mem file.");
exit(1);
}
if (hMapFile < 0)
{
return (-1);
}
/*
if((hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL, PAGE_READWRITE,
0,size, str))<0)
{
printf("error window %d\n",size);
return (-1);
}
*/
ptr=*((int*)(hMapFile));
return ptr; ///////////////error in return type
#else
如果我尝试在 JNI 中使用任何其他函数,我的 java 会崩溃。
错误
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000007feedf911be, pid=4696, tid=4216
#
# JRE version: Java(TM) SE Runtime Environment (8.0_77-b03) (build 1.8.0_77-b03)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.77-b03 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [JNIShm.dll+0x11be]
#
# 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:
# D:\workspace\tejasMinor\hs_err_pid4696.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.
#
谁能指出问题出在哪里?
您不能将 HANDLE
取消引用到文件映射对象。只需让你函数 return 句柄,如:
return (int)hMapFile;
在 64 位 Windows 上(使用 64 位 JRE/JNI),HANDLE
类型是 64 位宽,但只有较低的 32 位是有效的,所以没关系。
旁注:
- 不要使用
hMapFile < 0
。如果 API 失败,则 return 值为NULL
. - 您确定要先尝试使用 32 字节的文件,然后关闭它吗?为什么?
- 您可能需要调用
GetLastError
并针对ERROR_ALREADY_EXISTS
测试结果(如果您希望能够检测到该条件)