Thread overview
shared static this not invoked on almalinux 8.5, all is well on fedora 35
Jun 09, 2022
ichneumwn
Jun 09, 2022
kinke
Jun 09, 2022
ichneumwn
Jun 09, 2022
kinke
Jun 10, 2022
kinke
Jun 13, 2022
ichneumwn
Jun 13, 2022
ichneumwn
Jun 13, 2022
ichneumwn
June 09, 2022

Dear forum,

I am using ldc,
version 1.28.0-git-5a28329 (DMD v2.098.0, LLVM 10.0.0)
on two different systems:

  1. Almalinux 8.5
  2. Fedora 35

ldc itself was compiled on the Almalinux system and then copied over to the Fedora 35 system

I confirmed it is the same ldc executable on both systems by running

md5sum `which ldc2`

I have a simple test case where it seems on the Almalinux system, shared static this() code does not get invoked.

Output on Almalinux:

    dsostub : crt_constructor

Output on Fedora:

    dsostub : crt_constructor
    md_static_import : shared static this
    main : shared static this

The code is built using meson, and using meson compile --verbose I can see that the compilation steps are the same, and the linking step looks like this and is identical on both systems:

    /usr/bin/cc mwe.p/dsostub.d.o mwe.p/md_static_import.d.o mwe.p/main.d.o -o mwe -Xlinker --allow-shlib-undefined -L/opt/ldc2-1.28.0/lib -lphobos2-ldc-shared -ldruntime-ldc-shared -Wl,-rpath,/opt/ldc2-1.28.0/lib -Wl,--gc-sections -lrt -ldl -lpthread -lm -m64

If I copy over the build directory from the almalinux system to the fedora system and re-execute the link command as above, the resulting executable does work.

  1. /usr/bin/cc --version on almalinux : cc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4)
  2. /usr/bin/cc --version on fedora : cc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)

So it seems there is a difference in how gcc 8.5.0 and gcc 11.2.1 handle something in the linking process, but I assume it requires knowledge of ldc to know what that might be, which is why I am posting here.

The code can be gotten from here: github. It was originally also using using static and dynamic libraries which is why I have the dsostub code that uses pragma(crt_constructor) which is not actually relevant here.

I am hoping there might be a linker option that I can pass to the older gcc that would resolve the issue?

June 09, 2022

On Thursday, 9 June 2022 at 08:54:51 UTC, ichneumwn wrote:

>

So it seems there is a difference in how gcc 8.5.0 and gcc 11.2.1 handle something in the linking process, but I assume it requires knowledge of ldc to know what that might be, which is why I am posting here.

gcc probably doesn't matter, but the actual linker does. v1.28 still defaults to ld.gold, so that seems problematic for almalinux. - Anyway, DSO registration was revamped in v1.29, and it's now using the default linker (can choose with -linker option), so I'd recommend checking whether the problem still persists with v1.29.

June 09, 2022

On Thursday, 9 June 2022 at 11:19:48 UTC, kinke wrote:

>

On Thursday, 9 June 2022 at 08:54:51 UTC, ichneumwn wrote:

>

So it seems there is a difference in how gcc 8.5.0 and gcc 11.2.1 handle something in the linking process, but I assume it requires knowledge of ldc to know what that might be, which is why I am posting here.

gcc probably doesn't matter, but the actual linker does. v1.28 still defaults to ld.gold, so that seems problematic for almalinux. - Anyway, DSO registration was revamped in v1.29, and it's now using the default linker (can choose with -linker option), so I'd recommend checking whether the problem still persists with v1.29.

Thanks, that (the linker) solved it (I thought is was part of the gcc package). I just noticed meson tells me which linker is used. On AlmaLinux:

D compiler for the host machine: ldc2 (llvm 1.28.0-git "LDC - the LLVM D compiler (1.28.0-git-5a28329):")
D linker for the host machine: ldc2 ld.bfd 2.30-108

I downloaded and installed version 2.37 of binutils to match my Fedora system. Meson did not allow me to specify an absolute path to the linker, but putting it first in my PATH worked. With that the problems disappeared.

I very briefly tried v1.29 a little while ago, but my application compiled, started and then hung with 1.29. Haven't had time to isolate the problem area yet.

Would you have a pointer to information about "DSO registration" in ldc / D in general? Have only been able to piece together scraps of information so far, such as

pragma(crt_constructor)
// extern (C) routine here that starts the D runtime rt_init()
June 09, 2022

On Thursday, 9 June 2022 at 12:25:01 UTC, ichneumwn wrote:

>

Would you have a pointer to information about "DSO registration" in ldc / D in general?

For LDC, it's now almost entirely a druntime thing, the compiler just implicitly links in some prebuilt object file when linking an executable or shared lib against shared druntime. See https://github.com/ldc-developers/druntime/blob/ldc/src/rt/dso.d (and the mess of a sections_elf_shared.d).

June 10, 2022

On Thursday, 9 June 2022 at 08:54:51 UTC, ichneumwn wrote:

>

The code is built using meson, and using meson compile --verbose I can see that the compilation steps are the same, and the linking step looks like this and is identical on both systems:

    /usr/bin/cc mwe.p/dsostub.d.o mwe.p/md_static_import.d.o mwe.p/main.d.o -o mwe -Xlinker --allow-shlib-undefined -L/opt/ldc2-1.28.0/lib -lphobos2-ldc-shared -ldruntime-ldc-shared -Wl,-rpath,/opt/ldc2-1.28.0/lib -Wl,--gc-sections -lrt -ldl -lpthread -lm -m64

Ah, so meson seems to link manually, not via the D compiler, ignoring LDC's preference for linkers (so you most likely ended up using uber-slow ld.bfd instead of ld.gold) etc. It needs to be adapted for LDC v1.29 (to include the special prebuilt object file mentioned above that LDC would link in implicitly) if it hasn't been already - 'big news' #5 in https://github.com/ldc-developers/ldc/releases/tag/v1.29.0.

June 13, 2022

On Friday, 10 June 2022 at 11:48:37 UTC, kinke wrote:

>

Ah, so meson seems to link manually, not via the D compiler, ignoring LDC's preference for linkers (so you most likely ended up using uber-slow ld.bfd instead of ld.gold) etc. It needs to be adapted for LDC v1.29 (to include the special prebuilt object file mentioned above that LDC would link in implicitly) if it hasn't been already - 'big news' #5 in https://github.com/ldc-developers/ldc/releases/tag/v1.29.0.

I see, that probably explains the "hanging" when I use 1.29.0. meson is mostly pleasant to use, but it is rather opaque and it is often unclear how to influence what it decides to do (part of that could be inexperience)

June 13, 2022

On Monday, 13 June 2022 at 13:37:41 UTC, ichneumwn wrote:

>

On Friday, 10 June 2022 at 11:48:37 UTC, kinke wrote:

>

Ah, so meson seems to link manually, not via the D compiler, ignoring LDC's preference for linkers (so you most likely ended up using uber-slow ld.bfd instead of ld.gold) etc. It needs to be adapted for LDC v1.29 (to include the special prebuilt object file mentioned above that LDC would link in implicitly) if it hasn't been already - 'big news' #5 in https://github.com/ldc-developers/ldc/releases/tag/v1.29.0.

I see, that probably explains the "hanging" when I use 1.29.0. meson is mostly pleasant to use, but it is rather opaque and it is often unclear how to influence what it decides to do (part of that could be inexperience)

Hang on, I am talking rubbish. This is the chain of events:

meson compile --version told me:

ldc2 -of=mwe mwe.p/dsostub.d.o mwe.p/md_static_import.d.o mwe.p/main.d.o -L=--allow-shlib-undefined -link-defaultlib-shared

I added a "-v" to this and reexecuted this manually. This told me that the following gets executed:

/bin/cc mwe.p/dsostub.d.o mwe.p/md_static_import.d.o mwe.p/main.d.o -o mwe -Xlinker --allow-shlib-undefined -L/opt/ldc2-1.28.0/lib -lphobos2-ldc-shared -ldruntime-ldc-shared -Wl,-rpath,/opt/ldc2-1.28.0/lib -Wl,--gc-sections -lrt -ldl -lpthread -lm -m64

And that seems to invoke /bin/ld which through /etc/alternatives/ld links to /usr/bin/ld.bfd. So that seems how I end up with ld.bfd... Meson not to blame, apologies to meson :). I might be able to get meson to pass -fuse-ld=ld.gold or lld through ldc2 to /bin/cc.

June 13, 2022

On Monday, 13 June 2022 at 14:14:43 UTC, ichneumwn wrote:

>

And that seems to invoke /bin/ld which through /etc/alternatives/ld links to /usr/bin/ld.bfd. So that seems how I end up with ld.bfd... Meson not to blame, apologies to meson :). I might be able to get meson to pass -fuse-ld=ld.gold or lld through ldc2 to /bin/cc.

This gives some interesting behaviour with ldc-1.29.0 on AlmaLinux:

I can see ldc now pass ldc_rt.dso.o to /usr/bin/cc. The effect is, With the old ld.bdf (2.30), that the shared static this in md_static_import.d does get invoked, but not the one in main.d !? In any case, all is well with the newer ld.bdf as before.