sulong
sulong copied to clipboard
Regression: Spawning/Joining threads via NFI does not work correctly
The following examples do not work anymore since the bump of the truffle version in 26774d5c8b3d8d0eb65c58b9e2a6387d9290de9b. The critical change happened in graalvm/graal@727cc29f9747d93a0c8fc1f1384c05731658fa7a.
C
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *foo(){
printf("foo\n");
return(NULL);
}
int main(){
pthread_t thread1;
pthread_create(&thread1, NULL, &foo, NULL);
int err = pthread_join(thread1, NULL);
printf("exit %i\n", err);
return 0;
}
expected output:
foo
exit 0
actual output:
exit 0
Rust
use std::thread;
fn main() {
let n = thread::spawn(|| 7).join().unwrap();
}
expected output: -
actual output:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /checkout/src/libcore/option.rs:335
note: No backtrace available
It seems that there is no thread local context initialized for threads spawned in native code.
The C program causes the following stacktrace in thread1
:
com.oracle.truffle.llvm.runtime.SulongRuntimeException: AssertionError No current context available.
C stack trace:
LLVM IR Function @foo in cthreadbug.bc in Block {id: 0 name: implicit0}
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.executeStatements(LLVMBasicBlockNode.java:114)
at com.oracle.truffle.llvm.nodes.control.LLVMDispatchBasicBlockNode.executeGeneric(LLVMDispatchBasicBlockNode.java:80)
at com.oracle.truffle.llvm.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:74)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:64)
at com.oracle.truffle.api.impl.DefaultDirectCallNode.call(DefaultDirectCallNode.java:43)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNode.directCall(LLVMForeignCallNode.java:148)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNode.callDirectCached(LLVMForeignCallNode.java:139)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNodeGen.executeAndSpecialize(LLVMForeignCallNodeGen.java:112)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNodeGen.executeCall(LLVMForeignCallNodeGen.java:67)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolution$ForeignExecuteNode.access(LLVMFunctionMessageResolution.java:67)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeign$ForeignExecuteSubNode.accessWithTarget(LLVMFunctionMessageResolutionForeign.java:108)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeignFactory$ForeignExecuteSubNodeGen.executeAndSpecialize(LLVMFunctionMessageResolutionForeignFactory.java:55)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeignFactory$ForeignExecuteSubNodeGen.executeWithTarget(LLVMFunctionMessageResolutionForeignFactory.java:39)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeign$ForeignExecuteSubNode$EXECUTERootNode.execute(LLVMFunctionMessageResolutionForeign.java:125)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:64)
at com.oracle.truffle.api.impl.DefaultDirectCallNode.call(DefaultDirectCallNode.java:43)
at com.oracle.truffle.api.interop.InteropAccessNode.doCached(InteropAccessNode.java:186)
at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeAndSpecialize(InteropAccessNodeGen.java:80)
at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeImpl(InteropAccessNodeGen.java:45)
at com.oracle.truffle.api.interop.InteropAccessNode.execute(InteropAccessNode.java:67)
at com.oracle.truffle.api.interop.ForeignAccess.send(ForeignAccess.java:360)
at com.oracle.truffle.nfi.LibFFIClosure$CallClosureNode.execute(LibFFIClosure.java:143)
at com.oracle.truffle.nfi.LibFFIClosure$BufferRetClosureRootNode.execute(LibFFIClosure.java:186)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:82)
Caused by: java.lang.AssertionError: No current context available.
at com.oracle.truffle.api.vm.PolyglotContextImpl.requireContext(PolyglotContextImpl.java:210)
at com.oracle.truffle.api.vm.PolyglotImpl$EngineImpl.contextReferenceGet(PolyglotImpl.java:254)
at com.oracle.truffle.api.TruffleLanguage$ContextReference.get(TruffleLanguage.java:1623)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.cacheTrace(LLVMBasicBlockNode.java:159)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.traceEnabled(LLVMBasicBlockNode.java:165)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.executeStatements(LLVMBasicBlockNode.java:96)
... 23 more
com.oracle.truffle.llvm.runtime.SulongRuntimeException: AssertionError No current context available.
C stack trace:
LLVM IR Function @foo in cthreadbug.bc in Block {id: 0 name: implicit0}
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.executeStatements(LLVMBasicBlockNode.java:114)
at com.oracle.truffle.llvm.nodes.control.LLVMDispatchBasicBlockNode.executeGeneric(LLVMDispatchBasicBlockNode.java:80)
at com.oracle.truffle.llvm.nodes.func.LLVMFunctionStartNode.execute(LLVMFunctionStartNode.java:74)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:64)
at com.oracle.truffle.api.impl.DefaultDirectCallNode.call(DefaultDirectCallNode.java:43)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNode.directCall(LLVMForeignCallNode.java:148)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNode.callDirectCached(LLVMForeignCallNode.java:139)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNodeGen.executeAndSpecialize(LLVMForeignCallNodeGen.java:112)
at com.oracle.truffle.llvm.runtime.interop.LLVMForeignCallNodeGen.executeCall(LLVMForeignCallNodeGen.java:67)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolution$ForeignExecuteNode.access(LLVMFunctionMessageResolution.java:67)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeign$ForeignExecuteSubNode.accessWithTarget(LLVMFunctionMessageResolutionForeign.java:108)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeignFactory$ForeignExecuteSubNodeGen.executeAndSpecialize(LLVMFunctionMessageResolutionForeignFactory.java:55)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeignFactory$ForeignExecuteSubNodeGen.executeWithTarget(LLVMFunctionMessageResolutionForeignFactory.java:39)
at com.oracle.truffle.llvm.runtime.interop.LLVMFunctionMessageResolutionForeign$ForeignExecuteSubNode$EXECUTERootNode.execute(LLVMFunctionMessageResolutionForeign.java:125)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:64)
at com.oracle.truffle.api.impl.DefaultDirectCallNode.call(DefaultDirectCallNode.java:43)
at com.oracle.truffle.api.interop.InteropAccessNode.doCached(InteropAccessNode.java:186)
at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeAndSpecialize(InteropAccessNodeGen.java:80)
at com.oracle.truffle.api.interop.InteropAccessNodeGen.executeImpl(InteropAccessNodeGen.java:45)
at com.oracle.truffle.api.interop.InteropAccessNode.execute(InteropAccessNode.java:67)
at com.oracle.truffle.api.interop.ForeignAccess.send(ForeignAccess.java:360)
at com.oracle.truffle.nfi.LibFFIClosure$CallClosureNode.execute(LibFFIClosure.java:143)
at com.oracle.truffle.nfi.LibFFIClosure$BufferRetClosureRootNode.execute(LibFFIClosure.java:186)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:82)
Caused by: java.lang.AssertionError: No current context available.
at com.oracle.truffle.api.vm.PolyglotContextImpl.requireContext(PolyglotContextImpl.java:210)
at com.oracle.truffle.api.vm.PolyglotImpl$EngineImpl.contextReferenceGet(PolyglotImpl.java:254)
at com.oracle.truffle.api.TruffleLanguage$ContextReference.get(TruffleLanguage.java:1623)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.cacheTrace(LLVMBasicBlockNode.java:159)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.traceEnabled(LLVMBasicBlockNode.java:165)
at com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode.executeStatements(LLVMBasicBlockNode.java:96)
... 23 more
Caused by: com.oracle.truffle.api.TruffleStackTrace
AFAIK Sulong does not support threads at the moment. If fork/join/… using pthreads worked in the past, that worked just by chance (like a few other things in Sulong, including errno).
Yes. Threads worked by accident in the past. I can understand why it is a regression for you. We are working on a fix.
Hi all, is there any news on threads support or a work going on?