Reason for Cannot execute binary file

Posted by Napster on Tue, 18 Jan 2022 19:22:37 +0100

1. Write at the beginning

Question: the author uses kaniko to build a docker image, and the basic image is based on Alpine. After the build, run the compiled go binary. Always prompt the following error:

# ./example.exe
sh: ./example.exe: not found

Example is obvious here Exe file exists. It is suspected that sh has a problem. The author continues to try after following bash

# apk add bash
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz(1/4) Installing ncurses-terminfo-base (6.2_p20210109-r0)
(2/4) Installing ncurses-libs (6.2_p20210109-r0)(3/4) Installing readline (8.1.0-r0)
(4/4) Installing bash (5.1.0-r0)
Executing bash-5.1.0-r0.post-install
Executing busybox-1.32.1-r6.trigger
OK: 8 MiB in 18 packages
# bash
bash-5.1# /bin/bash example.exe
example.exe: example.exe: cannot execute binary file

At this point, the error becomes binary and cannot be executed. The author, unable to understand, can only harden his head to continue the investigation.

2. Troubleshooting direction

2.1 non root user

# whoami
root

Note: this option is excluded. The author logs in as root. If this is a non root user, you can execute chmod +x program

2.2 the compilation target is different from the execution environment

bash-5.1# file example.exeexample.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=r403apSf9gVnhAa92Ma3/CtPwwvYC_Td44-00QCD7/LNwlhyvp3IK5oGI_6pca/H9YPNEE1hvs-0EBN4ZA0, not stripped

bash-5.1# uname -a
Linux d015a01bdfbc 4.15.0-158-generic #166-Ubuntu SMP Fri Sep 17 19:37:52 UTC 2021 x86_64 Linux

Note: by comparing the file and uname commands, it is found that the compilation target of the program is the same as the execution environment. This option is excluded

2.3 the dynamic library or static library required by the program is missing

"Eliminate all the impossible, and the rest is the truth even if it is no longer possible."

bash-5.1# ldd example.exe
        /lib64/ld-linux-x86-64.so.2 (0x7ff2cb417000)        libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7ff2cb417000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7ff2cb417000)
Error relocating example.exe: __vfprintf_chk: symbol not found
Error relocating example.exe: __fprintf_chk: symbol not found
bash-5.1# ls /lib64
ls: /lib64: No such file or directory

Note: check the dependency Library of the program and find that there is a lack of dynamic dependency of lib64 locally. The reason is that Alpine uses a standard library that is different from most distributions musl libc , although this library is smaller, simpler and more secure than glibc, it is not compatible with the commonly used standard glibc.

2.3.1 solutions

The recommended solution for Wikipedia is to install glic as a supplement to musl libc.

Note: original text

If you want to run glibc programs in Alpine Linux, there are a few ways of doing so. You could install glibc as additional to musl (you would have to do this manually), or you could do it the easy way and use either Flatpak (the easiest) or a chroot.

Because there are different use cases, this is just a slight overview about what's possible and what's intelligent.

Install build base gcompat

bash-5.1# apk add build-base gcompat(1/22) Upgrading musl (1.2.2-r0 -> 1.2.2-r1)
(2/22) Installing libgcc (10.2.1_pre1-r3)(3/22) Installing libstdc++ (10.2.1_pre1-r3)
(4/22) Installing binutils (2.35.2-r1)(5/22) Installing libgomp (10.2.1_pre1-r3)
(6/22) Installing libatomic (10.2.1_pre1-r3)(7/22) Installing libgphobos (10.2.1_pre1-r3)
(8/22) Installing gmp (6.2.1-r0)
(9/22) Installing isl22 (0.22-r0)
(10/22) Installing mpfr4 (4.1.0-r0)
(11/22) Installing mpc1 (1.2.0-r0)
(12/22) Installing gcc (10.2.1_pre1-r3)
(13/22) Installing musl-dev (1.2.2-r1)
(14/22) Installing libc-dev (0.7.2-r3)
(15/22) Installing g++ (10.2.1_pre1-r3)
(16/22) Installing make (4.3-r0)
(17/22) Installing fortify-headers (1.1-r0)
(18/22) Installing patch (2.7.6-r7)
(19/22) Installing build-base (0.5-r2)
(20/22) Installing musl-obstack (1.1-r1)
(21/22) Installing libucontext (1.0-r0)
(22/22) Installing gcompat (1.0.0-r1)
Executing busybox-1.32.1-r6.trigger
OK: 198 MiB in 41 packages
bash-5.1# ./example.exe
Long: 0, ip:time="2022-01-17T12:04:04Z" level=info msg="[NewServer] Start to run http server" file="example.go:30"

4. Wait

The author developed go language, which should be static link by default. Why use dynamic links here? Re focus on the execution of the file command.

bash-5.1# file example.exe
example.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=r403apSf9gVnhAa92Ma3/CtPwwvYC_Td44-00QCD7/LNwlhyvp3IK5oGI_6pca/H9YPNEE1hvs-0EBN4ZA0, not stripped

Conclusion:

go itself does not rely on glibc, but the program developed by the author uses cgo, so libc is used. However, the processing of dependent libraries is different between the author's local compiler clang and the compiler gcc in the compilation image.

4.1 truth · solution

4.1.1 use of CGO_ENABLED=0

Using CGO_ENABLED=0 turns off allowing dynamic links.

4.1.2 replace the dependent basic image

Alpine Linux lacks the dynamic library of glibc by default, and it is changed to Ubuntu 18.04 X is solvable.

5. Broken thoughts

So far, a magical problem stepped on last week has been preliminarily solved. Of course, if you want to know the difference between compilers, you can still go deep into it, but the author still has development to do, so let's record it here first.

  • If a person affects your emotions, your focus should be on controlling your emotions, not the people who affect your emotions. Only in this way can we really be confident.
  • If you feel that everything around you is too unhappy, go to the place you like, do the things you like, and buy the things you like.
  • If you are happy occasionally, that is the meaning of life.

6. References

Topics: Linux Operation & Maintenance Docker