为什么' lsof'省略macOS上的系统库?

时间:2017-08-15 22:44:40

标签: macos

作为参考,这是在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,还是有其他原因导致系统库未在此处报告?)

2 个答案:

答案 0 :(得分:2)

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

这个过程没有很多文档。有趣的是,所讨论的少数几个来源之一是the iPhone dev wiki,因为iOS使用相同的机制来避免必须运送独立库。

答案 1 :(得分:0)

除了duskwuff的回答(这让我发现了这些文档 - 谢谢!),man dyld包含了这个:

  

<强> DYLD_SHARED_REGION

     

这可以&#34;使用&#34; (默认值),&#34;避免&#34;或&#34;私人&#34;。将其设置为    &#34;避免&#34;告诉dyld不要使用共享缓存。所有OS dylib都已加载    像其他所有dylib一样动态。将其设置为&#34; private&#34;告诉dyld    从进程地址空间和mmap()中删除共享区域    在共享区域地址中的dyld共享缓存的私有副本中    范围。这仅在磁盘上的共享缓存已更新时才有用    与使用中的共享缓存不同。

因此,如果我们想要确切地看到macOS上的进程正在加载和使用哪些库,我们可以使用DYLD_SHARED_REGION=avoid set启动它。例如:

$ 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