網(wǎng)站首頁 編程語言 正文
文章目錄
- 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
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-08-01 C++無符號整數(shù)溢出問題解析_C 語言
- 2022-04-24 C++vector的用法你都知道嘛_C 語言
- 2023-04-20 URL中的參數(shù)提取
- 2022-04-01 SQL?Server?的T-SQL高級查詢詳解_MsSql
- 2023-05-20 React組件的用法概述_React
- 2022-03-24 C++關(guān)于指針,繼承和多態(tài)介紹_C 語言
- 2022-08-28 glibc編譯時報錯:configure: error:*** LD_LIBRARY_PATH sh
- 2022-07-13 RedisDesktopManager遠(yuǎn)程連接redis的實現(xiàn)_Redis
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支