RFR(S): 8248910: NPE when freeing the memory for a slice from a buffer
Yangfei (Felix)
felix.yang at huawei.com
Tue Aug 18 08:13:36 UTC 2020
Hi,
Sorry for the late reply.
> -----Original Message-----
> From: Alan Bateman [mailto:Alan.Bateman at oracle.com]
> Sent: Monday, August 3, 2020 2:37 PM
> To: Yangfei (Felix) <felix.yang at huawei.com>; nio-dev at openjdk.java.net
> Subject: Re: RFR(S): 8248910: NPE when freeing the memory for a slice from
> a buffer
>
> On 03/08/2020 02:46, Yangfei (Felix) wrote:
> > Hi,
> >
> > Bug: https://bugs.openjdk.java.net/browse/JDK-8248910
> > Webrev: http://cr.openjdk.java.net/~fyang/8248910/webrev.00
> >
> > As commented on the bug, initially we observed this issue when we use
> Randoop which is a unit test generator for Java.
> > The overall procedure is described by the newly add test.
> > For a slice from a ByteBuffer, it does not have a cleaner, which leads to
> the NPE.
> > Here, I think we should not try to free the memory of a slice.
> > Proposed fix adds a null check for cleaner in Util.free before invoking its
> clean() method.
> >
> I think we need to diagnose the issue a bit further in the discussion here
> before discussing changes in this area.
>
> I can see there are issues if aligned slices are offered to the buffer cache but
> this should only arise with direct file I/O (JDK specific
> ExtendedOpenOption.DIRECT)? That is an issue that should be fixed but I
> can't tell if it related to your bug or not.
Is there an bug/issue to look at?
> Do you know if Randoop is using direct I/O? Maybe it is instrumenting JDK
> classes to use aligned slices? Or maybe it is using the internal buffer cache
> directly?
We spend some time looking into how Randoop works.
Overall, this tool checks for public method in the specified class file and composes test cases from these methods.
It calls the java compiler to compile the test cases and run them. One of the auto-generated test case looks like:
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class RandoopTemporarySeqTest285 {
public static boolean debug = false;
@Test
public void theSequence285() throws Throwable {
if (debug)
System.out.format("%n%s%n", "RandoopTemporarySeqTest285.theSequence285");
java.nio.ByteBuffer byteBuffer2 = sun.nio.ch.Util.getTemporaryAlignedDirectBuffer((int) (short) 100, (int) ' ');
sun.nio.ch.Util.releaseTemporaryDirectBuffer(byteBuffer2);
org.junit.Assert.assertNotNull(byteBuffer2);
}
}
So it looks to me like it is using the internal buffer cache directly.
I have put the complete call trace of the NPE on the bug.
This bug could also be triggered with the following test:
$ cat RandoopTest.java
import java.nio.ByteBuffer;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class RandoopTest {
public static void main(String[] args) {
ByteBuffer buffer = sun.nio.ch.Util.getTemporaryAlignedDirectBuffer(10, 32);
sun.nio.ch.Util.releaseTemporaryDirectBuffer(buffer);
JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
systemJavaCompiler.run(null, null, null, new String[]{"/home/yangfei/test/Hello.java"});
}
}
$ javac --add-exports=java.base/sun.nio.ch=ALL-UNNAMED RandoopTest.java
$ java RandoopTest
An exception has occurred in the compiler (16-internal). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program, the following diagnostic, and the parameters passed to the Java compiler in your report. Thank you.
java.lang.NullPointerException: Cannot invoke "jdk.internal.ref.Cleaner.clean()" because the return value of "sun.nio.ch.DirectBuffer.cleaner()" is null
at java.base/sun.nio.ch.Util.free(Util.java:328)
at java.base/sun.nio.ch.Util.getTemporaryDirectBuffer(Util.java:241)
at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:242)
at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:229)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:65)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:107)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:101)
at jdk.compiler/com.sun.tools.javac.file.BaseFileManager.makeByteBuffer(BaseFileManager.java:412)
at jdk.compiler/com.sun.tools.javac.file.PathFileObject.getCharContent(PathFileObject.java:483)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.readSource(JavaCompiler.java:613)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:676)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:1033)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:1020)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:938)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:317)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:176)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:82)
at jdk.compiler/com.sun.tools.javac.api.JavacTool.run(JavacTool.java:208)
at RandoopTest.main(RandoopTest.java:12)
Hope this helps.
Best Regards,
Felix
More information about the nio-dev
mailing list