Skip to content

Commit 35b7d9c

Browse files
committed
[GR-48374] Better error messages when dependencies are missing, use NativeModules=false for multiprocessing workers.
2 parents 9a4ec82 + 9518116 commit 35b7d9c

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import java.util.Map;
5656
import java.util.Objects;
5757
import java.util.concurrent.ConcurrentHashMap;
58+
import java.util.concurrent.atomic.AtomicBoolean;
5859
import java.util.concurrent.atomic.AtomicLong;
5960

6061
import org.graalvm.collections.EconomicMap;
@@ -526,7 +527,8 @@ public int getId() {
526527
* This represents whether the current process has already loaded an instance of the native CAPI
527528
* extensions - this can only be loaded once per process.
528529
*/
529-
private static boolean nativeCAPILoaded = false;
530+
private static AtomicBoolean nativeCAPILoaded = new AtomicBoolean();
531+
private static AtomicBoolean warnedSecondContexWithNativeCAPI = new AtomicBoolean();
530532

531533
@TruffleBoundary
532534
public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context, TruffleString name, TruffleString path) throws IOException, ImportException, ApiInitException {
@@ -540,11 +542,27 @@ public static CApiContext ensureCapiWasLoaded(Node node, PythonContext context,
540542
TruffleFile capiFile = homePath.resolve(libName);
541543
try {
542544
SourceBuilder capiSrcBuilder;
543-
boolean useNative = PythonOptions.NativeModules.getValue(env.getOptions()) && !nativeCAPILoaded;
544-
nativeCAPILoaded |= useNative;
545+
final boolean useNative;
546+
if (PythonOptions.NativeModules.getValue(env.getOptions())) {
547+
useNative = nativeCAPILoaded.compareAndSet(false, true);
548+
if (!useNative && warnedSecondContexWithNativeCAPI.compareAndSet(false, true)) {
549+
LOGGER.warning("GraalPy option 'NativeModules' is set to true, " +
550+
"but only one context in the process can use native modules, " +
551+
"second and other contexts fallback to NativeModules=false and " +
552+
"will use LLVM bitcode execution via GraalVM LLVM.");
553+
}
554+
} else {
555+
useNative = false;
556+
}
545557
if (useNative) {
558+
if (!env.getInternalLanguages().containsKey(J_NFI_LANGUAGE)) {
559+
throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.SystemError, ErrorMessages.NFI_NOT_AVAILABLE, "NativeModules", "true");
560+
}
546561
capiSrcBuilder = Source.newBuilder(J_NFI_LANGUAGE, "load(RTLD_GLOBAL) \"" + capiFile.getAbsoluteFile().getPath() + "\"", "<libpython>");
547562
} else {
563+
if (!env.getInternalLanguages().containsKey(J_LLVM_LANGUAGE)) {
564+
throw PRaiseNode.raiseUncached(node, PythonBuiltinClassType.SystemError, ErrorMessages.LLVM_NOT_AVAILABLE);
565+
}
548566
capiSrcBuilder = Source.newBuilder(J_LLVM_LANGUAGE, capiFile);
549567
}
550568
if (!context.getLanguage().getEngineOption(PythonOptions.ExposeInternalSources)) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,13 @@ public abstract class ErrorMessages {
14851485
public static final TruffleString HPY_CANNOT_SPECIFY_LEG_SLOTS_WO_SETTING_LEG = tsLiteral("cannot specify .legacy_slots without setting .builtin_shape=HPyType_BuiltinShape_Legacy");
14861486
public static final TruffleString HPY_CANNOT_USE_CALL_WITH_LEGACY = tsLiteral("Cannot use HPy call protocol with legacy types that inherit the struct. " +
14871487
"Either set the basicsize to a non-zero value or use legacy slot 'Py_tp_call'.");
1488+
public static final TruffleString NFI_NOT_AVAILABLE = tsLiteral("GraalPy option '%s' is set to '%s, but the 'nfi' language, which is required for this feature, is not available. " +
1489+
"If this is a GraalPy standalone distribution: this indicates internal error. If GraalPy was used as a Maven dependency: " +
1490+
"are you missing a runtime dependency 'org.graalvm.truffle:truffle-nfi-libffi', which should be a dependency of 'org.graalvm.polyglot:python{-community}'?");
1491+
1492+
public static final TruffleString LLVM_NOT_AVAILABLE = tsLiteral("GraalPy option 'NativeModules' is set to false, but the 'llvm' language, which is required for this feature, is not available. " +
1493+
"If this is a GraalPy standalone distribution: this indicates internal error. If GraalPy was used as a Maven dependency: are you missing a runtime dependency " +
1494+
"'org.graalvm.polyglot:llvm{-community}'?");
14881495
private static final String HPY_NON_DEFAULT_MESSAGE = "This is not allowed because custom HPy_mod_create slot cannot return a builtin module object and cannot make any use of any other " +
14891496
"data defined in the HPyModuleDef. Either do not define HPy_mod_create slot and let the runtime create a builtin module object from the provided HPyModuleDef, or do not " +
14901497
"define anything else but the HPy_mod_create slot.";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,10 @@
7676
import org.graalvm.nativeimage.ImageInfo;
7777

7878
import com.oracle.graal.python.PythonLanguage;
79+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
7980
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
81+
import com.oracle.graal.python.nodes.ErrorMessages;
82+
import com.oracle.graal.python.nodes.PRaiseNode;
8083
import com.oracle.graal.python.runtime.PosixSupportLibrary.AcceptResult;
8184
import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursor;
8285
import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursorLibrary;
@@ -349,6 +352,12 @@ private static String getLibPath(PythonContext context) {
349352
private static void loadLibrary(NFIPosixSupport posix) {
350353
String path = getLibPath(posix.context);
351354
String backend = posix.nfiBackend.toJavaStringUncached();
355+
Env env = posix.context.getEnv();
356+
357+
if (!env.getInternalLanguages().containsKey(J_NFI_LANGUAGE)) {
358+
throw PRaiseNode.raiseUncached(null, PythonBuiltinClassType.SystemError, ErrorMessages.NFI_NOT_AVAILABLE, "PosixModuleBackend", "native");
359+
}
360+
352361
String withClause = backend.equals(J_NATIVE) ? "" : "with " + backend;
353362
String src = String.format("%sload (RTLD_LOCAL) \"%s\"", withClause, path);
354363
Source loadSrc = Source.newBuilder(J_NFI_LANGUAGE, src, "load:" + SUPPORTING_NATIVE_LIB_NAME).internal(true).build();
@@ -357,9 +366,13 @@ private static void loadLibrary(NFIPosixSupport posix) {
357366
LOGGER.fine(String.format("Loading native library: %s", src));
358367
}
359368
try {
360-
posix.nfiLibrary = posix.context.getEnv().parseInternal(loadSrc).call();
369+
posix.nfiLibrary = env.parseInternal(loadSrc).call();
361370
} catch (Throwable e) {
362-
throw CompilerDirectives.shouldNotReachHere("Unable to load native posix support library", e);
371+
throw new UnsupportedOperationException(String.format("""
372+
Could not load posix support library from path '%s'. Troubleshooting:\s
373+
Check permissions of the file.
374+
Missing runtime Maven dependency 'org.graalvm.truffle:truffle-nfi-libffi' (should be a dependency of `org.graalvm.polyglot:python{-community}`)?""",
375+
path));
363376
}
364377
}
365378

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,7 @@ public long spawnTruffleContext(int fd, int sentinel, int[] fdsToKeep) {
11511151
forceSharing(getOption(PythonOptions.ForceSharingForInnerContexts)).//
11521152
inheritAllAccess(true).//
11531153
initializeCreatorContext(true).//
1154+
option("python.NativeModules", "false").//
11541155
// TODO always force java posix in spawned: test_multiprocessing_spawn fails
11551156
// with that. Gives "OSError: [Errno 9] Bad file number"
11561157
// option("python.PosixModuleBackend", "java").//

0 commit comments

Comments
 (0)