Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module constructors in executable called twice, never in loaded shared library #19624

Open
dlangBugzillaToGithub opened this issue Sep 27, 2019 · 3 comments

Comments

@dlangBugzillaToGithub
Copy link

John Colvin (@John-Colvin) reported this on 2019-09-27T09:38:47Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=20248

CC List

  • kinke

Description

% cat modcon.d
import modcon2;
void main()
{
        import core.runtime : Runtime;
        import core.sys.posix.dlfcn;
        import std.stdio;
        writeln("HI");
        assert(Runtime.loadLibrary("./libmodcon2.so"));
}
% cat modcon2.d
__gshared int a;
shared static this() { foo(); }
void foo()
{
        import core.stdc.stdio;
        printf("%p ", &a);
        printf("%p
", &foo);
}

% dmd -shared modcon2.d -of=libmodcon2.so
% dmd -defaultlib=libphobos2.so modcon.d modcon2.d
% ./modcon
0x7f920f3a2140 0x7f920f39f930
HI
0x7f920f3a2140 0x7f920f39f930


As you can see from the printed pointers, the module constructor from the executable is called twice - once on process start and once on loading the shared library - and the module constructor from the shared library is never called.

Module constructors are normally designed to be called only once, so this causes some havok
@dlangBugzillaToGithub
Copy link
Author

kinke commented on 2021-07-05T07:55:06Z

This 'works' with LDC v1.27 (but DMD v2.097 still fails):

0x55debef38074 0x55debef34090
HI
0x7fdfb6c12064 0x7fdfb6c10870

I think this is more likely related to compiler differences wrt. relocation model, not a druntime divergence.

@dlangBugzillaToGithub
Copy link
Author

kinke commented on 2021-07-29T16:11:06Z

Further tests have shown that with DMD, the ModuleInfos of modules contained in both executable and library are apparently resolved to the executable's.

E.g., versioning out the module ctor in `modcon2.d` for the library still leads to it being invoked when loading the library; the opposite case, versioning it out for the executable, means it's not invoked at all.

@dlangBugzillaToGithub
Copy link
Author

kinke commented on 2021-07-29T16:36:54Z

There's a related issue regarding CRT ctors - if both executable and library contain an identically mangled `pragma(crt_constructor)` function (doesn't even need to be in the same module - and name collision is quite likely due to the `extern(C)` requirement...), the executable one is invoked twice. Again DMD-specific, works with LDC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant