深入理解linux执行文件提示No such file or directory的背后原因
1背景
最近一直在研究在ZC706-ARM开发板的linux系统中弄一套编译系统(不支持apt),刚好发现公司有一套英伟达的ARM开发板且带有ubunut系统(支持apt),此时产生一个想法,英伟达板子上编译的程序能否在ZC706的板子上运行?
2过程
在英伟达的开发板中gcca.c生成a.out,然后拷贝到ZC706中执行出现“Nosuchfileordirectory”
以前遇到的是以下原因:
- 文件本身不存在或者文件损坏
- 无执行权限(chmod777xxx)
- 系统位数与程序位数不同
但是经过以下过程发现是ZC706缺少xx程序的指定的装载器:
1.排除文件损坏等问题-->重新生成拷贝验证
2.排除程序权限问题-->chmod777xx&&ls-all
3.通过unanme-a排除架构问题
4.通过readelffile等命令对比正常执行的文件与错误执行文件的差别
验证过程:
a.out由英伟达gcc编译生成且zc706出现上面问题|b.out由x86ubunut交叉编译生成且可以正常执行
后来通过google等发现装载器也会造成该现象,从下面可以发现两者的区别主要在于interpreter
解决方案:
1.统一编译器与库的关系
2.建立软链接ln-s/lib/ld-linux.so.3/lib/ld-linux-armhf.so.3
3.编译程序时,加入-static选项静态链接程序,即不使用动态库
root@tegra-ubuntu:~#readelf-ha.out ELFHeader: Magic:7f454c46010101000000000000000000 Class:ELF32 Data:2'scomplement,littleendian Version:1(current) OS/ABI:UNIX-SystemV ABIVersion:0 Type:EXEC(Executablefile) Machine:ARM Version:0x1 Entrypointaddress:0x8315 Startofprogramheaders:52(bytesintofile) Startofsectionheaders:4500(bytesintofile) Flags:0x5000402,hasentrypoint,Version5EABI,hard-floatABI Sizeofthisheader:52(bytes) Sizeofprogramheaders:32(bytes) Numberofprogramheaders:9 Sizeofsectionheaders:40(bytes) Numberofsectionheaders:30 Sectionheaderstringtableindex:27 root@tegra-ubuntu:~#readelf-hb.out ELFHeader: Magic:7f454c46010101000000000000000000 Class:ELF32 Data:2'scomplement,littleendian Version:1(current) OS/ABI:UNIX-SystemV ABIVersion:0 Type:EXEC(Executablefile) Machine:ARM Version:0x1 Entrypointaddress:0x86bc Startofprogramheaders:52(bytesintofile) Startofsectionheaders:4136(bytesintofile) Flags:0x5000202,hasentrypoint,Version5EABI,soft-floatABI Sizeofthisheader:52(bytes) Sizeofprogramheaders:32(bytes) Numberofprogramheaders:8 Sizeofsectionheaders:40(bytes) Numberofsectionheaders:31 Sectionheaderstringtableindex:28 root@tegra-ubuntu:~#readelf-lhelloworld|grepinterpreter readelf:Error:'helloworld':Nosuchfile root@tegra-ubuntu:~#readelf-la.out|grepinterpreter [Requestingprograminterpreter:/lib/ld-linux-armhf.so.3] root@tegra-ubuntu:~#readelf-lb.out|grepinterpreter [Requestingprograminterpreter:/lib/ld-linux.so.3]
3介绍ld装载器
Linux使用这个ld-linux.so*(虚拟机x86的ubuntu是使用ld-linux.so2)中的来装载(其实这只是一个链接)其他库。所以这个库必须放在linux中/lib下。对于其他,通常我们共享库放在/lib这个路径下,而且也是系统默认的搜索路径。
Linux共享库的搜索路径先后顺序:
1、编译目标代码时指定的动态库搜索路径:在编译的时候指定-Wl,-rpath=路径
2、环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3、配置文件/etc/ld.so.conf中指定的动态库搜索路径
4、默认的动态库搜索路径/lib
5、默认的动态库搜索路径/usr/lib
注意:
1.有些开发板会发现/etc没有ld.so.conf,此时运行ldconfig会提示"ldconfig:Warning:ignoringconfigurationfilethatcannotbeopened:/etc/ld.so.conf:Nosuchfileordirectory"
解决:加入库到环境变量,然后ldconfig-v(/sbin/ldconfig:relativepath`–v'usedtobuildcache)
2.共享库cnnotopensharedobject
测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
这时候找不到libtest.so,是动态链接库的查找路径出问题,因此加入上面动态库查找位置即可
3ldconfig命令主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件
4LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用/sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了,要用bash命令)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。