为啥 'lsof' 在 macOS 上省略了系统库?

Posted

技术标签:

【中文标题】为啥 \'lsof\' 在 macOS 上省略了系统库?【英文标题】:Why does 'lsof' omit system libraries on macOS?为什么 'lsof' 在 macOS 上省略了系统库? 【发布时间】:2017-08-15 22:44:40 【问题描述】:

作为参考,这是在 macOS Sierra (10.12.6) 上。

例如,在终端中,我们可以执行以下命令列出当前shell加载的库:

$ lsof -p $$
COMMAND   PID  USER   FD   TYPE DEVICE  SIZE/OFF      NODE NAME
bash    57772 kevin  cwd    DIR    1,4     10370  89692838 /usr/lib
bash    57772 kevin  txt    REG    1,4    969276 101782360 /usr/local/Cellar/bash/4.4.12/bin/bash
bash    57772 kevin  txt    REG    1,4    698896 119314050 /usr/lib/dyld
bash    57772 kevin  txt    REG    1,4 662274048 120217216 /private/var/db/dyld/dyld_shared_cache_x86_64h
bash    57772 kevin    0u   CHR   16,4  0t566809      1083 /dev/ttys004
bash    57772 kevin    1u   CHR   16,4  0t566809      1083 /dev/ttys004
bash    57772 kevin    2u   CHR   16,4  0t566809      1083 /dev/ttys004
bash    57772 kevin  255u   CHR   16,4  0t566809      1083 /dev/ttys004

请注意,此处未显示系统库。但是,vmmap 确实确认我的 shell 确实在使用(例如)系统的 C++ 标准库:

$ vmmap $$ | grep libc++
__TEXT                 00007fffb9a64000-00007fffb9abb000 [  348K   204K     0K     0K] r-x/r-x SM=COW          /usr/lib/libc++.1.dylib
__TEXT                 00007fffb9abb000-00007fffb9ae5000 [  168K   148K     0K     0K] r-x/r-x SM=COW          /usr/lib/libc++abi.dylib
__DATA                 00007fffc3b78000-00007fffc3b80000 [   32K    24K    16K     4K] rw-/rwx SM=COW          /usr/lib/libc++.1.dylib
__DATA                 00007fffc3b80000-00007fffc3b82000 [    8K     4K     0K     4K] rw-/rwx SM=COW          /usr/lib/libc++abi.dylib

但是,在我的 Ubuntu 16.04 VM 上,我确实看到了lsof 输出中显示的系统库的使用情况——例如libc 在这里报告:

$ lsof -p $$ | grep libc
bash    2740 kevin  mem    REG    8,1  1868984 2883654 /lib/x86_64-linux-gnu/libc-2.23.so

我可以在 macOS 上做些什么来确保lsof 报告系统库吗? (是否有一些额外的标志我应该传递给lsof,或者还有其他原因导致这里没有报告系统库?)

【问题讨论】:

【参考方案1】:

它们存在 - 只是不是以您期望的形式。 macOS 将包括 libSystem 在内的大多数常见系统库组合到一个对象中,以便可以一次加载它们。此对象是 dyld 共享缓存 (dyld_shared_cache_x86_64h),它出现在您的 lsof 输出中。

关于这个过程的文档并不多。有趣的是,确实谈论它的少数来源之一是the iPhone dev wiki,因为 ios 使用相同的机制来完全避免发布独立库。

【讨论】:

【参考方案2】:

除了duskwuff 的回答(这让我发现了这一点文档——谢谢!),man dyld 包含以下内容:

DYLD_SHARED_REGION

这可以是“使用”(默认)、“避免”或“私人”。将其设置为 "avoid" 告诉 dyld 不要使用共享缓存。所有操作系统 dylib 都已加载 就像其他所有dylib一样动态地。将其设置为“私人”告诉 dyld 从进程地址空间中删除共享区域并返回 mmap() 在共享区域地址中 dyld 共享缓存的私有副本中 范围。这仅在磁盘上的共享缓存已更新并且 与正在使用的共享缓存不同。

因此,如果我们想确切了解 macOS 上某个进程加载和使用了哪些库,我们可以使用 DYLD_SHARED_REGION=avoid 设置启动它。例如:

$ DYLD_SHARED_REGION=avoid bash
$ lsof -p $$
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
bash    67924 kevin  cwd    DIR    1,4     6528    588406 /Users/kevin
bash    67924 kevin  txt    REG    1,4   969276 101782360 /usr/local/Cellar/bash/4.4.12/bin/bash
bash    67924 kevin  txt    REG    1,4   523200 108804194 /usr/lib/libncurses.5.4.dylib
bash    67924 kevin  txt    REG    1,4  2108224 108804181 /usr/lib/libiconv.2.dylib
bash    67924 kevin  txt    REG    1,4    60848 119314060 /usr/lib/libSystem.B.dylib
< ... more libraries ... >
bash    67924 kevin  txt    REG    1,4 14249664 119320170 /usr/lib/libobjc.A.dylib
bash    67924 kevin  txt    REG    1,4   436256 119314065 /usr/lib/libc++abi.dylib
bash    67924 kevin  txt    REG    1,4  1436752 108804146 /usr/lib/libc++.1.dylib
bash    67924 kevin  txt    REG    1,4   698896 119314050 /usr/lib/dyld
bash    67924 kevin    0u   CHR   16,6 0t462359      1097 /dev/ttys006
bash    67924 kevin    1u   CHR   16,6 0t462359      1097 /dev/ttys006
bash    67924 kevin    2u   CHR   16,6 0t462359      1097 /dev/ttys006
bash    67924 kevin  255u   CHR   16,6 0t462359      1097 /dev/ttys006

【讨论】:

以上是关于为啥 'lsof' 在 macOS 上省略了系统库?的主要内容,如果未能解决你的问题,请参考以下文章

在macos下运行redis命令为啥

为啥 Epic Games Launcher 在 MacOS 上崩溃? (崩溃报告)[关闭]

如何通过 pssh/fabric 库使用 lsof 命令? Bash:找不到lsof命令[重复]

为啥相同的 SwiftUI 代码可以在 iOS 上运行而在 macOS 上失败?

为啥这个基本链表可以在 MacOS 上工作,但在 Linux 上会出现段错误

为啥在 macOS 上使用 QThread 时 PyQt 应用程序崩溃或挂起?