oracle / fastr

A high-performance implementation of the R programming language, built on GraalVM.
Other
623 stars 64 forks source link

FastR internal error: java.lang.NullPointerException #201

Closed epragtbeamtree closed 2 years ago

epragtbeamtree commented 2 years ago

Can you reproduce with the latest development build?

Haven't tried yet, but currently running the latest version of GraalVM:

openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06)
OpenJDK 64-Bit Server VM GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06, mixed mode, sharing)

Include the following info

No error logs are produced. The only output is this:

 bin  ./helloworldr                                                                ✔ │ base  │ graalvm64-17.0.3 
true
Starting...
In R context
FastR internal error: java.lang.NullPointerException
An internal error occurred.
Please report an issue at https://github.com/oracle/fastr including the commands. You can rerun FastR with --R.PrintErrorStacktracesToFile=true to turn on internal errors logging. Please attach the log file to the issue if possible.
[1] 1

I've attempted to run the binary with the printStackTrace flag, like this:

 bin  ./helloworldr --R.PrintErrorStacktracesToFile=true

but not output is produced. When I run the application using Java instead of a binary, the application works fine.

This is the whole source file:

import java.io.*;
import java.util.stream.*;
import org.graalvm.polyglot.*;

public class HelloWorldR {

    static { /* works fine! ! */
      System.setProperty("java.awt.headless", "true");
      System.out.println(java.awt.GraphicsEnvironment.isHeadless());
      /* ---> prints true */
    }

  public static void main(String[] args) throws Exception {
    System.out.println("Starting...");
    Context allContext = Context.newBuilder("R").allowAllAccess(true).build();
    try (Context context = allContext) {
      System.out.println("In R context");
      context.eval("R", "print(1)");
    }
  }
}
 bin  $GRAALVM_HOME/bin/R --vm.version                                        ✔ │ 5s │ base  │ graalvm64-17.0.3 
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06)
OpenJDK 64-Bit Server VM GraalVM CE 22.1.0 (build 17.0.3+7-jvmci-22.1-b06, mixed mode, sharing)

macOS Monterey Version 12.4

Akirathan commented 2 years ago

Hello @epragtbeamtree, thanks for the report.

How did you produce the helloworldr binary?

I was able to reproduce the issue on Ubuntu 20.04, with the latest Graal master, with:

$GRAALVM_HOME/bin/javac HelloWorldR.java
$GRAALVM_HOME/bin/native-image --language:R HelloWorldR helloworldr
env R_HOME=$GRAALVM_HOME/languages/R ./helloworldr

From the generatedfastr_errors.log, I can see that there is some problem with fetching home from llvm, more specifically, LLVMLanguage.getLLVMLanguageHome() (which is transitively called from RContext.initialize) returns null. I don't know yet where is this issue stemming from. Let me investigate and get back to you.

Moreover, why are you setting java.awt.headless property in the static constructor? For native-image, java.awt.GraphicsEnvironment.isHeadless() should always return true, because, as far as I know, AWT is not yet supported in native images. Do you think this issue is related to the AWT library, or were you just trying some stuff?

epragtbeamtree commented 2 years ago

Hi @Akirathan ,

Thanks for your quick feedback. I created the image using the following:

native-image --language:R -Djava.awt.headless=true --no-fallback HelloWorldR

I'm setting the java.awt.headless property because if I don't, the application doesn't start at all as a native-image, and fails with the following error:

 bin  ./helloworldr                                               ✔ │ 3m 34s │ base  │ graalvm64-17.0.3 
Starting...
In R context
Exception in thread "main" org.graalvm.polyglot.PolyglotException: java.lang.UnsatisfiedLinkError: no awt in java.library.path
    at com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:132)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:47)
    at java.lang.Runtime.loadLibrary0(Runtime.java:818)
    at java.lang.System.loadLibrary(System.java:1989)
    at sun.awt.PlatformGraphicsInfo.lambda$static$0(PlatformGraphicsInfo.java:38)
    at java.security.AccessController.executePrivileged(AccessController.java:169)
    at java.security.AccessController.doPrivileged(AccessController.java:318)
    at sun.awt.PlatformGraphicsInfo.<clinit>(PlatformGraphicsInfo.java:37)
    at java.awt.GraphicsEnvironment.lambda$getHeadlessProperty$0(GraphicsEnvironment.java:150)
    at java.security.AccessController.executePrivileged(AccessController.java:169)
    at java.security.AccessController.doPrivileged(AccessController.java:318)
    at java.awt.GraphicsEnvironment.getHeadlessProperty(GraphicsEnvironment.java:145)
    at java.awt.GraphicsEnvironment.isHeadless(GraphicsEnvironment.java:122)
    at com.oracle.truffle.r.runtime.ROptions.applyDefaults(ROptions.java:213)
    at com.oracle.truffle.r.runtime.ROptions$ContextStateImpl.initialize(ROptions.java:125)
    at com.oracle.truffle.r.runtime.context.RContext.doEnvOptionsProfileInitialization(RContext.java:607)
    at com.oracle.truffle.r.runtime.context.RContext.initializeContext(RContext.java:558)
    at com.oracle.truffle.r.runtime.context.TruffleRLanguage.initializeContext(TruffleRLanguage.java:127)
    at com.oracle.truffle.r.runtime.context.TruffleRLanguage.initializeContext(TruffleRLanguage.java:61)
    at com.oracle.truffle.api.TruffleLanguage$Env.postInit(TruffleLanguage.java:3390)
    at com.oracle.truffle.api.LanguageAccessor$LanguageImpl.postInitEnv(LanguageAccessor.java:281)
    at com.oracle.truffle.polyglot.PolyglotLanguageContext.ensureInitialized(PolyglotLanguageContext.java:685)
    at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:1324)
    at com.oracle.truffle.polyglot.PolyglotContextDispatch.eval(PolyglotContextDispatch.java:63)
    at org.graalvm.polyglot.Context.eval(Context.java:399)
    at org.graalvm.polyglot.Context.eval(Context.java:425)
    at HelloWorldR.main(HelloWorldR.java:20)
