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