Executables with shared libraries fail to run with err "no such file or directory"

On my system, I had it installed as a dependency for steam, that’s why the program was running normally for me.

$ nix why-depends /run/current-system nixpkgs#glibc_multi
/nix/store/4a4lz5fj7s31wc5giw6g72cis03qjhvi-nixos-system-nixos-24.05.20240509.f1010e0
└───/nix/store/lix00h8v7jl9fv5aavl9ykfxz6lagwx9-system-path
    └───/nix/store/4slxy5jsmypyi30rr5lzh6ja94kk53qz-steam-run
        └───/nix/store/v0lwlgnb1jc4mdlzzyh77zszakkyf8q7-steam-run-bwrap
            └───/nix/store/8zl8x3ijicd3shdc4lydzc5l80xlfjw4-steam-run-fhs
                └───/nix/store/5ddanrp2i7g7fvpbpzk6s93ah4vg7ycz-steam-run-usr-target
                    └───/nix/store/v6ayhasssr0wj8906zihf6lc1dnsx9ag-glibc-multi-2.39-31-bin

It would be nice if we could somehow run inside a shell/environment where no libraries are loaded by default from the system, but turns out it’s not hard to debug the libraries the program needs once you get the hang of it.

Congrats, anyways :tada:

1 Like

While I’m glad it’s working,

I’m still not sure why it wasn’t working.

e.g. those libs are already in glibc:

ls /nix/store/apab5i73dqa09wx0q27b6fbhd1r18ihl-glibc-2.39-31/lib/ | grep 'lib\(pthread\|resolv\|c\)'

and upthread, ldd seemed to be able to find them:

I notice the dynamic linker ld-linux-x86-64.so.2 resolves to a different path for some reason /nix/store/35pq4hr29c3sl79lgfwgsvd9nwzyp4am-glibc-2.39-5/lib/ld-linux-x86-64.so.2 => /nix/store/apab5i73dqa09wx0q27b6fbhd1r18ihl-glibc-2.39-31/lib64/ld-linux-x86-64.so.2.

Sure, setting LD_LIBRARY_PATH results in a core dump, but that wasn’t the observed error. Using patch-elf --set-interpreter with this /nix/store/35pq....p4am-glib-2.39-5/ didn’t result in the same error, either.

The same thing happened in:

So there is definitely something wrong there. Both programs deal with a "net/http" server so I wonder how that relates.

That’s true. I couldn’t reproduce the error with this either, but perhaps this is not the main cause, but an rather an effect.

Here is my take on why it wasn’t working based on these two threads:

  • wrong version of glibc gets picked as an interpreter
  • this version doesn’t exist (anymore? after gc?) on the machaine
  • user tries to run the binary, but interpreter is not found
  • no such file or directory error

How to reproduce?

  • $ nix run nixpkgs#patchelf – --set-interpreter “/hello/world” ./main
  • $ ./main
  • $ zsh: no such file or directory: ./main
  • now, replace “/hello/world” with a glibc that no longer exists and you’ll have the same issue

Solutions?

  • re-install the system → correct linker gets picked
  • install another glibc → its linker gets picked? fixes the first issue? :person_shrugging: