是否有一种编程方式来检查 Linux 上的当前 rpath?
Posted
技术标签:
【中文标题】是否有一种编程方式来检查 Linux 上的当前 rpath?【英文标题】:Is there a programmatic way to inspect the current rpath on Linux? 【发布时间】:2011-02-19 15:34:51 【问题描述】:我知道可以使用 readelf -d <elf> | grep RPATH
从 shell 检查给定的二进制文件,但是可以在进程中执行此操作吗?
类似于(我完全编造的系统调用):
/* get a copy of current rpath into buffer */
sys_get_current_rpath(&buffer);
我正在尝试在我们的代码库中诊断一些可疑的 SO 链接问题,并希望尽可能以这种方式检查 RPATH(我宁愿不必生成外部脚本)。
【问题讨论】:
请记住,在诊断共享库问题时,您还应该检查 RUNPATH 标记。因此,您应该改为grep PATH
。使用 RPATH 还是 RUNPATH 取决于链接器,两者之间存在细微但重要的区别:***.com/a/52020177
【参考方案1】:
为了记录,这里有几个命令将显示rpath
标头。
objdump -x binary-or-library |grep RPATH
也许更好的方法是:
readelf -d binary-or-library |head -20
第二个命令还列出了对其他库的直接依赖关系,后面跟着rpath
。
【讨论】:
在 ubuntu 15.04 上我必须使用:objdump -x binary-or-library |grep RUNPATH RPATH != RUNPATH,见***.com/questions/7967848/use-rpath-but-not-runpath & blog.qt.io/blog/2011/10/28/rpath-and-runpath 这个答案nothing与所提出的问题(并且包含在问题本身中)。【参考方案2】:#include <stdio.h>
#include <elf.h>
#include <link.h>
int main()
const ElfW(Dyn) *dyn = _DYNAMIC;
const ElfW(Dyn) *rpath = NULL;
const char *strtab = NULL;
for (; dyn->d_tag != DT_NULL; ++dyn)
if (dyn->d_tag == DT_RPATH)
rpath = dyn;
else if (dyn->d_tag == DT_STRTAB)
strtab = (const char *)dyn->d_un.d_val;
if (strtab != NULL && rpath != NULL)
printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
return 0;
【讨论】:
它很棒,但它不适用于 $ORIGIN。 $ORIGIN 不被解释,并由函数按原样返回。有没有办法添加 $ORIGIN 解释? @Jérôme 如果您在安装了/proc
的环境中执行,那么扩展$ORIGIN
就像readlink("/proc/self/exe", ...)
一样简单,然后在最后一个斜杠处以NUL 终止。
虽然这个问题专门针对RPATH
,但我想指出,如果希望了解二进制文件可能加载其共享库的路径,检查DT_RUNPATH
标签同样重要来自。【参考方案3】:
你也可以使用:
chrpath -l binary-or-library
【讨论】:
在 ubuntu 上:apt-get install -y chrpath
【参考方案4】:
为了方便起见,我将其用作 shell 函数:
function getrpath
eu-readelf -d "$1:?" | sed -e '/RUNPATH/s~.*\[\(.*\)\]~\1~;n;d'
这会消耗来自elfutils
的eu-readelf
输出,例如:
Type Value
NEEDED Shared library: [libpq.so.5]
NEEDED Shared library: [libc.so.6]
RUNPATH Library runpath: [/some/path/to/lib]
....
并发射
/some/path/to/lib
它应该可以正常使用 binutils readelf
而不是 elfutils eu-readelf
。
【讨论】:
【参考方案5】:有办法。按照man dlinfo
[1]中的示例代码,但使用NULL
作为dlopen()
的第一个参数。
[1]https://man7.org/linux/man-pages/man3/dlinfo.3.html
【讨论】:
以上是关于是否有一种编程方式来检查 Linux 上的当前 rpath?的主要内容,如果未能解决你的问题,请参考以下文章