为啥 '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 上省略了系统库?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Epic Games Launcher 在 MacOS 上崩溃? (崩溃报告)[关闭]
如何通过 pssh/fabric 库使用 lsof 命令? Bash:找不到lsof命令[重复]
为啥相同的 SwiftUI 代码可以在 iOS 上运行而在 macOS 上失败?