Thread overview
[Issue 24590] Illegal instruction with module constructors cycle and shared libphobos2 in _d_criticalenter2
Jun 09, 2024
kinke
Jun 11, 2024
Dlang Bot
Jun 12, 2024
Dlang Bot
June 09, 2024
https://issues.dlang.org/show_bug.cgi?id=24590

--- Comment #1 from Andrei Horodniceanu <a.horodniceanu@proton.me> ---
> The code above fails with both dmd and ldc2 but not with gdc.

My bad, I forgot to pass `-shared-libphobos` when building with gdc. With the flag disabled I get:
----
object.Error@/var/tmp/portage/sys-devel/gcc-14.1.1_p20240518/work/gcc-14-20240518/libphobos/libdruntime/rt/minfo.d(372):
Cyclic dependency between module constructors/destructors of b and a
b* ->
a* ->
b*

----
And when passing the flag I get:
----
object.Error@/var/tmp/portage/sys-devel/gcc-14.1.1_p20240518/work/gcc-14-20240518/libphobos/libdruntime/rt/minfo.d(372):
Cyclic dependency between module constructors/destructors of b and a
b* ->
a* ->
b*

----------------
??:? _d_createTrace [0x7fafb9cfe3fb]
??:? _d_throw [0x7fafb9cf23b4]
??:? ???[0x7fafb9d02c08]
??:? ???[0x7fafb9d02b7d]
??:? ???[0x7fafb9d02d87]
??:? nothrow void rt.minfo.ModuleGroup.sortCtors(immutable(char)[])
[0x7fafb9d04317]
??:? ???[0x7fafb9d04427]
??:? int gcc.sections.elf.DSO.opApply(scope int delegate(ref
gcc.sections.elf.DSO)) [0x7fafb9cf321a]
??:? rt_init [0x7fafb9cfe84a]
??:? ???[0x7fafb9cfe9ef]
??:? _d_run_main2 [0x7fafb9cfed1b]
??:? _d_run_main [0x7fafb9cfeefc]
/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/d/core/internal/entrypoint.d:29
main [0x560cd1844306]
??:? ???[0x7fafb96592df]
??:? __libc_start_main [0x7fafb9659398]
??:? _start [0x560cd1844094]
??:? ???[0xffffffffffffffff]
----

Which is an improvement since it's not a crash.

--
June 09, 2024
https://issues.dlang.org/show_bug.cgi?id=24590

kinke <kinke@gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kinke@gmx.net

--- Comment #2 from kinke <kinke@gmx.net> ---
AFAICT, this happens because at program termination, each binary unregisters
itself via a CRT destructor, incl. running the module dtors of that binary if
druntime had been initialized via `rt_init()`. For libphobos2.so, this includes
the `rt.trace` module dtor (whereas static druntime probably doesn't unless
using tracing functionality), which uses an anonymous mutex, which depends on
an initialized druntime (`_d_critical_init()` without `_d_critical_term()`).

But `rt_init()` already cleans up via `_d_critical_term()` if initialization failed, e.g., due to module cycles here. AFAICT, the problem is `rt.sections_elf_shared._isRuntimeInitialized`, which is set once during the `initSections()` call, but would need to be unset if module ctors later throw. We should probably get rid of that variable and use `rt.dmain2._initCount` instead.

This also crashes with `-defaultlib=libphobos2.so` only:
```
shared static this() {
    throw new Exception("oops");
}

void main() {}
```

--
June 11, 2024
https://issues.dlang.org/show_bug.cgi?id=24590

--- Comment #3 from Dlang Bot <dlang-bot@dlang.rocks> ---
@kinke created dlang/dmd pull request #16578 "Fix Bugzilla 24590 - Don't run module destructors if druntime failed to initialize" mentioning this issue:

- Add test case for Bugzilla 24590

https://github.com/dlang/dmd/pull/16578

--
June 12, 2024
https://issues.dlang.org/show_bug.cgi?id=24590

Dlang Bot <dlang-bot@dlang.rocks> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #4 from Dlang Bot <dlang-bot@dlang.rocks> ---
dlang/dmd pull request #16578 "Fix Bugzilla 24590 - Don't run module destructors if druntime failed to initialize" was merged into master:

- 83b62e9633dbe8b789065cec7a7253cf8480e5e2 by Martin Kinkelin:
  Add test case for Bugzilla 24590

- 6f20e8f9da84c9498a3c865734b14bbae6d5213a by Martin Kinkelin:
  Fix Bugzilla 24590 - Don't run module destructors if druntime failed to
initialize

https://github.com/dlang/dmd/pull/16578

--