Skip to content

x86_64-unknown-linux-musl target and main-returning-Result produces a dynamically-linked executable instead of a statically linked one. #54243

Closed

Description

@luqmana

I've run into this weird interaction between the musl target, diesel, returning Result from main and debug vs release mode.

The setup:

Cargo.toml:

[package]
name = "main-musl-bug"
version = "0.1.0"

[dependencies]
diesel = { version = "1.3", features = ["sqlite"] }

main.rs:

extern crate diesel;

fn main() -> Result<(), std::io::Error> {
    println!("Hello, world!");
    Ok(())
}

Now if we take this simple innocuous looking program and try to run it:

➜  cargo run --target x86_64-unknown-linux-musl 
   Compiling main-musl-bug v0.1.0 (/home/luqman/Develop/tmp/main-musl-bug)                                                 
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s                                                              
     Running `target/x86_64-unknown-linux-musl/debug/main-musl-bug`
error: could not execute process `target/x86_64-unknown-linux-musl/debug/main-musl-bug` (never executed)

Caused by:
  No such file or directory (os error 2)

Well, the file is definitely there but running file gives this:

➜  file ./target/x86_64-unknown-linux-musl/debug/main-musl-bug
./target/x86_64-unknown-linux-musl/debug/main-musl-bug: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld64.so.1, BuildID[sha1]=c43d7e9e32151f6240e2e93e744c3bda8e2e179f, with debug_info, not stripped

That's odd, I would've expected a statically linked binary but file disagrees here. The no such file or directory error I'm guessing results from the bogus program interpreter in the elf header:

➜  readelf -a ./target/x86_64-unknown-linux-musl/debug/main-musl-bug
[...]
      [Requesting program interpreter: /lib/ld64.so.1]
[...]

That path doesn't exist on my machine.

Now, the weird thing is a couple different things workaround the issue:

  1. build/run with --release OR
  2. use a plain old fn main() { ... } function.

rustc/cargo version:

➜  ~ rustc -V
rustc 1.29.0 (aa3ca1994 2018-09-11)
➜  ~ cargo -V
cargo 1.29.0 (524a578d7 2018-08-05)

EDIT: Repros on stable.

Activity

  1. bossmc commented on Sep 19, 2018

    @bossmc
    Contributor

    Is this repros on nightly you can add rustflags = ["-Z", "print-link-args"] to the [build] section of your .cargo/config file (see https://doc.rust-lang.org/cargo/reference/config.html) to see the actual link command used which should help analyse this issue.

  2. bossmc commented on Sep 21, 2018

    @bossmc
    Contributor

    I think there's various things going on here:

    1. I guess you're linking with gcc and are thus linking to the system-wide libsqlite3.so (dynamically) - this leads to your issue, but it's never going to work anyway
      • The reason --release made this appear to work is that the dynamic link was optimized out (as it's not used anywhere)
      • I'm guessing something similar occurs with non-Result main the linker can more easily see that the dynamic library is unneeded
    2. Changing the linker to musl-gcc leads to -lsqlite3: Not found errors (as expected - musl-gcc sets library lookup paths to a special place to prevent cross-contamination)
    3. Adding libsqlite3-sys = { version = "0.9.3", features = ["bundled"] } as a dependency causes a local (static/musl) version to be compiled and linked in and the world to work once more. Probably diesel should add that feature when compiling for x86_64-unknown-linux-musl....?
  3. luqmana commented on Sep 22, 2018

    @luqmana
    ContributorAuthor

    @bossmc Hmm, I'm pretty sure it's already using musl-gcc (since I forgot to install it earlier and it complained).

    And yea, just working around it now by using the bundled version for now.

  4. bossmc commented on Sep 22, 2018

    @bossmc
    Contributor

    Can you run the print-link-args test and paste the output?

  5. luqmana commented on Sep 22, 2018

    @luqmana
    ContributorAuthor

    Ah ok, you were right, it was indeed just invoking cc. I only got the error when I was trying the bundled sqlite feature.

    A bit unfortunate but the bundled feature does actually map to more what I want.

    Thanks @bossmc

  6. added a commit that references this issue on Nov 10, 2018
    8912b0e
  7. added 2 commits that reference this issue on Dec 29, 2018
    1d5cbcb
    4e6debd
  8. added a commit that references this issue on Mar 18, 2019
    f952c61
  9. added a commit that references this issue on Apr 2, 2019
    2d60183
  10. added 2 commits that reference this issue on May 21, 2019
    859624e
    7f7ea1c
  11. added a commit that references this issue on Sep 3, 2019
    10bd267
  12. added a commit that references this issue on Nov 5, 2019
    7e10afd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-muslTarget: The musl libc

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions