运行 C语言有root权限的时候不能link动态库吗?
Can't link dynamic library when running C language with root privileges?
我有一个名为 testFunc.c
的 C 语言文件,它使用了动态库 libCfunc.so
。这个库放在路径/home/cuiyujie/workspace/library/lib
.
下
我将此路径添加到库路径 export LD_LIBRARY_PATH=/home/cuiyujie/workspace/library/lib:$LD_LIBRARY_PATH
当我使用如下命令编译时,可以正常编译。
gcc testFunc.c -lCfunc -lm -O0 -g -o testFunc
但是当我运行它的时候,如果我使用./testFunc
,它可以运行正常。
但是如果我用sudo ./testFunc
,他会报如下错误
./testFunc: error while loading shared libraries: libCfunc.so: cannot
open shared object file: No such file or directory
我在Google上发现,当使用root时,LD_LIBRARY_PATH
变量的值被忽略了。
我使用以下命令重新编译。编译时指定库路径
gcc testFunc.c -L/home/cuiyujie/workspace/library/lib -lCfunc -lm -O0 -g -o testFunc
当我用sudo ./testFunc
命令继续运行时,仍然出现同样的错误。
之所以需要用root执行,是因为需要读取一些只有root权限才能读取的查询。想获取某些变量的物理地址,需要读取进程的映射文件,需要root权限
linker 标志 -L
只是告诉 linker 在 link 处寻找库(或库存根,如果使用的话)时间。它不会影响运行时的库搜索路径。
对于系统范围安装的库,您可以将库放置在全局 linker 搜索路径中配置的位置,通过 /etc/ld.so.conf
和 /etc/ld.so.conf.d
中的文件进行设置.
然而,完全可以通过所谓的 rpath 指定特定于某些二进制文件的其他搜索路径。 rpath 是使用(你猜对了)rpath
extra linker 标志 -Wl,-rpath
设置的。
将程序链接到
gcc -o … -Wl,-rpath='${ORIGIN}' …
将使 ELF 解释器(加载 ELF 二进制文件并执行动态 linkage 的代码段)也在程序旁边寻找其他库二进制。您可以在 ld.so
联机帮助页中阅读 rpaths 的详细信息。
请注意,rpaths 会引起某些安全考虑。
LD_LIBRARY_PATH
是一个环境变量,所有的环境变量都是为每个用户单独存在的。
当您在普通用户下导出它,然后 运行 使用 sudo
作为 root 可执行文件时,新进程的导出不存在。
您可以使用 -E 参数保留用户的环境:
sudo -E ./testFunc
或者您可以像这样专门保留 LD_LIBRARY_PATH
变量:
sudo LD_LIBRARY_PATH=/home/cuiyujie/workspace/library/lib:$LD_LIBRARY_PATH ./testFunc
我有一个名为 testFunc.c
的 C 语言文件,它使用了动态库 libCfunc.so
。这个库放在路径/home/cuiyujie/workspace/library/lib
.
我将此路径添加到库路径 export LD_LIBRARY_PATH=/home/cuiyujie/workspace/library/lib:$LD_LIBRARY_PATH
当我使用如下命令编译时,可以正常编译。
gcc testFunc.c -lCfunc -lm -O0 -g -o testFunc
但是当我运行它的时候,如果我使用./testFunc
,它可以运行正常。
但是如果我用sudo ./testFunc
,他会报如下错误
./testFunc: error while loading shared libraries: libCfunc.so: cannot open shared object file: No such file or directory
我在Google上发现,当使用root时,LD_LIBRARY_PATH
变量的值被忽略了。
我使用以下命令重新编译。编译时指定库路径
gcc testFunc.c -L/home/cuiyujie/workspace/library/lib -lCfunc -lm -O0 -g -o testFunc
当我用sudo ./testFunc
命令继续运行时,仍然出现同样的错误。
之所以需要用root执行,是因为需要读取一些只有root权限才能读取的查询。想获取某些变量的物理地址,需要读取进程的映射文件,需要root权限
linker 标志 -L
只是告诉 linker 在 link 处寻找库(或库存根,如果使用的话)时间。它不会影响运行时的库搜索路径。
对于系统范围安装的库,您可以将库放置在全局 linker 搜索路径中配置的位置,通过 /etc/ld.so.conf
和 /etc/ld.so.conf.d
中的文件进行设置.
然而,完全可以通过所谓的 rpath 指定特定于某些二进制文件的其他搜索路径。 rpath 是使用(你猜对了)rpath
extra linker 标志 -Wl,-rpath
设置的。
将程序链接到
gcc -o … -Wl,-rpath='${ORIGIN}' …
将使 ELF 解释器(加载 ELF 二进制文件并执行动态 linkage 的代码段)也在程序旁边寻找其他库二进制。您可以在 ld.so
联机帮助页中阅读 rpaths 的详细信息。
请注意,rpaths 会引起某些安全考虑。
LD_LIBRARY_PATH
是一个环境变量,所有的环境变量都是为每个用户单独存在的。
当您在普通用户下导出它,然后 运行 使用 sudo
作为 root 可执行文件时,新进程的导出不存在。
您可以使用 -E 参数保留用户的环境:
sudo -E ./testFunc
或者您可以像这样专门保留 LD_LIBRARY_PATH
变量:
sudo LD_LIBRARY_PATH=/home/cuiyujie/workspace/library/lib:$LD_LIBRARY_PATH ./testFunc