Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8137121

(fc) Infinite loop FileChannel.truncate

XMLWordPrintable

    • b84
    • Verified

        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 ----------

              igerasim Ivan Gerasimov
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: