Search in sources :

Example 1 with Uninterruptible

use of com.oracle.svm.core.annotate.Uninterruptible in project graal by oracle.

the class PosixJavaLangSubstitutions method uninterruptibleForkAndExec.

@Uninterruptible(reason = "fragile state after fork()")
private static int uninterruptibleForkAndExec(CCharPointer file, CCharPointer dir, CCharPointerPointer argv, CCharPointerPointer envp, int[] stdioFds, int initialFailFd, PointerBase buffer, int buflen, CCharPointer procFdsPath, CCharPointer searchPaths, CCharPointer searchPathSeparator) {
    int childPid;
    childPid = UnistdNoTransitions.fork();
    if (childPid != 0) {
        return childPid;
    }
    // If we are here, we are the child process.
    int failFd = initialFailFd;
    try {
        // In case of an error, we "return" to end up in the finally block below and notify the
        // parent process of the failure.
        final int gotoFinally = -1;
        if (Java_lang_UNIXProcess_Supplement.dup2(stdioFds[0], 0) < 0) {
            return gotoFinally;
        }
        if (Java_lang_UNIXProcess_Supplement.dup2(stdioFds[1], 1) < 0) {
            return gotoFinally;
        }
        if (Java_lang_UNIXProcess_Supplement.dup2(stdioFds[2], 2) < 0) {
            return gotoFinally;
        }
        if (Java_lang_UNIXProcess_Supplement.dup2(failFd, 3) < 0) {
            return gotoFinally;
        }
        failFd = 3;
        // FD_CLOEXEC: close fail pipe on exec() to indicate success to parent
        if (Fcntl.fcntl_no_transition(failFd, Fcntl.F_SETFD(), Fcntl.FD_CLOEXEC()) < 0) {
            return gotoFinally;
        }
        /*
             * opendir() below allocates a file descriptor. We close failFd+1 so it should become
             * the descriptor allocated to opendir() and we can avoid closing it together with the
             * other descriptors.
             */
        final int maxFd = failFd + 1;
        if (UnistdNoTransitions.close(maxFd) < 0) {
            return gotoFinally;
        }
        if (procFdsPath.isNull()) {
            // We have no procfs, resort to close file descriptors by trial and error
            int maxOpenFds = (int) UnistdNoTransitions.sysconf(Unistd._SC_OPEN_MAX());
            for (int fd = maxFd + 1; fd < maxOpenFds; fd++) {
                if (UnistdNoTransitions.close(fd) != 0 && Errno.errno() != Errno.EBADF()) {
                    return gotoFinally;
                }
            }
        } else {
            DIR fddir = Dirent.opendir_no_transition(procFdsPath);
            if (fddir.isNull()) {
                return gotoFinally;
            }
            dirent dirent = WordFactory.pointer(buffer.rawValue());
            direntPointer direntptr = StackValue.get(SizeOf.get(direntPointer.class));
            int status;
            while ((status = Dirent.readdir_r_no_transition(fddir, dirent, direntptr)) == 0 && direntptr.read().isNonNull()) {
                CCharPointerPointer endptr = StackValue.get(SizeOf.get(CCharPointerPointer.class));
                long fd = LibC.strtol(dirent.d_name(), endptr, 10);
                if (fd > maxFd && endptr.read().isNonNull() && endptr.read().read() == '\0') {
                    UnistdNoTransitions.close((int) fd);
                }
            }
            if (status != 0) {
                // readdir_r() does not set errno
                Errno.set_errno(status);
                return gotoFinally;
            }
            Dirent.closedir_no_transition(fddir);
        }
        if (dir.isNonNull()) {
            if (UnistdNoTransitions.chdir(dir) < 0) {
                return gotoFinally;
            }
        }
        CCharPointerPointer actualEnvp = envp;
        if (actualEnvp.isNull()) {
            actualEnvp = LibCHelper.getEnviron();
        }
        if (LibC.strchr(file, '/').isNonNull()) {
            UnistdNoTransitions.execve(argv.read(0), argv, actualEnvp);
        } else {
            // Scan PATH for the file to execute. We cannot use execvpe()
            // because it is a GNU extension that is not universally available.
            final int fileStrlen = (int) LibC.strlen(file).rawValue();
            int stickyErrno = 0;
            final CCharPointerPointer saveptr = StackValue.get(SizeOf.get(CCharPointerPointer.class));
            saveptr.write(WordFactory.nullPointer());
            CCharPointer searchDir = LibC.strtok_r(searchPaths, searchPathSeparator, saveptr);
            while (searchDir.isNonNull()) {
                CCharPointer bufptr = WordFactory.pointer(buffer.rawValue());
                int len0 = (int) LibC.strlen(searchDir).rawValue();
                if (len0 + fileStrlen + 2 > buflen) {
                    Errno.set_errno(Errno.ENAMETOOLONG());
                    continue;
                }
                if (len0 > 0) {
                    LibC.strcpy(bufptr, searchDir);
                    if (bufptr.read(len0 - 1) != '/') {
                        bufptr.write(len0, (byte) '/');
                        len0++;
                    }
                }
                LibC.strcpy(bufptr.addressOf(len0), file);
                UnistdNoTransitions.execve(bufptr, argv, actualEnvp);
                int e = Errno.errno();
                if (e == Errno.EACCES()) {
                    // as exec(): report EACCES unless we succeed later
                    stickyErrno = e;
                } else if (e == Errno.ENOENT() || e == Errno.ENOTDIR() || e == Errno.ELOOP() || e == Errno.ESTALE() || e == Errno.ENODEV() || e == Errno.ETIMEDOUT()) {
                // ignore
                } else {
                    stickyErrno = e;
                    // bad
                    break;
                }
                searchDir = LibC.strtok_r(WordFactory.nullPointer(), searchPathSeparator, saveptr);
            }
            if (stickyErrno != 0) {
                Errno.set_errno(stickyErrno);
            }
        }
    // If we are here, exec certainly failed.
    } catch (Throwable t) {
        Errno.set_errno(Integer.MIN_VALUE);
    } finally {
        try {
            // notify parent of failure
            final int intSize = SizeOf.get(CIntPointer.class);
            CIntPointer pErrno = StackValue.get(intSize);
            pErrno.write(Errno.errno());
            Java_lang_UNIXProcess_Supplement.writeEntirely(failFd, pErrno, WordFactory.unsigned(intSize));
            UnistdNoTransitions.close(failFd);
        } finally {
            UnistdNoTransitions._exit(-1);
        }
    }
    throw VMError.shouldNotReachHere();
}
Also used : CIntPointer(org.graalvm.nativeimage.c.type.CIntPointer) Dirent.direntPointer(com.oracle.svm.core.posix.headers.Dirent.direntPointer) DIR(com.oracle.svm.core.posix.headers.Dirent.DIR) CCharPointerPointer(org.graalvm.nativeimage.c.type.CCharPointerPointer) CCharPointer(org.graalvm.nativeimage.c.type.CCharPointer) Dirent.dirent(com.oracle.svm.core.posix.headers.Dirent.dirent) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible)

Example 2 with Uninterruptible

use of com.oracle.svm.core.annotate.Uninterruptible in project graal by oracle.

the class PosixCEntryPointSnippets method failFatally.

@Uninterruptible(reason = "Unknown thread state.")
@SubstrateForeignCallTarget
private static void failFatally(int code, CCharPointer message) {
    FILE stderr = fdopen(2, FAIL_FATALLY_FDOPEN_MODE.get());
    fprintfSD(stderr, FAIL_FATALLY_MESSAGE_FORMAT.get(), message, code);
    LibC.exit(code);
}
Also used : FILE(com.oracle.svm.core.posix.headers.Stdio.FILE) SubstrateForeignCallTarget(com.oracle.svm.core.snippets.SubstrateForeignCallTarget) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible)

Example 3 with Uninterruptible

use of com.oracle.svm.core.annotate.Uninterruptible in project graal by oracle.

the class PosixCEntryPointSnippets method createIsolate.

@Uninterruptible(reason = "Thread state not yet set up.")
@SubstrateForeignCallTarget
private static int createIsolate(CEntryPointCreateIsolateParameters parameters, int vmThreadSize) {
    WordPointer isolate = StackValue.get(SizeOf.get(WordPointer.class));
    isolate.write(Word.nullPointer());
    int error = PosixIsolates.create(isolate, parameters);
    if (error != Errors.NO_ERROR) {
        return error;
    }
    if (UseHeapBaseRegister.getValue()) {
        setHeapBase(PosixIsolates.getHeapBase(isolate.read()));
    }
    if (MultiThreaded.getValue()) {
        PosixVMThreads.ensureInitialized();
    }
    return attachThread(isolate.read(), vmThreadSize);
}
Also used : WordPointer(org.graalvm.nativeimage.c.type.WordPointer) Safepoint(com.oracle.svm.core.thread.Safepoint) SubstrateForeignCallTarget(com.oracle.svm.core.snippets.SubstrateForeignCallTarget) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible)

Example 4 with Uninterruptible

use of com.oracle.svm.core.annotate.Uninterruptible in project graal by oracle.

