- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在构建高性能 Linpack,我正在尝试与我的同事共享二进制文件。在我构建之前,以下库也是我自己构建的,安装在/opt
中。这些库是:/opt/blis
、/opt/knem
和 /opt/openmpi
。
我试图将这些二进制和唯一必要的库传输给我的同事。但是我发现我在 /opt/openmpi/lib
中构建的库必须在运行时引用。
我已经检查了所有关于 rpath/runpath 的二进制文件和库,以及使用 ldd、chrpath 和 objdump 共享库的使用情况。不应引用 /opt/openmpi/lib
中的其他库。
是否有任何建议的方法来了解将引用哪个库,或者如何为我跟踪运行时文件访问,以找出我需要传输给我同事的最小文件集是什么?
使用ldd,发现会用到以下库和二进制文件:
二进制文件:
xhpl
mpirun
图书馆:
libblis.so.2
libjemalloc.so.2
libmpi.so.40
libopen-pal.so.40
libopen-rte.so.40
我使用 chrpath 让所有二进制文件和库指向运行目录,但它不起作用:
chrpath -c [二进制文件和库]
chrpath -r ./[二进制文件和库]
我预计我只能将最少数量的文件传输给我的同事并在不修改系统配置的情况下运行它。
最佳答案
你很幸运,Linux 在这些事情上非常强大。可能的原因,为什么ldd
不显示它们,是ldd
仅显示由动态链接器链接的库。它不显示由 C api 调用链接的库( dlopen(...)
等)。
您可以使用 strace
查看工具,程序在运行时试图做什么。大多数情况下,in 在第一秒加载它的库:
命令
strace -s 4096 -f -o sux ./yourbinary
将启动您的 ./yourbinary
在跟踪模式下,并将输出写入名为 sux
的文件中.例如,/bin/echo
的 strace 的前几行看起来是这样的:
execve("/bin/echo", ["/bin/echo", "arg"], 0x7ffd2542fc50 /* 39 vars */) = 0
brk(NULL) = 0x5631fce2c000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (file not found)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=275366, ...}) = 0
mmap(NULL, 275366, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7edeb8de6000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 <--- here you can see, that it opened /lib/x86_64-linux-gnu/libc.so.6 !
它跟踪内核调用、二进制文件执行的内容、大量不需要的(对于没有经验的人来说,通常难以理解的)信息的结果。但是,任何时候如果它使用 open
-就像调用某个库(在我的例子中,/lib/<arch>/libc.so.6
文件),它将清晰可见。
您还可以使用 grep
过滤输出的工具,例如 grep openat.*\.so sux
将过滤输出文件中的库开口(在我们的示例中为 sux
)。
重要的是我们在这里使用的是什么,打开一个共享库是用一个简单的 openat()
完成的。在内核级别调用(C 库中 open()
的内核调用变体)。
这是由 lsof
完成的工具。共享库中的链接是 mmap()
-ped 文件在正在运行的进程的地址空间中。 MMap 意味着文件不会被读入进程的堆中,而是被映射到它的地址空间中。在我们的案例中,差异并不重要,但 lsof
以不同的方式显示它们。本质上,mmap()
的内容-ped 文件将在进程内存中的指针上可用:读取它会读取文件,写入它会写入文件(在磁盘上)。 它甚至可以被执行(由 call
在汇编级别调用),这就是我们使用链接共享库时最常做的事情!
要获取正在运行的进程的打开(映射)文件列表,您可以使用命令
lsof -n -P -p <pid>
-n -P
只是在这里禁用一些不需要的网络分辨率,-p
很重要,因为它显示了 <pid>
的打开文件.例如,lsof
正在运行的 bash shell 的输出是这样的:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 9072 root cwd DIR 8,7 4096 721255 /root
bash 9072 root rtd DIR 8,7 4096 2 /
bash 9072 root txt REG 8,7 1168776 6422594 /bin/bash
bash 9072 root mem REG 8,7 55792 2105586 /lib/x86_64-linux-gnu/libnss_files-2.28.so
bash 9072 root mem REG 8,7 164738 3844637 /usr/share/locale/de/LC_MESSAGES/libc.mo
bash 9072 root mem REG 8,7 337184 3051462 /usr/lib/locale/de_AT.utf8/LC_CTYPE
bash 9072 root mem REG 8,7 2586242 2753498 /usr/lib/locale/aa_DJ.utf8/LC_COLLATE
bash 9072 root mem REG 8,7 1824496 2105577 /lib/x86_64-linux-gnu/libc-2.28.so
bash 9072 root mem REG 8,7 14592 2105579 /lib/x86_64-linux-gnu/libdl-2.28.so
bash 9072 root mem REG 8,7 183528 2097224 /lib/x86_64-linux-gnu/libtinfo.so.6.1
bash 9072 root mem REG 8,7 89016 2105583 /lib/x86_64-linux-gnu/libnsl-2.28.so
bash 9072 root mem REG 8,7 47608 2105588 /lib/x86_64-linux-gnu/libnss_nis-2.28.so
bash 9072 root mem REG 8,7 39736 2105584 /lib/x86_64-linux-gnu/libnss_compat-2.28.so
bash 9072 root mem REG 8,7 54 3020617 /usr/lib/locale/agr_PE/LC_NUMERIC
bash 9072 root mem REG 8,7 165632 2105569 /lib/x86_64-linux-gnu/ld-2.28.so
<...many unneeded thingy...>
bash 9072 root 0u CHR 136,2 0t0 5 /dev/pts/2
bash 9072 root 1u CHR 136,2 0t0 5 /dev/pts/2
bash 9072 root 2u CHR 136,2 0t0 5 /dev/pts/2
bash 9072 root 255u CHR 136,2 0t0 5 /dev/pts/2
在fd
列,在那里你可以看到 mem
,它是一个 mmap()
-ed 文件。 如果文件带有 .so
扩展被映射,那么它就是一个运行时链接的共享库。
您可以再次使用 grep
过滤输出的工具。
关于linux - 如何使用ldd和rpath找到无法显示的隐藏库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57688882/
当路径不存在时运行 ldd 命令时,我得到的是“找不到文件”而不是路径。bash-3.2$ ldd curl libcurl.so.4 =>/usr/local/lib/libcurl.so.4 li
假设我有一个 A.so 文件,它的依赖项是从 ldd 中找到的 #ldd A [...] libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00007faaf972
我在可执行文件上运行 truss 命令并得到以下输出: stat64("/net/xyzmachine/vol/tools/solx64/studio11/SUNWspro/lib/rw7/librt
我在使用库时遇到问题,尽管它的版本正确,但找不到它。 ldd /lib/libQt5Core.so linux-gate.so.1 (0xb77ac000) libpt
我正在尝试创建一个共享库 libddv3djava.so 我像这样编译 libddv3djava.so 的源代码: ~/Programming/intellijprojects/ddv3dbindin
我知道 ldd 只能将二进制作为其参数我在这里问的是如何使用二进制运行 ldd,比如 mybin,带有二进制参数。例如,mybin --myparam ./configfile.conf。 如果我为我
我不清楚为什么 ldd 在找不到依赖项时多次向我显示同一个共享库。在一个使用 boost 的小可执行文件中,输出是: libboost_chrono.so.1.49.0 => not found li
我在 Open MPI 创建的可执行文件上运行了 ldd 命令。它显示了对 libpthread.so 的引用使用 LD_PRELOAD 变量,我创建了自己的 pthread_create 实现,但从
假设我们有一个名为 utils.so 的共享库。它可能包含 undefined symbol 。还假设 ldd 报告该库依赖于其他一些库: $ ldd utils.so library1.so
我正在 Linux (Ubuntu 11) 下编译 2 个共享库(“A”、“B”) 库“B”正在使用库“A”的导出函数(与 -lA 静态链接) 但是当我在“B”上运行 ldd 时,我只有* linux
我正在尝试编译项目。它编译成功。我的make命令退出,状态代码为 0并且没有显示错误。 但是,该项目无法运行,当我运行 ldd -d 时它显示我有两个库未找到。 >ldd -d output_fil
为什么给ldd可执行文件名时没有出现动态加载的库?这是真的吗?因为我给的时候找不到。这可能是因为动态加载和动态链接。 请帮我解决这个问题,如果您需要任何进一步的详细信息,请告诉我。 输出如下。 ldd
如果问题很基础,请直截了当。 ldd 命令显示可执行文件上的依赖库是我所知道的。在可执行文件中,这些信息保存在哪里? 最佳答案 这存储在 ELF 的 .dynamic 部分中可执行。参见 ELF-64
我有一个二进制文件,其中 ldd 显示出意外的依赖关系和 libicuuc(来自“icu”)。 #ldd A [...] libxml2.so.2 => /usr/lib64/libxml2.so.2
我有一个使用一堆 .so 文件的二进制文件。 bash-3.00$ file foo foo: ELF 32-bit LSB executable, Intel 80386, version 1 (S
ldd如何知道这取决于 libc.so.6 ,不是 libc.so.5或 libc.so.7 ? libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
Version information: ./VideoEncoderFilter.so: libgcc_s.so.1 (GCC_3.0) => /lib/x86_64-linux-gnu/l
我试图为 Linux 部署 Qt/QML 应用程序。发生了一些奇怪的事情,目标系统提示 libQt5Widget.so.5 中 undefined symbol ,而我已经复制了 ldd -r 结果中
如何从可执行文件的 ldd 输出中复制所有共享对象? 我正在寻找这样的东西,但这是用于 find 的,我需要 ldd: find -name "*python3.7*" -exec cp "{}" /
由于使用 Gentoo,更新程序后经常会链接到旧版本的库。通常,revdep-rebuild 有助于解决这个问题,但这次它是对 python 库的依赖,而 python-updater 不会选择它。
我是一名优秀的程序员,十分优秀!