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
- Go Execution Modes
- how can i resolve the error cannot execute binary file
- Running glibc programs
- Do not easily use Alpine image to build Docker image. There are pits!
- No such file or directory
- interpreter /lib64/ld-linux-x86-64.so.2?
- Go-compiled binary won't run in an alpine docker container on Ubuntu host
- Several reasons and solutions for - / bin / sh: XX (command) not found