Calling D library from other languages on linux using foreign threads

tchaloupka chalucha at gmail.com
Fri Mar 22 19:34:14 UTC 2019


I've searched a lot at it should be working at least on linux, 
but apparently is not or I'm doing something totally wrong..

Our use case is to call shared D library from C# (.Net Core) and 
from different threads.

What I've read about this, is that foreign thread should be 
registered by `thread_attachThis()`.

But even with this, there is a trouble with GC being called in 
that thread which ends up with:

```D
Thread 3 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7aeb700 (LWP 5850)]
0x000000000045bed7 in 
_D4core6thread15scanAllTypeImplFNbMDFNbEQBmQBk8ScanTypePvQcZvQgZv 
()
(gdb) bt
#0  0x000000000045bed7 in 
_D4core6thread15scanAllTypeImplFNbMDFNbEQBmQBk8ScanTypePvQcZvQgZv 
()
#1  0x000000000045be7f in 
_D4core6thread18thread_scanAllTypeUNbMDFNbEQBpQBn8ScanTypePvQcZvZ__T9__lambda2TQvZQoMFNbQBeZv ()
#2  0x000000000044dc10 in core.thread.callWithStackShell(scope 
void(void*) nothrow delegate) ()
#3  0x000000000045be56 in thread_scanAllType ()
#4  0x00000000004599aa in thread_scanAll ()
#5  0x00000000004582a9 in 
_D2gc4impl12conservativeQw3Gcx__T7markAllS_DQBqQBqQBoQBzQBe16markConservativeMFNbNlPvQcZvZQCfMFNbbZv ()
#6  0x0000000000453f1d in 
_D2gc4impl12conservativeQw3Gcx11fullcollectMFNbbZm ()
#7  0x000000000045732f in 
_D2gc4impl12conservativeQw14ConservativeGC__T9runLockedS_DQCeQCeQCcQCnQBs11fullCollectMFNbZ2goFNbPSQDtQDtQDrQEc3GcxZmTQvZQCyMFNbKQBgZm ()
#8  0x000000000045167d in 
_D2gc4impl12conservativeQw14ConservativeGC11fullCollectMFNbZm ()
#9  0x000000000045165e in 
_D2gc4impl12conservativeQw14ConservativeGC7collectMFNbZv ()
#10 0x000000000042f2bd in gc_collect ()
#11 0x000000000042ca11 in core.memory.GC.collect() ()
#12 0x000000000042c8a6 in entry_point2 (_param_0=0x0) at 
worker.d:36
#13 0x000000000042c62e in threadFun (arg=0x42c864 <entry_point2>) 
at main.d:24
#14 0x00007ffff7f6e58e in start_thread () from 
/usr/lib64/libpthread.so.0
#15 0x00007ffff7cee6a3 in clone () from /usr/lib64/libc.so.6

```

I've tried to compile phobos with debug symbols and ended up with 
this:

```D
Thread 3 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7aeb700 (LWP 11470)]
0x000000000043d7e3 in invariant._d_invariant(Object) 
(o=0x7ffff6eeb000) at src/rt/invariant.d:27
27	    c = typeid(o);
(gdb) bt
#0  0x000000000043d7e3 in invariant._d_invariant(Object) 
(o=0x7ffff6eeb000) at src/rt/invariant.d:27
#1  0x000000000043927a in 
_D4core6thread6Thread6removeFNbNiCQBgQBeQBaZv (t=0x7ffff6eeb000) 
at src/core/thread.d:1864
#2  0x000000000043947b in thread_detachThis () at 
src/core/thread.d:2263
#3  0x00000000004378b0 in entry_point2 (_param_0=0x0) at 
worker.d:39
#4  0x000000000043762e in threadFun (arg=0x437864 <entry_point2>) 
at main.d:24
#5  0x00007ffff7f6e58e in start_thread () from 
/usr/lib64/libpthread.so.0
#6  0x00007ffff7cee6a3 in clone () from /usr/lib64/libc.so.6
```

So actually after manual GC.collect call in test method which is 
really strange.

I've tested this with dmd-2.085.0 because of this fix: 
https://github.com/dlang/druntime/commit/f60eb358ccbc14a1a5fc1774eab505ed0132e999 which seemed to be exactly what is needed for this to work.

I've even created a github repo with my tests using 4 variations:

* static lib from D
* dynamic lib from D
* static lib from C
* dynamic lib from D

all using pthread as a foreign thread on linux.

You can see it here: https://github.com/tchaloupka/dlangsharedlib

All tests fails with the same result.
C tests only differs in that they explicitly calls `rt_init()` to 
initialize DRuntime. Should be the same otherwise.

I wonder where is the problem.
Is GC supposed to work with foreign threads when registered?


More information about the Digitalmars-d-learn mailing list