日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

Cannot execute binary file 之原因

作者:phantom_111 更新時間: 2024-02-26 編程語言

文章目錄

    • 1. 寫在最前面
    • 2. 排查方向
      • 2.1 非 root 用戶
      • 2.2 編譯目標(biāo)與執(zhí)行環(huán)境不同
      • 2.3 程序需要的動態(tài)庫或靜態(tài)庫缺失
        • 2.3.1 解決辦法
    • 4. 等等
      • 4.1 真·解決辦法
        • 4.1.1 使用 CGO_ENABLED=0
        • 4.1.2 更換依賴的基礎(chǔ)鏡像
    • 5. 碎碎念
    • 6. 參考資料

1. 寫在最前面

問題:筆者用 kaniko 構(gòu)建了一個 docker 鏡像,基礎(chǔ)鏡像是基于 Alpine。構(gòu)建好后,運行編譯后的 go 二進(jìn)制程序。一直提示下面的錯誤:

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

在此處明顯看到 example.exe 的文件是存在的。懷疑是 sh有問題,筆者又按照了 bash 后繼續(xù)嘗試

# 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

到此處錯誤變?yōu)榱硕M(jìn)制無法執(zhí)行。百思不得其解的筆者,只能硬著頭皮繼續(xù)排查。

2. 排查方向

2.1 非 root 用戶

# whoami
root

注:此選項排除,筆者是以 root 的用戶登陸的。若此處為非 root 用戶,可以執(zhí)行 chmod +x program

2.2 編譯目標(biāo)與執(zhí)行環(huán)境不同

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

注:執(zhí)行 file 和 uname 命令對比發(fā)現(xiàn),程序的編譯目標(biāo)與執(zhí)行環(huán)境相同,排除此選項

2.3 程序需要的動態(tài)庫或靜態(tài)庫缺失

「排除一切不可能的,剩下的就算再不可能也是真相」

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

注:檢查程序的依賴庫,發(fā)現(xiàn)本地缺少 lib64 的動態(tài)依賴。原因是 Alpine 使用的標(biāo)準(zhǔn)庫與大多數(shù)發(fā)行版不同,它使用的是musl libc ,這個庫雖然相比 glibc 更小,更簡單,更安全,但是與大家常用的標(biāo)準(zhǔn) glibc 并不兼容。

2.3.1 解決辦法

采用維基百科的建議方案是,安裝 glic 作為 musl libc 的補(bǔ)充的方案。

注:原文

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.

安裝 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. 等等

筆者開發(fā)的是 go 語言,默認(rèn)應(yīng)該就是靜態(tài)鏈接。為什么此處使用了動態(tài)鏈接呢?重新關(guān)注下 file 命令的執(zhí)行。

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

結(jié)論:

go 本身沒有依賴 glibc,但是筆者開發(fā)的程序有 cgo 的使用,所以有 libc 的使用,而筆者本地的編譯器 clang 和編譯鏡像里的編譯器 gcc 對依賴庫的處理有所不同。

4.1 真·解決辦法

4.1.1 使用 CGO_ENABLED=0

使用 CGO_ENABLED=0 關(guān)掉允許動態(tài)鏈接。

4.1.2 更換依賴的基礎(chǔ)鏡像

Alpine Linux 默認(rèn)缺少 glibc 的動態(tài)庫,改為 ubuntu 18.04.x 可解。

5. 碎碎念

至此,上周踩到的一個神奇的問題才算是初步解決了,當(dāng)然你要是想知道編譯器的區(qū)別,也還是可以深究的,但是筆者還有開發(fā)要搞,就先記錄的到這里吧。

  • 如果一個人影響到了你的情緒,你的焦點應(yīng)該放在控制自己的情緒上,而不是影響你情緒的人身上。只有這樣,才能真正的自信起來。
  • 如果覺得身邊的一切都太不如意,那就去喜歡的地方,做喜歡的事,買喜歡的東西。
  • 如果偶爾快樂,那就是生活的意義。

6. 參考資料

  • Go Execution Modes
  • how can i resolve the error cannot execute binary file
  • Running glibc programs
  • 不要輕易使用 Alpine 鏡像來構(gòu)建 Docker 鏡像,有坑!
  • 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
  • 關(guān)于-/bin/sh:xx(命令) not found 的幾種原因和解決辦法

原文鏈接:https://blog.csdn.net/phantom_111/article/details/122547593

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新