<div dir="ltr"><div>Hello</div><div><br></div><div>I've gotten a segfault when accessing MemorySegments via SIMD Vector out of bounds in JDK 21.</div><div>The repro is:<br></div><div>- Read from a MemorySegment via Vector.fromMemorySegment.<br></div><div>- Ensure the code get hot enough<br></div><div>- Walk of the boundary of the MemorySegment<br></div><div>- Results in SIGSEGV</div><div><br></div><div>I'm mostly posting in here just in case. Here is my repro:<br><br>import jdk.incubator.vector.ByteVector;<br>import jdk.incubator.vector.Vector;<br>import jdk.incubator.vector.VectorSpecies;<br><br>import java.io.IOException;<br>import java.lang.foreign.Arena;<br>import java.lang.foreign.MemorySegment;<br>import java.nio.ByteOrder;<br>import java.nio.channels.FileChannel;<br>import java.nio.file.Files;<br>import java.nio.file.Path;<br>import java.nio.file.Paths;<br>import java.util.Random;<br><br>public class SegFaultRepro {<br>    private static final Path file = Paths.get("example.bin");<br>    public static void main(String[] args) throws IOException {<br>        // File needs to be large enough: To get the code hot enough to be C2 compiled. Increase if JVM does not crash<br>        final long LARGE_FILE_SEG_FAULTS = 200_000;<br>        final long SMALL_FILE_WORKS = 100;<br>        setupTest(LARGE_FILE_SEG_FAULTS);<br>        VectorSpecies<Byte> byteVec = ByteVector.SPECIES_PREFERRED;<br><br>        try{<br>            Vector<Byte> blackhole = byteVec.zero();<br>            try(var arena = Arena.ofConfined();<br>                FileChannel fc = FileChannel.open(file)){<br>                MemorySegment fileContent = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size(), arena);<br>                // -Alternative 2: Also segfaults: Needs way larger memory area on my machine<br>                // MemorySegment fileContent = arena.allocate(1_000_000L*4096L);<br>                // - Alternative 3: Works as expected? Couldn't get a crash yet.<br>                //   Maybe because I can't get a large enough memory section in this basic example<br>                // MemorySegment fileContent = MemorySegment.ofArray(new byte[Integer.MAX_VALUE-1024]);<br>                long fileSize = fileContent.byteSize();<br><br>                int i = 0;<br>                while(i<byteVec.loopBound(fileSize)){<br>                    int offByOneError = i + 1;<br>                    Vector<Byte> read = byteVec.fromMemorySegment(fileContent, offByOneError, ByteOrder.BIG_ENDIAN);<br>                    blackhole = blackhole.add(read);<br>                    i+= byteVec.length();<br>                }<br>            }<br>            System.out.println(blackhole.toString());<br>        } catch (IndexOutOfBoundsException e){<br>            System.out.println("All good. We have a off by one error and got an Exception for it.");<br>        }<br>    }<br>    private static void setupTest(long LARGE_FILE_SEG_FAULTS) throws IOException {<br>        final long fileSize = LARGE_FILE_SEG_FAULTS;<br>        byte[] exampleData = new byte[4096];<br>        new Random().nextBytes(exampleData);<br>        try (var out = Files.newOutputStream(file)) {<br>            for (int i = 0; i < fileSize; i++) {<br>                out.write(exampleData);<br>            }<br>        }<br>        System.out.println("Example file created!");<br>    }<br>}<br><br><br><br></div><div>Notes:<br></div><div>- Running on x86-64bit linux.<br></div><div>- Crashes only on hot loop<br></div><div>- Works best with Memory Mapped files for me. Probably because it changes the timing / slows down the memory access to give C2 time to compile.</div><div>- I can reproduce it with an Arena.allocate Memory segment as well =).</div><div>- Could not reproduce it with a Memory<br></div><div><br><br></div><div>Best regards<br></div><div>Roman Stoffel<br></div><div><br></div></div>