www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'shared static this' of loaded D library not called

I need your help even after reading the documentation[1] and some of 
druntime source code.

This is all on Linux (Ubuntu).

I have a D shared library (let's call it libparent.so) that dynamically 
and conditionally loads other D shared libraries (let's call one of them 
libchild.so).

The parent library is supposed to be used by D, C++, and Python 
programs; so it defines a 'pragma(crt_constructor)'[2] function which 
calls rt_init() to initialize the D runtime.

The parent library calls Runtime.loadLibrary() to load libchild.so. What 
is important here is that the 'shared static this' section of the child 
gets called and everybody is happy in most of our use cases:

- D runtime is initialized by the parent

- The 'shared static this' of the child is called upon loadLibrary

Unfortunately, things break when the parent library is loaded from a 
distance. :) In this case, the parent library is *not* linked with the 
program or loaded by it directly:

1) A Python program that loads

2) a Python module that loads

3) a SIP Python extension module (mylib_sip.so, which is generated C 
code from SIP (I learned that SIP is a QT thing)) that links with

4) a user library in C++ (mylib.so) that loads

5) our libparent.so mentioned above.

THE PROBLEM:

- GOOD: The 'pragma(crt_constructor)' function of libparent.so gets called

- GOOD: Runtime.loadLibrary() for the child succeeds (dlsym works too)

- BAD: The 'shared static this' of libchild.so is not called

(Note: Others have reported that things work when children are loaded in 
different orders. Hmmm... Could this be related? I've seen code in 
druntime about module ctor dependencies and their ordering before 
execution.)

Am I missing crucial steps or making wrong assumptions here?

Can you think of a workaround to force calling module ctors of child 
library? I tried dlsym'ing and calling two functions with names "init" 
in them but it did not run the 'shared static this' of the child either. 
(Minor complication: The module ctors do get called when linked in other 
use cases; so, my calling ctors explicitly would be extra in those 
cases, but luckily the ctors are idempotent.)

How about thread_attachThis? (I ask because everything works without 
thread_attachThis in other use cases even when we are loaded into 
another Python program! Oh... it must be because rt_init() gets called 
from the Python thread and rt_init already attaches this thread.) I 
tried this as well but there are so many dimensions that I may have 
missed the right combination that would work.

Thank you,
Ali

[1] https://dlang.org/articles/dll-linux.html

[2] https://dlang.org/spec/pragma.html#crtctor
Jan 21 2021