Bug 20248 – Module constructors in executable called twice, never in loaded shared library

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2019-09-27T09:38:47Z
Last change time
2024-12-13T19:05:43Z
Keywords
backend, industry, wrong-code
Assigned to
No Owner
Creator
John Colvin
Moved to GitHub: dmd#19624 →

Comments

Comment #0 by john.loughran.colvin — 2019-09-27T09:38:47Z
% 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\n", &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
Comment #1 by kinke — 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.
Comment #2 by kinke — 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.
Comment #3 by kinke — 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.
Comment #4 by robert.schadek — 2024-12-13T19:05:43Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19624 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB