rust-analyzer: rust-analyzer fails to load proc-macros when loaded through ld.so

This is a somewhat niche problem, but I figured there should at least be a public record of it.

If rust-analyzer is executed through ld.so, it fails to load the shared library for proc-macros:

proc-macro: error while loading shared libraries: proc-macro: cannot open shared object file

You can reproduce this with:

cargo new --lib ra-ldso
cd ra-ldso
/lib/"ld-linux-$(uname -m).so.1" "$(which rust-analyzer)" analysis-stats .

Note that it’s not even necessary to actually pass --library-path — invoking through ld.so is sufficient.

Loading through ld.so is primarily useful because it allows setting the shared library search path without setting LD_LIBRARY_PATH. This, in turn, is useful because LD_LIBRARY_PATH is “viral” — it also affects the search path for child processes, whereas ld.so --library-path does not. It’s important to use a non-viral mechanism in nix-style applications where each program lives in its own runtime environment, and you want a way to set the runtime environment for a given binary, but not for any binaries that it may in turn execute, since those may themselves have their won runtime environments.

Based purely on a guess, I suspect this is related to the solution implemented through https://github.com/rust-lang/rust-analyzer/issues/12803, but hard to say for sure. Alternatively, it might be related to how rust-analyzer locates its own binary to execute the proc-macro-srv — if it uses argv0, then it’ll now find ld.so rather than the true rust-analyzer!

rust-analyzer version: rust-analyzer 0.0.0 (ab068f120 2022-08-31)

rustc version: rustc 1.63.0 (4b91a6ea7 2022-08-08)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 25 (25 by maintainers)

Most upvoted comments

That is odd, if r-a tries to use the server in the rust sysroot it shouldn’t be passing any arguments at all… So I guess it’s not finding the sysroot here for some reason … Well I guess I’ll look into the fixing the path config, that way you can test this by specifying a path for the server directly instead of it falling back to the current exe

Same thing happens with most recent nightly (set through a rustup override for the current directory):

$ rustc -V
rustc 1.65.0-nightly (9243168fa 2022-08-31)
$ sh -c "exec -a $(which rust-analyzer) /lib/ld-linux-aarch64.so.1 $(which rust-analyzer) analysis-stats ."
...
proc-macro: error while loading shared libraries: proc-macro: cannot open shared object file

Oh right, analysis-stats is not running the server. Ye so I think your assumption might be right, analysis-stats is always running the “current exe” with proc-macro as the arg unlike the server that now uses the sysroot if possible

https://github.com/rust-lang/rust-analyzer/blob/643c3a54de9da45f07ba9282c2ec7917d9ee7225/crates/rust-analyzer/src/cli/load_cargo.rs#L60-L66

Though https://github.com/rust-lang/rust-analyzer/issues/12803 is unrelated to that as this was already the behavior prior to that