gpt4 book ai didi

linux - 如何使用ldd和rpath找到无法显示的隐藏库?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:13:27 25 4
gpt4 key购买 nike

我正在构建高性能 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com