linux – 使用glibc而不是默认库编译的C程序:执行时拒绝权限
这是我关于stackoverflow的第一个问题,所以我会尽力做好.
语境: 我想提供一个可以在每个Linux发行版上运行的程序(例如,一个将使用C 11的程序,在没有C 11库的系统上运行). 我有2个环境要测试: 我在Opensuse下编译我的程序,并在Ubuntu下运行它.该程序使用默认库时效果很好. 项目: 这是main.c: int main(int ac,char **av) { printf("Hello World !n"); } 这是我在Opensuse下的文件夹的树(在没有main.c et exec.sh的Ubuntu下相同): + project | +--- main.c +--- a.out +--- exec.sh +---+ lib | +--- libc.so.6 +--- ld-linux-x86-64.so.2 最后,当我使用简单的编译启动程序时,这里是ldd和readelf: > gcc main.c -o a.out > ldd ./a.out linux-vdso.so.1 (0x00007fff85f57000) libc.so.6 => /lib64/libc.so.6 (0x00007f1fdaaaf000) /lib64/ld-linux-x86-64.so.2 (0x00007f1dae75000) > readelf -d a.out | grep "library|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 我做了一些研究,最后找到了this post,他们解释了一下ld-linux.so. 这是我用来编译的脚本: #!/bin/bash dir=`pwd` execName="a.out" libDir="/lib" linker="ld-linux-x86-64.so.2" gcc main.c -o ${execName} -Wl,--rpath=${dir}${libDir} -Wl,--dynamic-linker=${dir}${libDir}/${linker} 当我在我的Opensuse上使用脚本启动我的a.out编译时,我得到了以下内容: > ./a.out Hello World ! > ldd ./a.out linux-vdso.so.1 (0x00007f3222e27000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f3222a7e000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000073222e2b000) > readelf -d a.out | grep "library|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib] 问题: 现在,当我在我的Ubuntu上启动此可执行文件a.out(在Opensuse下编译)时,我得到以下输出: > ./a.out ./a.out: Permission denied. > ldd ./a.out linux-vdso.so.1 (0x00007fff5b5fe000) libc.so.6 => /path/to/project/lib/libc.so.6 (0x00007f47df480000) /path/to/project/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f47df82a000) > readelf -d a.out | grep "library|Library" 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000001d (RUNPATH) Library runpath: [/path/to/project/lib] 当我启动可执行文件时,我一直拒绝此权限,我不知道为什么. 我使用Filezilla将我的a.out和我的lib文件夹从Opensuse传输到Ubuntu,并且a.out在传输之后不是可执行文件,所以我需要这样做: chmod 755 a.out 我在Opensuse和Ubuntu下拥有相同的树 任何关于许可被拒绝的帮助,或者其他方式来做我想要的将是受欢迎的. 注意:我不能使用LD_PRELOAD,因为你需要root才能使用它,它不能用于我想做的事情. 解决方法
有很多事情可能是错的.以下是一些建议.
检查复制库的文件权限 您已经提到,无论您使用什么来复制a.out,都会改变该文件的权限.库也需要特定权限,因此请检查这些权限. 检查符号链接是否损坏 其中许多库通常实际上是真正二进制文件的符号链接.如果您只复制了链接而不复制基础二进制文件,则无法复制. 检查库是否不匹配 如您所知,libc不仅仅是一个文件.例如,在我的Linux机器上,如果我运行ldd /lib64/libc.so.6,我得到这个结果: /lib64/ld-linux-x86-64.so.2 (0x0000003531200000) linux-vdso.so.1 => (0x00007ffe2c78c000) 除非您还要复制所需的所有库,否则它将无法工作. 考虑使用-R作为链接器 -L标志告诉链接器它可以在哪里找到库,但是还有一个-R标志,它告诉生成的可执行文件在运行时在哪里找到库.我不清楚你是否需要它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |