如何调试"cannot open shared object file: No such file or directory"?

How to debug "cannot open shared object file: No such file or directory"?

在我们工作的项目中,我使用由另一个团队管理的构建系统,我 运行 遇到了一个问题,我可以编译和 link 二进制文件,但是当执行它,它抱怨无法加载共享对象文件,它不应该被 link 反对:

/home/me/build/bin/executable: error while loading shared libraries: libicui18n.so.52.1: cannot open shared object file: No such file or directory

奇怪的是,我什至在我的机器上能找到的文件名 libicui18n.so.52.1 的唯一实例是 /opt/onlyoffice/desktopeditors/libicui18n.so.52.1/home/me/.local/opt/foxitsoftware/foxitreader/lib/libicui18n.so.52.1,我肯定 不要 link 反对,至少根据构建系统执行的 linker 命令:

所以现在我想知道 libicui18n.so.52.1 还可能 link 反对什么,以及我如何着手调试这样的问题。

how else the libicui18n.so.52.1 may be linked against

ELF 库可以指定“在运行时应使用什么名称”独立于 库本身的名称。示例:

gcc -fPIC -shared -o libt.so t.c -Wl,--soname=libfoo.so.1.2.3
gcc main.c -L. -lt

./a.out
./a.out: error while loading shared libraries: libfoo.so.1.2.3: cannot open shared object file: No such file or directory

这里,库的构建方式需要在运行时 libfoo.so.1.2.3,尽管不存在这样的库。由打包系统提供这样的库(或 symlink)。

您可以检查一个库以查看它希望在运行时使用什么名称,如下所示:

readelf -d libt.so | grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libfoo.so.1.2.3]

您可以在运行时检查 a.out 所需的库列表,如下所示:

 readelf -d ./a.out | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libfoo.so.1.2.3]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

how I may go about debugging such an issue.

同上。您的下一个问题可能是“我怎样才能解决这个问题?”。

因为 libicui18n.so.52.1 安装的,但没有安装到动态 linker 默认搜索的目录中,您所要做的就是告诉您的二进制文件将非标准 /opt/onlyoffice/desktopeditors 目录添加到要搜索的目录列表中。

您可以通过将 -Wl,-rpath=/opt/onlyoffice/desktopeditors 添加到可执行文件的 link 行来实现。

您也可以将 /opt/onlyoffice/desktopeditors 添加到 LD_LIBRARY_PATH,但最好使用 -Wl,-rpath