Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustup installs incorrect version when 64 bit kernel enabled in 32bit OS. #3307

Closed
Robtom5 opened this issue Apr 3, 2023 · 13 comments · Fixed by #3490
Closed

rustup installs incorrect version when 64 bit kernel enabled in 32bit OS. #3307

Robtom5 opened this issue Apr 3, 2023 · 13 comments · Fixed by #3490
Labels

Comments

@Robtom5
Copy link

Robtom5 commented Apr 3, 2023

Problem

When attempting to install Rust in a 32-bit environment with a 64 kernel the wrong version is installed. This is due to rustup determining 64/32 bit from what is available, not what is being used

Steps

  1. Install fresh 32-bit Raspberry Pi OS image
  2. Enable the 64-bit kernel (set arm_64bit=1 in /boot/config.txt)
  3. Restart
  4. Follow rust installation instructions
  5. Rust installed is 64-bit despite user running in a 32-bit environment (rust wont run)

Possible Solution(s)

getconf LONG_BIT is a better solution than uname -m for determining whether the user is operating in 64 bit or 32 bit (which is more in line with user specific installation)

Notes

Execution of rustc after running rustup:

robtom@robtom-pi:~ $ rustc --version
error: command failed: 'rustc': No such file or directory (os error 2)

Rustup version

rustup 1.25.2 (17db695f1 2023-02-01)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `(error reading rustc version)`

Installed toolchains

Default host: aarch64-unknown-linux-gnu
rustup home:  /home/control/.rustup

stable-aarch64-unknown-linux-gnu (default)
(error reading rustc version)
@Robtom5 Robtom5 added the bug label Apr 3, 2023
@Robtom5
Copy link
Author

Robtom5 commented Apr 3, 2023

Another acceptable solution in this case could be to fail to autopopulate the host triple and force the user to manually set it

@rbtcollins
Copy link
Contributor

What does file `which rustup` report?

I want to determine if the wrong rustup binary is installed, or the wrong toolchain (or both).

@Robtom5
Copy link
Author

Robtom5 commented Apr 11, 2023

rustup@rustup:~ $ file `which rustup`
/home/rustup/.cargo/bin/rustup: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.101, with debug_info, not stripped

@MichaIng
Copy link

We recognised the same:

  • rustup-init.sh correctly detects and handles the case with 64-bit kernel but 32-bit userland and installs all binaries (rustup, cargo, rustc, ...) as 32-bit:
    root@OdroidN2:~# file .cargo/bin/* | mawk '{print $1,$3}'
    .cargo/bin/cargo: 32-bit
    .cargo/bin/cargo-clippy: 32-bit
    .cargo/bin/cargo-fmt: 32-bit
    .cargo/bin/cargo-miri: 32-bit
    .cargo/bin/clippy-driver: 32-bit
    .cargo/bin/rls: 32-bit
    .cargo/bin/rust-gdb: 32-bit
    .cargo/bin/rust-gdbgui: 32-bit
    .cargo/bin/rust-lldb: 32-bit
    .cargo/bin/rustc: 32-bit
    .cargo/bin/rustdoc: 32-bit
    .cargo/bin/rustfmt: 32-bit
    .cargo/bin/rustup: 32-bit
  • rustup itself however selects the aarch64 host triple, which naturally causes failures if no headers for cross-compiling were intentionally installed.

The rustup installer uses this function to check for 32-bit userland when 64-bit CPU arch is detected, which obviously works fine. Probably this can be used as starting point for doing the same in rustup itself:

get_bitness() {
    need_cmd head
    # Architecture detection without dependencies beyond coreutils.
    # ELF files start out "\x7fELF", and the following byte is
    #   0x01 for 32-bit and
    #   0x02 for 64-bit.
    # The printf builtin on some shells like dash only supports octal
    # escape sequences, so we use those.
    local _current_exe_head
    _current_exe_head=$(head -c 5 /proc/self/exe )
    if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
        echo 32
    elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
        echo 64
    else
        err "unknown platform bitness"
    fi
}

@rami3l
Copy link
Member

rami3l commented Sep 23, 2023

Triage Report 1

Related issues

#2498 #2565 #3431 #3342 #3471 #3487 2

Possible cause

https://forums.raspberrypi.com/viewtopic.php?t=289963#p1756063 says:

although the Pi was running a 32 bit user land the kernel identified as 64 bit, which confused the Rust installer.

#2565 (comment) says:

The output of ldd rustc suggests you don't - and in fact despite having an aarch64 CPU you're running an armhf userland which is something we weren't expecting.

So I suspect that rustup wants to install aarch64-unknown-linux-gnu (or similar) because it has detected a 64-bit Linux (which is correct).
However, your PiOS user land is 32-bit, so only something like arm-unknown-linux-gnueabihf will work.

