sulong icon indicating copy to clipboard operation
sulong copied to clipboard

Regression: Spawning/Joining threads via NFI does not work correctly

Open anatol1234 opened this issue 7 years ago • 3 comments

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

anatol1234 avatar Nov 10 '17 20:11 anatol1234

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).

pekd avatar Nov 13 '17 13:11 pekd

Yes. Threads worked by accident in the past. I can understand why it is a regression for you. We are working on a fix.

chumer avatar Nov 20 '17 13:11 chumer

Hi all, is there any news on threads support or a work going on?

sudosalim avatar Jul 26 '18 10:07 sudosalim