Caused by: Attached Guest Language Frames (0)
Internal GraalVM error, please report at https://github.com/oracle/graal/issues/.
Akirathan commented 2 years ago

I'm setting the java.awt.headless property because if I don't, the application doesn't start at all as a native-image, and fails with the following error:

Seems related to MacOS-specific issue in https://github.com/hpi-swa/trufflesqueak/issues/168. On Ubuntu 20.04, I don't have to specify java.awt.headless property. Anyway, this is unrelated to this issue.

Our problem is with providing correct home directories for Truffle languages. The issue is with configuration - just run native image build with:

$GRAALVM_HOME/bin/native-image --language:R -Dorg.graalvm.launcher.home=$GRAALVM_HOME HelloWorldR

and everything works as expected.

For more info, see https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.home/src/org/graalvm/home/impl/DefaultHomeFinder.java

Akirathan commented 2 years ago

I am closing this issue now as it is unrelated to FastR.

epragtbeamtree commented 2 years ago

@Akirathan Thanks for looking into this.

Would it be helpful to give a bit more information than just the NPE? I'm happy to help in that, but is there a way how I can run with debug or verbose information to see where exactly the NPE occured?

steve-s commented 2 years ago

Truffle team is planning to work on documenting and improving this experience (setting language home for native images with some languages embedded) in general.

It is good point that TruffleLanguage#getLanguageHome() may instead of returning null throw some nice exception. Its JavaDoc does not document what happens when the language home is not available. CC @jchalou

jchalou commented 2 years ago

@steve-s @epragtbeamtree @Akirathan I am not sure how the issue is related to the LLVM's language home, because what fixed it was setting the org.graalvm.launcher.home property which is not setting the LLVM language home returned by LLVMLanguage.getLLVMLanguageHome(). I also haven't found a place where returning null from TruffleLanguage#getLanguageHome() would cause a NPE, but maybe I am missing something.

Akirathan commented 2 years ago

@jchalou - LLVMLanguage#getLLVMLanguageHome transitively calls into com.oracle.truffle.polyglot.LanguageCache#getLanguageHomeImpl, which checks "org.graalvm.language.llvm.home" property, which was set by DefaultHomeFinder according to the provided "org.graalvm.launcher.home" property during native image build time.

So, if org.graalvm.launcher.home is not set during the native image build time, LLVMLanguage#getLLVMLanguageHome returns null, which later causes NPE in com.oracle.truffle.llvm.runtime.ToolchainImpl.getToolPath - you can see that in this stacktrace: fastr_errors.log.

TL:DR; NPE is thrown not directly in TruffleLanguage#getLanguageHome(), but later in FastR. More specifically, when loading the base package and trying to figure out LLVM toolchain path (as can be seen in the attached stack trace). I guess that what @steve-s was trying to say is whether it makes sense for TruffleLanguage#getLanguageHome() to return null, and whether throwing some custom exception in case the home is missing wouldn't be better? If returning null from TruffleLanguage#getLanguageHome() makes sense, then we will handle such case in fastr. It is possible that null home is problematic only for fastr, and not yet for any other truffle language.

jchalou commented 2 years ago

Ok, I missed that DefaultHomeFinder sets the language homes from launcher home during native image build time. I will discuss this internally in the team whether we can improve anything. Thanks.

jchalou commented 2 years ago

We do not plan to change the functionality at the moment. It is up to the languages to react properly to the situation where TruffleLanguage#getLanguageHome returns null. In this case the LLVM language needs an improvement. However, we will improve the embedding documentation here: https://www.graalvm.org/22.1/reference-manual/embed-languages/#build-native-executables-from-polyglot-applications to mention language homes.