JDK-8137121 : (fc) Infinite loop FileChannel.truncate
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 8u60
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-09-21
  • Updated: 2016-08-24
  • Resolved: 2015-09-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9
7u95Fixed 8u72Fixed 9 b84Fixed
Related Reports
Relates :  
Description
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 ----------