the class PosixCEntryPointSnippets method attachThread.

@Uninterruptible(reason = "Thread state not yet set up.")
@SubstrateForeignCallTarget
private static int attachThread(Isolate isolate, int vmThreadSize) {
    int sanityError = PosixIsolates.checkSanity(isolate);
    if (sanityError != Errors.NO_ERROR) {
        return sanityError;
    }
    if (UseHeapBaseRegister.getValue()) {
        setHeapBase(PosixIsolates.getHeapBase(isolate));
    }
    if (MultiThreaded.getValue()) {
        if (!PosixVMThreads.isInitialized()) {
            return Errors.UNINITIALIZED_ISOLATE;
        }
        IsolateThread thread = PosixVMThreads.VMThreadTL.get();
        if (VMThreads.isNullThread(thread)) {
            // not attached
            thread = LibC.calloc(WordFactory.unsigned(1), WordFactory.unsigned(vmThreadSize));
            VMThreads.attachThread(thread);
            // Store thread and isolate in thread-local variables.
            PosixVMThreads.VMThreadTL.set(thread);
            PosixVMThreads.IsolateTL.set(thread, isolate);
        }
        writeCurrentVMThread(thread);
    }
    return Errors.NO_ERROR;
}
Also used : IsolateThread(org.graalvm.nativeimage.IsolateThread) Safepoint(com.oracle.svm.core.thread.Safepoint) SubstrateForeignCallTarget(com.oracle.svm.core.snippets.SubstrateForeignCallTarget) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible)

Example 5 with Uninterruptible

use of com.oracle.svm.core.annotate.Uninterruptible in project graal by oracle.

the class PosixCEntryPointSnippets method detachThreadMT.

@SubstrateForeignCallTarget
@Uninterruptible(reason = "Thread state going away.")
@RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Must not (thread-local) allocate while detaching a thread.")
private static int detachThreadMT(IsolateThread thread) {
    int result = Errors.NO_ERROR;
    /*
         * Set thread status to exited. This makes me immune to safepoints (the safepoint mechanism
         * ignores me). Also clear any pending safepoint requests, since I will not honor them.
         */
    VMThreads.StatusSupport.setStatusExited();
    Safepoint.setSafepointRequested(Safepoint.SafepointRequestValues.RESET);
    // try-finally because try-with-resources can call interruptible code
    VMThreads.THREAD_MUTEX.lockNoTransition();
    try {
        detachJavaLangThreadMT(thread);
        // clear references to thread to avoid unintended use
        writeCurrentVMThread(VMThreads.nullThread());
        PosixVMThreads.VMThreadTL.set(VMThreads.nullThread());
        VMThreads.detachThread(thread);
    } catch (Throwable t) {
        result = Errors.UNSPECIFIED;
    } finally {
        VMThreads.THREAD_MUTEX.unlock();
        LibC.free(thread);
    }
    return result;
}
Also used : Safepoint(com.oracle.svm.core.thread.Safepoint) SubstrateForeignCallTarget(com.oracle.svm.core.snippets.SubstrateForeignCallTarget) Uninterruptible(com.oracle.svm.core.annotate.Uninterruptible) RestrictHeapAccess(com.oracle.svm.core.annotate.RestrictHeapAccess)

Aggregations

Uninterruptible (com.oracle.svm.core.annotate.Uninterruptible)54 Pointer (org.graalvm.word.Pointer)15 UnsignedWord (org.graalvm.word.UnsignedWord)9 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)7 SubstrateForeignCallTarget (com.oracle.svm.core.snippets.SubstrateForeignCallTarget)5 IsolateThread (org.graalvm.nativeimage.IsolateThread)5 AlignedHeader (com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader)4 Safepoint (com.oracle.svm.core.thread.Safepoint)4 HostedMethod (com.oracle.svm.hosted.meta.HostedMethod)4 CodePointer (org.graalvm.nativeimage.c.function.CodePointer)4 CCharPointer (org.graalvm.nativeimage.c.type.CCharPointer)4 RestrictHeapAccess (com.oracle.svm.core.annotate.RestrictHeapAccess)3 Substitute (com.oracle.svm.core.annotate.Substitute)3 Log (com.oracle.svm.core.log.Log)3 Time.timespec (com.oracle.svm.core.posix.headers.Time.timespec)3 Time.timeval (com.oracle.svm.core.posix.headers.Time.timeval)3 Time.timezone (com.oracle.svm.core.posix.headers.Time.timezone)3 DebugContext (org.graalvm.compiler.debug.DebugContext)3 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)3 CIntPointer (org.graalvm.nativeimage.c.type.CIntPointer)3