Segmentation fault with new Linker.Option.CaptureCallState feature
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Nov 15 00:02:58 UTC 2022
Hi Mark,
many thanks for the bug report (and the kind words :-) ).
This looks like a bug - in the sense that I'm not aware of any
limitations in this area. The fact that the function returns a value
must be tripping something up in the assembly trampoline we generate.
For now, I've filed this:
https://bugs.openjdk.org/browse/JDK-8296973
Thanks!
Maurizio
On 14/11/2022 21:56, Mark Schroeder wrote:
> Hi everyone,
>
> first of all, I wanted to thank you for the amazing work you're doing
> in this project. I really enjoy working with the API.
> While experimenting with some system calls under Linux, I encountered
> an issue with the new Linker.Option.CaptureCallState feature delivered
> here: https://github.com/openjdk/panama-foreign/pull/742. When calling
> a function that returns a value (such as a system call returning -1 in
> case of an error), the JVM exits due to a segmentation fault. As a
> minimal example, I adapted the test code from the pull request (the
> issue is not limited to system calls).
> This is the C code:
>
> #include <errno.h>
> #include <stdint.h>
>
> void set_errno(int32_t value) {
> errno = value;
> }
>
> int32_t set_errno2(int32_t value) {
> errno = (int) value;
> return value * 2;
> }
>
> I compiled the code on Linux (Fedora 36) with the following command:
> gcc -o libCaptureCallState.so -shared -Wall libCaptureCallState.c
> This is the Java code causing the issue:
>
> import java.lang.foreign.FunctionDescriptor;
> import java.lang.foreign.Linker;
> import java.lang.foreign.MemoryLayout;
> import java.lang.foreign.MemorySegment;
> import java.lang.foreign.MemorySession;
> import java.lang.foreign.SymbolLookup;
> import java.lang.foreign.ValueLayout;
> import java.lang.invoke.MethodHandle;
> import java.lang.invoke.VarHandle;
> import java.nio.file.Path;
>
> public class TestCaptureCallState {
>
> public static void main(String[] args) throws Throwable {
> System.load(Path.of("libCaptureCallState.so").toAbsolutePath().toString());
> Linker linker = Linker.nativeLinker();
> SymbolLookup lookup = SymbolLookup.loaderLookup();
> Linker.Option.CaptureCallState state =
> Linker.Option.captureCallState("errno");
> VarHandle errno =
> state.layout().varHandle(MemoryLayout.PathElement.groupElement("errno"));
> MethodHandle setErrno = linker.downcallHandle(
> lookup.find("set_errno").orElseThrow(),
> FunctionDescriptor.ofVoid(ValueLayout.JAVA_INT),
> state
> );
> MethodHandle setErrno2 = linker.downcallHandle(
> lookup.find("set_errno2").orElseThrow(),
> FunctionDescriptor.of(ValueLayout.JAVA_INT,
> ValueLayout.JAVA_INT),
> state
> );
>
> try (MemorySession session = MemorySession.openConfined()) {
> MemorySegment saveSeg = session.allocate(state.layout());
> System.out.println("Testing set_errno ...");
> setErrno.invoke(saveSeg, 42);
> int savedErrno = (int) errno.get(saveSeg);
> System.out.printf("errno: %d\n", savedErrno);
> }
> try (MemorySession session = MemorySession.openConfined()) {
> System.out.println("Testing set_errno2 ...");
> MemorySegment saveSeg = session.allocate(state.layout());
> int result = (int) setErrno2.invoke(saveSeg, 42);
> int savedErrno = (int) errno.get(saveSeg);
> System.out.printf("errno: %d, result: %d\n", savedErrno,
> result);
> }
> }
> }
>
> I executed the code with the following commands:
> javac --enable-preview --release 20 TestCaptureCallState.java
> java --enable-preview --enable-native-access=ALL-UNNAMED
> TestCaptureCallState
> The code fails when calling the function with the return value:
>
> Testing set_errno ...
> errno: 42
> Testing set_errno2 ...
> #
> # A fatal error has been detected by the Java Runtime Environment:
> #
> # SIGSEGV (0xb) at pc=0x00007fea8ed0dce8, pid=47154, tid=47155
> #
> # JRE version: OpenJDK Runtime Environment (20.0) (build
> 20-internal-adhoc.maschroeder.openjdk--panama-foreign)
> # Java VM: OpenJDK 64-Bit Server VM
> (20-internal-adhoc.maschroeder.openjdk--panama-foreign, mixed mode,
> sharing, tiered, compressed oops, compressed class ptrs, g1 gc,
> linux-amd64)
> # Problematic frame:
> # V [libjvm.so+0x70dce8] DowncallLinker::capture_state(int*, int)+0x18
> ...
>
> Is there something that I overlooked? Is this a known limitation of
> the new feature?
>
> Mark
More information about the panama-dev
mailing list