Details
-
Bug
-
Resolution: Fixed
-
P4
-
7, 8
-
b26
-
windows
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8056798 | emb-9 | Unassigned | P4 | Resolved | Fixed | b26 |
Description
We have seen crashes and unexpected exceptions due to a bug in Java_sun_nio_ch_FileDispatcherImpl_lock0 under windows when running the jck test
"api/java_nio/channels/AsynchronousFileChannel/AsynchronousFileChannel.html#tryLock".
The exception text states "Overlapped I/O operation is in progress" which is the error returned by the windows API function "LockFileEx".
The C code contains the following. Note that LockFileEx works asynchronously in this test.
OVERLAPPED o;
...
result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
...
no check for o afterwards!
With this current coding, Java_sun_nio_ch_FileDispatcherImpl_lock0 may return even though I/O is still pending. The asynchronous LockFileEx then modifies the OVERLAPPED o on stack which is no longer valid because the stack frame has gone.
According to Microsoft, this is not allowed:
-Do not deallocate or modify the OVERLAPPED structure or the data buffer until all asynchronous I/O operations to the file object have been completed.
-If you declare your pointer to the OVERLAPPED structure as a local variable, do not exit the local function until all asynchronous I/O operations to the file object have been completed. If the local function is exited prematurely, the OVERLAPPED structure will go out of scope and it will be inaccessible to any ReadFile or WriteFile functions it encounters outside of that function.
(http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683%28v=vs.85%29.aspx)
The LockFileEx function is described here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365203%28v=vs.85%29.aspx
*Possibilities to fix this:*
A possible way to fix this problem, is to check for ERROR_IO_PENDING and use GetOverlappedResult to wait until the update to o has been completed and we can safely return if the locking has worked or not.
We know that this defeats the purpose of being asynchronous to some extend, because GetOverlappedResult waits for the I/O in case of ERROR_IO_PENDING. Do we need to optimize this case and return to java to do something else? If yes, it requires to change the tryLock mechanism because the OVERLAPPED structure needs to get passed to someone who checks and frees it later.
"api/java_nio/channels/AsynchronousFileChannel/AsynchronousFileChannel.html#tryLock".
The exception text states "Overlapped I/O operation is in progress" which is the error returned by the windows API function "LockFileEx".
The C code contains the following. Note that LockFileEx works asynchronously in this test.
OVERLAPPED o;
...
result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
...
no check for o afterwards!
With this current coding, Java_sun_nio_ch_FileDispatcherImpl_lock0 may return even though I/O is still pending. The asynchronous LockFileEx then modifies the OVERLAPPED o on stack which is no longer valid because the stack frame has gone.
According to Microsoft, this is not allowed:
-Do not deallocate or modify the OVERLAPPED structure or the data buffer until all asynchronous I/O operations to the file object have been completed.
-If you declare your pointer to the OVERLAPPED structure as a local variable, do not exit the local function until all asynchronous I/O operations to the file object have been completed. If the local function is exited prematurely, the OVERLAPPED structure will go out of scope and it will be inaccessible to any ReadFile or WriteFile functions it encounters outside of that function.
(http://msdn.microsoft.com/en-us/library/windows/desktop/aa365683%28v=vs.85%29.aspx)
The LockFileEx function is described here:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365203%28v=vs.85%29.aspx
*Possibilities to fix this:*
A possible way to fix this problem, is to check for ERROR_IO_PENDING and use GetOverlappedResult to wait until the update to o has been completed and we can safely return if the locking has worked or not.
We know that this defeats the purpose of being asynchronous to some extend, because GetOverlappedResult waits for the I/O in case of ERROR_IO_PENDING. Do we need to optimize this case and return to java to do something else? If yes, it requires to change the tryLock mechanism because the OVERLAPPED structure needs to get passed to someone who checks and frees it later.
Attachments
Issue Links
- backported by
-
JDK-8056798 (fc) FileDispatcherImpl.lock0 does not handle ERROR_IO_PENDING [win]
-
- Resolved
-