文章目录

  • 1. 写在最前面
  • 2. 排查方向
    • 2.1 非 root 用户
    • 2.2 编译目标与执行环境不同
    • 2.3 程序需要的动态库或静态库缺失
      • 2.3.1 解决办法
  • 4. 等等
    • 4.1 真·解决办法
      • 4.1.1 使用 CGO_ENABLED=0
      • 4.1.2 更换依赖的基础镜像
  • 5. 碎碎念
  • 6. 参考资料

1. 写在最前面

问题:笔者用 kaniko 构建了一个 docker 镜像,基础镜像是基于 Alpine。构建好后,运行编译后的 go 二进制程序。一直提示下面的错误:

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

在此处明显看到 example.exe 的文件是存在的。怀疑是 sh有问题,笔者又按照了 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

到此处错误变为了二进制无法执行。百思不得其解的笔者,只能硬着头皮继续排查。

2. 排查方向

2.1 非 root 用户

# whoami
root

注:此选项排除,笔者是以 root 的用户登陆的。若此处为非 root 用户,可以执行 chmod +x program

2.2 编译目标与执行环境不同

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 strippedbash-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

注:执行 file 和 uname 命令对比发现,程序的编译目标与执行环境相同,排除此选项

2.3 程序需要的动态库或静态库缺失

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

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

注:检查程序的依赖库,发现本地缺少 lib64 的动态依赖。原因是 Alpine 使用的标准库与大多数发行版不同,它使用的是musl libc ,这个库虽然相比 glibc 更小,更简单,更安全,但是与大家常用的标准 glibc 并不兼容。

2.3.1 解决办法

采用维基百科的建议方案是,安装 glic 作为 musl libc 的补充的方案。

注:原文

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

笔者开发的是 go 语言,默认应该就是静态链接。为什么此处使用了动态链接呢?重新关注下 file 命令的执行。

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

结论:

go 本身没有依赖 glibc,但是笔者开发的程序有 cgo 的使用,所以有 libc 的使用,而笔者本地的编译器 clang 和编译镜像里的编译器 gcc 对依赖库的处理有所不同。

4.1 真·解决办法

4.1.1 使用 CGO_ENABLED=0

使用 CGO_ENABLED=0 关掉允许动态链接。

4.1.2 更换依赖的基础镜像

Alpine Linux 默认缺少 glibc 的动态库,改为 ubuntu 18.04.x 可解。

5. 碎碎念

至此,上周踩到的一个神奇的问题才算是初步解决了,当然你要是想知道编译器的区别,也还是可以深究的,但是笔者还有开发要搞,就先记录的到这里吧。

  • 如果一个人影响到了你的情绪,你的焦点应该放在控制自己的情绪上,而不是影响你情绪的人身上。只有这样,才能真正的自信起来。
  • 如果觉得身边的一切都太不如意,那就去喜欢的地方,做喜欢的事,买喜欢的东西。
  • 如果偶尔快乐,那就是生活的意义。

6. 参考资料

  • Go Execution Modes
  • how can i resolve the error cannot execute binary file
  • Running glibc programs
  • 不要轻易使用 Alpine 镜像来构建 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
  • 关于-/bin/sh:xx(命令) not found 的几种原因和解决办法

