有没有一种程序化的方法来检查 Linux 上当前的 rpath?

我知道可以使用 readelf -d <elf> | grep RPATH从 shell 中检查给定的二进制文件,但是可以在进程中这样做吗?

比如(我完全编造的系统调用) :

  /* get a copy of current rpath into buffer */
sys_get_current_rpath(&buffer);

我正在尝试诊断一些可疑的 SO 连接问题在我们的代码库中,并希望以这种方式检查 RPATH 如果可能的话(我宁愿不要产生一个外部脚本)。

99511 次浏览
#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;
}

For the record, here are a couple of commands that will show the rpath / runpath header.

objdump -x binary-or-library |grep 'R.*PATH'

Maybe an even better way to do it is the following:

readelf -d binary-or-library |head -20

The second command also lists the direct dependencies on other libraries followed by rpath.

You can also use:

chrpath -l binary-or-library

Here's what I use for convenience, as a shell function:

function getrpath {
eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

This consumes eu-readelf output from elfutils like:

Type              Value
NEEDED            Shared library: [libpq.so.5]
NEEDED            Shared library: [libc.so.6]
RUNPATH           Library runpath: [/some/path/to/lib]
....

and emits

 /some/path/to/lib

It should work fine with binutils readelf instead of elfutils eu-readelf too.

There is a way. Follow the example code in man dlinfo [1], but use NULL as the first parameter of dlopen().

[1] https://man7.org/linux/man-pages/man3/dlinfo.3.html