Skip to content

MacOS native image calling JNI code: passed in argument to JNI call always passed as 0 #2152

Closed
@retrogradeorbit

Description

@retrogradeorbit

Describe GraalVM and your environment :

  • GraalVM version or commit id if built from source: 19.3.1, 20.1.0-dev
  • CE or EE: CE
  • Build Time or run time failure: run-time
  • JDK version: JDK8 and JDK11
  • Native compiler information:
    Run the following to capture compiler version
    • In windows: cl.exe
    • In macOS : cc -v
    • In Linux: gcc --version
Apple LLVM version 10.0.0 (clang-1000.11.45.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode-10.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
  • Native linker information:
    Run the following to capture linker version
    • In windows: cl.exe
    • In macOS : cc -Wl,-v
    • In Linux: gcc -Wl,--version
@(#)PROGRAM:ld  PROJECT:ld64-302.3
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em (tvOS)
Library search paths:
	/usr/lib
	/usr/local/lib
Framework search paths:
	/Library/Frameworks/
	/System/Library/Frameworks/
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
  • OS and OS Version: Mac OS X 10.13.6 17G65 (Circle CI mac build node)
  • Architecture: AMD64
  • The output of java -Xinternalversion:
Java HotSpot(TM) 64-Bit Server VM (25.181-b13) for bsd-amd64 JRE (1.8.0_181-b13), built on Jul  7 2018 01:02:31 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

Have you verified this issue still happens when using the latest snapshot?
Yes. Happens on all MacOS native-images up to and including 20.1.0-dev

Describe the issue
JNI code writing to Unix domain sockets, when called from a graal native-image on MacOS, always writes 0 bytes.
JNI call on native-image on MacOS gets argument passed always as 0 when it shouldn't be:

JNIEXPORT jint JNICALL Java_SocketTest_unix_1socket_1write
  (JNIEnv *env, jclass this, jint fd, jbyteArray buf, jint count)

The final jint argument count is always passed a 0. (note: the first jint arg fd is passed correctly)

On MacOS the code works when running on the JVM, but fails when run as a native-image.
The code works on Linux, on both the JVM and as a native image.

Describe the full native-image command

Capture full native-image command by running with the `--verbose` flag e.g.:
bin/native-image \
        -jar SocketTest.jar \
        -H:Name=sockettest \
        -H:+ReportExceptionStackTraces \
        -H:ConfigurationFileDirectories=config-dir \
        --initialize-at-build-time \
        --verbose \
        --no-fallback \
        --no-server \
        "-J-Xmx1g"
javac src/SocketTest.java
cd src && jar cfm ../SocketTest.jar manifest.txt SocketTest.class
cd src && javah -o SocketTest.h -cp ./ SocketTest
cc -I/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/include -I/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/include/darwin -I. -dynamiclib -undefined suppress -flat_namespace src/SocketTest.c -o libSocketTest.dylib -fPIC
/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/bin/native-image \
        -jar SocketTest.jar \
        -H:Name=sockettest \
        -H:+ReportExceptionStackTraces \
        -H:ConfigurationFileDirectories=config-dir \
        --initialize-at-build-time \
        --verbose \
        --no-fallback \
        --no-server \
        "-J-Xmx1g"
Executing [
/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/bin/java \
-XX:+UnlockExperimentalVMOptions \
-XX:+EnableJVMCI \
-Dtruffle.TrustAllTruffleRuntimeProviders=true \
-Dtruffle.TruffleRuntime=com.oracle.truffle.api.impl.DefaultTruffleRuntime \
-Dgraalvm.ForcePolyglotInvalid=true \
-Dgraalvm.locatorDisabled=true \
-d64 \
-XX:-UseJVMCIClassLoader \
-XX:+UseJVMCINativeLibrary \
-Xss10m \
-Xms1g \
-Xmx6871947672 \
-Duser.country=US \
-Duser.language=en \
-Dorg.graalvm.version=19.3.1 \
-Dorg.graalvm.config=CE \
-Dcom.oracle.graalvm.isaot=true \
-Djvmci.class.path.append=/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/graal.jar \
-javaagent:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/svm.jar \
-Djdk.internal.lambda.disableEagerInitialization=true \
-Djdk.internal.lambda.eagerlyInitialize=false \
-Djava.lang.invoke.InnerClassLambdaMetafactory.initializeLambdas=false \
-Xmx1g \
-Xbootclasspath/a:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/boot/graal-sdk.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/boot/graaljs-scriptengine.jar \
-cp \
/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/graal-llvm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/javacpp-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/llvm-platform-specific-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/llvm-wrapper-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/objectfile.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/pointsto.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/svm-llvm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/svm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/graal-management.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/graal.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/jvmci-api.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/jvmci-hotspot.jar \
com.oracle.svm.hosted.NativeImageGeneratorRunner \
-imagecp \
/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/boot/graal-sdk.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/boot/graaljs-scriptengine.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/graal-llvm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/javacpp-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/llvm-platform-specific-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/llvm-wrapper-shadowed.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/objectfile.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/pointsto.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/svm-llvm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/builder/svm.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/graal-management.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/graal.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/jvmci-api.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/jvmci/jvmci-hotspot.jar:/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/library-support.jar:/Users/distiller/project/SocketTest.jar \
-H:Path=/Users/distiller/project \
-H:Class=SocketTest \
-H:+ReportExceptionStackTraces \
-H:ConfigurationFileDirectories=config-dir \
-H:ClassInitialization=:build_time \
-H:FallbackThreshold=0 \
-H:CLibraryPath=/Users/distiller/graalvm-ce-java8-19.3.1/Contents/Home/jre/lib/svm/clibraries/darwin-amd64 \
-H:Name=sockettest
]
[sockettest:658]    classlist:   2,609.97 ms
[sockettest:658]        (cap):   2,352.17 ms
[sockettest:658]        setup:   4,091.46 ms
[sockettest:658]   (typeflow):   4,852.49 ms
[sockettest:658]    (objects):   4,295.98 ms
[sockettest:658]   (features):     218.70 ms
[sockettest:658]     analysis:   9,509.99 ms
[sockettest:658]     (clinit):     145.00 ms
[sockettest:658]     universe:     467.81 ms
[sockettest:658]      (parse):   1,066.00 ms
[sockettest:658]     (inline):   1,890.51 ms
[sockettest:658]    (compile):   6,216.90 ms
[sockettest:658]      compile:   9,636.61 ms
[sockettest:658]        image:     727.41 ms
[sockettest:658]        write:     244.79 ms
[sockettest:658]      [total]:  27,775.94 ms
rm -f socket; \
    nc -l -U socket & \
    sleep 5; \
    LD_LIBRARY_PATH=./ ./sockettest
Hello world; this is C talking!
opened fd: 3
writing to fd...
bytes written (should be 14): 0
closed fd: 3
Test FAILED!

Code snippet or code repository that reproduces the issue
I've setup a repo reducing the expression of the problem to the barest minimum.

https://github.com/epiccastle/graal-jni-unix-socket-test

Steps to reproduce the issue
Please include both build steps as well as run steps

  1. git clone git@github.com:epiccastle/graal-jni-unix-socket-test.git
  2. cd graal-jni-unix-socket-test
  3. make run-native-test GRAALVM=$GRAALVM_HOME

Expected behavior
The test should pass. 14 bytes should be written to the socket. Instead 0 bytes are written.

Additional context
Add any other context about the problem here. Specially important are stack traces or log output. Feel free to link to gists or to screenshots if necesary

Details
CI builds of this test code on both JVM and native image on all the graal versions and linux, too:
https://circleci.com/gh/epiccastle/graal-jni-unix-socket-test/tree/master

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions