应用程序在调用ZwWriteFile

时间:2018-03-19 12:55:23

标签: java windows kernel eclipse-rcp overlapped-io

我在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;
}

0 个答案:

没有答案