我在Window 64bit上运行的Java(Eclipse RCP)应用程序出现问题(如果应用程序使用32位JVM运行,则不会出现此问题)
如果应用程序在调试器中运行,也不会出现此问题。
在应用程序中,调试输出是使用System.err.print(...)进行的。如果应用程序不在调试器控制下运行,则UI线程只是随机冻结。
我使用GDB附加了进程,并看到该进程在ZwWriteFile的调用中挂起。
(gdb) where
#0 0x000000007745bdba in ntdll!ZwWriteFile () from /cygdrive/c/windows/SYSTEM32/ntdll.dll
#1 0x000007fefd3a1b3b in WriteFile () from /cygdrive/c/windows/system32/KERNELBASE.dll
#2 0x0000000077311f66 in WriteFile () from /cygdrive/c/windows/system32/kernel32.dll
#3 0x000000006651cb65 in java!handleRead () from /cygdrive/d/Programme/Razorcat/Shared/1.3/JRE_1.8/bin/java.dll
#4 0x000000006651c31e in java!JNI_OnLoad () from /cygdrive/d/Programme/Razorcat/Shared/1.3/JRE_1.8/bin/java.dll
#5 0x0000000066512dc9 in java!Java_java_io_FileOutputStream_writeBytes () from /cygdrive/d/Programme/Razorcat/Shared/1.3/JRE_1.8/bin/java.dll
(gdb) disass
Dump of assembler code for function ntdll!ZwWriteFile:
0x000000007745bdb0 <+0>: mov %rcx,%r10
0x000000007745bdb3 <+3>: mov $0x5,%eax
0x000000007745bdb8 <+8>: syscall
=> 0x000000007745bdba <+10>: retq
0x000000007745bdbb <+11>: nopl 0x0(%rax,%rax,1)
有没有人遇到这样的问题?有没有办法(内核调试器?)更密切地研究这个问题。
下面是调用WriteFile Windows API函数的函数(io_util_md.c)。可能是Windows在伪句柄处有重叠IO的问题。 (我猜这个过程在没有在调试器中运行时没有标准句柄)
static jint writeInternal(FD fd, const void *buf, jint len, jboolean append)
{
BOOL result = 0;
DWORD written = 0;
HANDLE h = (HANDLE)fd;
if (h != INVALID_HANDLE_VALUE) {
OVERLAPPED ov;
LPOVERLAPPED lpOv;
if (append == JNI_TRUE) {
ov.offset = (DWORD)0xFFFFFFFF;
ov.OffsetHigh = (DWORD)0xFFFFFFFF;
ov.hEvent = NULL;
lpOv = &ov;
} else {
lpOv = NULL;
}
result = WriteFile(h, /* File handle to write */
buf, /* pointers to the buffers */
len, /* number of bytes to write */
&written, /* receives number of bytes written */
lpOv); /* overlapped struct */
}
if ((h == INVALID_HANDLE_VALUE) ||| (result == 0)) {
return -1;
}
return (jint)written;
}