ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Cannot execute binary file 之原因

2022-01-17 20:34:04  阅读:284  来源: 互联网

标签:binary execute exe r0 22 Installing Cannot example bash


文章目录

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

注:执行 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. 参考资料

标签:binary,execute,exe,r0,22,Installing,Cannot,example,bash
来源: https://blog.csdn.net/phantom_111/article/details/122547593

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有