Possible solution

We could choose to do one (or many) of the following:

Footnotes

  1. Moved here from https://github.com/rust-lang/rustup/issues/3471#issuecomment-1703993191

  2. Would you mind to mark those issues as duplicate and close them (if applicable), @rbtcollins? Thanks a lot!

@alex
Copy link
Member

alex commented Sep 23, 2023

The proximate cause is here: https://github.com/rust-lang/rustup/blob/master/src/dist/dist.rs#L323-L361

rustup consults uname, which will return aarch64 on a 64-bit kernel with a 32-bit userspace.

I think the best choice is to automatically handle this case and set a 32-bit default-target for the installed rustc.

However, I'm not positive what the correct way to detect this situation is. One choice is simply checking: is the running rustup a 32-bit process? If so, select a 32-bit target.

Are there cases where that's not correct (i.e., where we'd be running a 32-bit rustup on a 64-bit kernel, but want a rustc which is 64-bit by default)?

I'm happy to develop a PR for either this approach, or any other approach folks can think of.

@rami3l
Copy link
Member

rami3l commented Sep 23, 2023

I think the best choice is to automatically handle this case and set a 32-bit default-target for the installed rustc.

However, I'm not positive what the correct way to detect this situation is.

@alex Exactly. After triaging all those issues it does seem to me that the _current_exe_head approach in #3307 (comment) is the most reasonable solution to me so far (although indeed we should also care about other platforms, but this should be a good starting point). Also, it should not be that hard to translate that part into Rust.

If you would like to make a PR to address this issue, please do! I'll try my best to review it in that case :)

@alex
Copy link
Member

alex commented Sep 23, 2023

👍, my only hesitation is that https://github.com/rust-lang/rustup/blob/master/src/dist/dist.rs#L373 seems to deliberately prefer the host target to the build target, and this would invert that (for this situation).

If it sounds good to you, I'll send a PR for it tomorrow!

@rami3l
Copy link
Member

rami3l commented Sep 23, 2023

👍, my only hesitation is that https://github.com/rust-lang/rustup/blob/master/src/dist/dist.rs#L373 seems to deliberately prefer the host target to the build target, and this would invert that (for this situation).

@alex I'm not sure if we are on the same page here, but I believe that inspecting the head of /proc/self/exe should be able to help us guess the bitness of the whole userland (which should be part of the host target that you'd expect, and it's exactly what we need to change here). The build target seems to be less relevant anyway in this case.

alex added a commit to alex/rustup that referenced this issue Sep 23, 2023
…hain

this mirrors a similar check that exists in rustup-init.sh

fixes rust-lang#3307
alex added a commit to alex/rustup that referenced this issue Sep 24, 2023
…hain

this mirrors a similar check that exists in rustup-init.sh

fixes rust-lang#3307
alex added a commit to alex/rustup that referenced this issue Oct 5, 2023
…hain

this mirrors a similar check that exists in rustup-init.sh

fixes rust-lang#3307
alex added a commit to alex/rustup that referenced this issue Oct 5, 2023
…hain

this mirrors a similar check that exists in rustup-init.sh

fixes rust-lang#3307
@rami3l rami3l closed this as completed in 745473d Oct 5, 2023
@rochdev
Copy link

rochdev commented Mar 2, 2024

I'm still getting this same issue when using rustup in an armv7 Docker container on an aarch64 host.

@djc
Copy link
Contributor

djc commented Mar 4, 2024

What version did you try with? Did you try the beta?

https://internals.rust-lang.org/t/seeking-beta-testers-for-rustup-1-27-0/20352/7

@rami3l
Copy link
Member

rami3l commented Mar 4, 2024

@djc I guess @rochdev wasn't on a chimera system (like Pi OS), has downloaded a working rustup binary, but encountered #3122 instead during the installation phase which is a different issue from this one. (Please feel free to correct me if I'm wrong, @rochdev.)

@rochdev
Copy link

rochdev commented Mar 4, 2024

What version did you try with? Did you try the beta?

@djc It looks like it works properly with the beta. Thanks!

@djc I guess @rochdev wasn't on a chimera system (like Pi OS), has downloaded a working rustup binary, but encountered #3122 instead during the installation phase which is a different issue from this one. (Please feel free to correct me if I'm wrong, @rochdev.)

@rami3l I do have a separate issue where the installation just hangs, but the architecture was also not detected properly, so I had to force the target explicitly. It looks like the detection issue is now resolved in the beta.

@djc djc closed this as not planned Won't fix, can't repro, duplicate, stale Mar 4, 2024
@djc djc closed this as completed Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants