|
Relates :
|
FULL PRODUCT VERSION :
A DESCRIPTION OF THE PROBLEM :
sun.nio.ch.FileChannelImpl#truncate(long) has this loop
do {
rv = (int)position0(fd, p);
} while ((rv == IOStatus.INTERRUPTED) && isOpen());
Problem is that in cases where position0(fd, p) returns p, and it just happens that p is a long value that when cast to int becomes -3, then the loop here where never terminate since IOStatus.INTERRUPTED is -3 as well.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
package play;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Play {
public static void main(String[] args) throws Throwable {
ByteBuffer zeroByte = ByteBuffer.wrap(new byte[1]);
File file = File.createTempFile("whatever", null);
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")
) {
FileChannel channel = raf.getChannel();
channel.position(8589934589L + 1);
channel.write(zeroByte);
zeroByte.flip();
channel.truncate(8589934589L);
}
}
}
and now the thread will be stuck in that loop within FIleChannelImpl as described
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
that the truncation works
ACTUAL -
the thread gets into an infinite loop and never returns
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package play;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Play {
public static void main(String[] args) throws Throwable {
ByteBuffer zeroByte = ByteBuffer.wrap(new byte[1]);
File file = File.createTempFile("whatever", null);
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")
) {
FileChannel channel = raf.getChannel();
channel.position(8589934589L + 1);
channel.write(zeroByte);
zeroByte.flip();
channel.truncate(8589934589L);
}
}
}
---------- END SOURCE ----------