Cannot execute binary file 之原因相关推荐

  1. -bash: /tyrone/jdk/jdk1.8.0_91/bin/java: cannot execute binary file

    问题描述:今天在linux环境下安装了一下JDK,安装成功后,打算输入java -version去测试一下,结果却出错了. 错误信息:-bash: /tyrone/jdk/jdk1.8.0_91/bi ...

  2. java: cannot execute binary file错误

    http://everlook.iteye.com/blog/1568886 tomcat报错: /data/cmsolr/tomcat-solr-bid/bin/catalina.sh: line ...

  3. Ubuntu18.04报错:bin/bash: prebuilts/misc/linux-x86/bison/bison: cannot execute binary file解决

    报错:bin/bash: prebuilts/misc/linux-x86/bison/bison: cannot execute binary file报错原因:在x86 64位系统执行32位程序 ...

  4. java: cannot execute binary file 如果遇到这个错,一般是操作系统位数出问题了。

    [root@testserver usr]# java/jdk1.6.0_12/bin/java -bash: java/jdk1.6.0_12/bin/java: cannot execute bi ...

  5. 【linux】运行run文件显示cannot execute binary file

    linux系统下遇到cannot execute binary file的问题,一般由以下情况造成: 1. 非root用户或者无执行权限 2. 编译环境不同(程序由其他操作环境复制过来)对于第一种情况 ...

  6. ARM平台安装oracle时出现错误:runinstaller: line 97 /db/database/install/.oui: cannot execute binary file

    安装oracle时出现错误:runinstaller: line 97 /db/database/install/.oui: cannot execute binary file 用的华为云虚拟出的a ...

  7. mac上 go build的二进制文件在Linux上运行提示cannot execute binary file或者-bash: ./sayHello: 无法执行二进制文件的解决方式

    我在mac本上写的一段测试代码,想在linux系统上运行,go build sayHello.go,然后拷贝到Linux系统上./sayHello出现了错误提示: 提示cannot execute b ...

  8. Mac上执行Linux可执行文件报错:cannot execute binary file

    问题 在Mac上执行一个Linux可执行程序.出现以下报错:-bash: xxx: cannot execute binary file 解决 在Linux系统上执行,或在Mac上安装虚拟机.

  9. linux运行run文件显示cannot execute binary file

    感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正! 如果转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167原博文地址 ...

  10. java: cannot execute binary file问题的解决

    2019独角兽企业重金招聘Python工程师标准>>> 今天在虚机上安装了java,执行java -ersion 发现出现如题目错误,百了一下,发现应该是虚机32位的,而jdk是64 ...

最新文章

  1. 2019年中国重点大学排名发布,北大第1,清华第2,浙大第5
  2. C语言:在屏幕上打印杨辉三角形
  3. Linux常用网络命令总结
  4. LeetCode 螺旋矩阵(Spiral Matrix)
  5. mysql越筛越少_面试官:为什么SELECT * 会导致查询效率低?
  6. 【翻译】Nginx的反向代理
  7. 运放的典型电路举例与计算仿真
  8. C语言——字符串函数
  9. java中钩子方法 addShutdownHook 学习使用
  10. win10计算机用户文件夹改名字怎么改,win10如何改成自己想要的文件夹用户名
  11. python中read() readline()以及readlines()用法
  12. idea集成svn问题
  13. LHC或许已经首次制造出顶夸克“四胞胎”
  14. 计算机系统(一)期末复(yu)习(3):LC-3汇编,输入与输出
  15. 深度学习的简介、领域、框架和实际应用概述
  16. 基于51单片机的水温水流量检测/智能水龙头控制系统proteus仿真原理图PCB
  17. 蓝桥杯试题 算法提高 Monday-Saturday质因子
  18. 卸载EDR软件(简单记录)
  19. java基础/java调用shell命令和脚本
  20. 一次令人吐血的ubuntu源码安装gcc-5.4.0经历

热门文章

  1. Android apk包体瘦身
  2. 如果判断小米MIUI的NFC权限、后台弹出界面权限是否禁用
  3. MTK nvram介绍
  4. 1G、2G、3G、4G和5G有什么区别?5G的原理是什么?
  5. 经典策略之Dual Trust策略
  6. 上传图片到腾讯云(海外服务器)com.qcloud5.5.4版本
  7. 高速扩张的云市场,需要怎样的安全能力?
  8. 六西格玛黑带是什么?取得黑带认证有何意义?
  9. GRLDR外部MENU.LST调用GRLDR内部菜单
  10. 固态硬盘的计算机需要进行磁盘碎片整理吗,有问有答:固态硬盘需要磁盘碎片整理吗?...