c - Mach 寻呼机将文件加载到 mmap 文件中的内存

标签 c macos mmap kernel-extension xnu

按照我的问题 here ,我扩展了我对调用文件 mmap 时从文件到内存的实际读/写的研究,反之亦然。与 READ 和 WRITE 系统调用不同,MMAP 的情况不同,如下面的回溯所示:

(lldb) bt
* thread #3, name = '0xffffff801a6c24c0', queue = '0x0', stop reason = step in
* frame #0: 0xffffff80133b0788 kernel`ubc_map [inlined] VNOP_MMAP(fflags=<unavailable>, ctx=0xffffff8021a74af0) at kpi_vfs.c:3649 [opt]
frame #1: 0xffffff80133b0775 kernel`ubc_map(vp=<unavailable>, flags=<unavailable>) at ubc_subr.c:1793 [opt]
frame #2: 0xffffff8012f571dd kernel`vnode_pager_map(mem_obj=<unavailable>, prot=<unavailable>) at bsd_vm.c:737 [opt]
frame #3: 0xffffff8012f7a1cd kernel`vm_map_enter_mem_object_control [inlined] memory_object_map(memory_object=<unavailable>, prot=<unavailable>) at memory_object.c:2332 [opt]
frame #4: 0xffffff8012f7a1c3 kernel`vm_map_enter_mem_object_control(target_map=<unavailable>, address=<unavailable>, initial_size=<unavailable>, mask=<unavailable>, flags=<unavailable>, control=<unavailable>, offset=1, copy=<unavailable>, cur_protection=<unavailable>, max_protection=<unavailable>, inheritance=<unavailable>) at vm_map.c:4493 [opt]
frame #5: 0xffffff80133751a8 kernel`mmap(p=<unavailable>, uap=<unavailable>, retval=<unavailable>) at kern_mman.c:600 [opt]
frame #6: 0xffffff8013425695 kernel`unix_syscall64(state=<unavailable>) at systemcalls.c:376 [opt]
frame #7: 0xffffff8012e9dd46 kernel`hndl_unix_scall64 + 22

看起来 mach 寻呼机正在做这里的所有工作(将文件读入内存)。我知道 load_machfile 通常在 execve 中加载新图像时使用 vn_rdwr 读取文件部分,但我在 中找不到任何同义词code>vnode_pager_map 功能树。

所以我的问题是哪种方法实际读取了 mmap 系统调用中的文件内容?

最佳答案

好的,所以在阅读了对我的问题的评论之后,事实证明映射是惰性完成的..意思是,当尝试访问内存时。我在相关函数中放置了一些断点,并验证当我从映射文件的内存中读取时,它遇到页面错误并因此检索数据(参见下面的回溯):

* thread #12, name = '0xffffff801a378078', queue = '0x0', stop reason = breakpoint 6.1
* frame #0: 0xffffff801310abe4 kernel`cluster_read(vp=0xffffff801b5300f8, uio=0xffffff801d6f5050, filesize=146309, xflags=0) at vfs_cluster.c:3615 [opt]
frame #1: 0xffffff7f946c860d
frame #2: 0xffffff801314b5d8 kernel`VNOP_READ(vp=0xffffff80724bb528, uio=0x0000000000000000, ioflag=<unavailable>, ctx=<unavailable>) at kpi_vfs.c:3410 [opt]
frame #3: 0xffffff7f946c2fbb
frame #4: 0xffffff801314e5f4 kernel`VNOP_GETXATTR(vp=0x0000000000000000, name=<unavailable>, uio=<unavailable>, size=<unavailable>, options=<unavailable>, ctx=<unavailable>) at kpi_vfs.c:5424 [opt]
frame #5: 0xffffff7f94f81a6b
frame #6: 0xffffff7f94f81d93
frame #7: 0xffffff7f94f816e0
frame #8: 0xffffff8013160844 kernel`decmpfs_fetch_uncompressed_data(vp=<unavailable>, cp=<unavailable>, hdr=<unavailable>, offset=<unavailable>, size=<unavailable>, nvec=1, vec=<unavailable>, bytes_read=<unavailable>) at decmpfs.c:1064 [opt]
frame #9: 0xffffff80131601d3 kernel`decmpfs_pagein_compressed(ap=<unavailable>, is_compressed=0xffffff80724bba68, cp=<unavailable>) at decmpfs.c:1199 [opt]
frame #10: 0xffffff7f946cf340
frame #11: 0xffffff80133fc817 kernel`vnode_pagein [inlined] VNOP_PAGEIN(pl_offset=<unavailable>, size=0, flags=4096, ctx=<unavailable>) at kpi_vfs.c:5207 [opt]
frame #12: 0xffffff80133fc7d0 kernel`vnode_pagein(vp=<unavailable>, upl=<unavailable>, upl_offset=188416, f_offset=<unavailable>, size=<unavailable>, flags=4096, errorp=<unavailable>) at vnode_pager.c:597 [opt]
frame #13: 0xffffff8012f573c8 kernel`vnode_pager_cluster_read(vnode_object=0xffffff801deaf348, base_offset=188416, offset=<unavailable>, io_streaming=<unavailable>, cnt=0x0000000000001000) at bsd_vm.c:864 [opt]
frame #14: 0xffffff8012f57153 kernel`vnode_pager_data_request(mem_obj=0xffffff801deaf348, offset=188416, length=<unavailable>, desired_access=<unavailable>, fault_info=<unavailable>) at bsd_vm.c:645 [opt]
frame #15: 0xffffff8012f66043 kernel`vm_fault_page [inlined] memory_object_data_request(memory_object=0xffffff801deaf348, offset=<unavailable>, length=4096, desired_access=1, fault_info=0x0000000000000000) at memory_object.c:2228 [opt]
frame #16: 0xffffff8012f6602d kernel`vm_fault_page(first_object=<unavailable>, first_offset=<unavailable>, fault_type=<unavailable>, must_be_resident=0, caller_lookup=0, protection=<unavailable>, result_page=<unavailable>, top_page=<unavailable>, type_of_fault=0x0000000100000001, error_code=<unavailable>, no_zero_fill=<unavailable>, data_supply=0, fault_info=0x0000000000000000) at vm_fault.c:1794 [opt]
frame #17: 0xffffff8012f6afd6 kernel`vm_fault_internal(map=<unavailable>, vaddr=<unavailable>, caller_prot=1, change_wiring=0, interruptible=2, caller_pmap=<unavailable>, caller_pmap_addr=0, physpage_p=<unavailable>) at vm_fault.c:4716 [opt]
frame #18: 0xffffff80130015ec kernel`user_trap [inlined] vm_fault(map=<unavailable>, vaddr=<unavailable>, fault_type=<unavailable>, change_wiring=0, interruptible=2, caller_pmap=<unavailable>, caller_pmap_addr=0) at vm_fault.c:3397 [opt]
frame #19: 0xffffff80130015c8 kernel`user_trap(saved_state=0xffffff801a49c300) at trap.c:1123 [opt]
frame #20: 0xffffff8012e9d455 kernel`hndl_alltraps + 229

关于c - Mach 寻呼机将文件加载到 mmap 文件中的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44494314/

相关文章:

python - Mac OS X 无法再使用 pip 安装软件包

linux - 在 mmap 相同文件后删除 tmpfs(/dev/shm) 中的文件

十六进制长整数字面量 "L"的C解释

c - 如何在 C Win32 控制台应用程序中打印卡片套装字符?

c - 在 C 中播放 mp3 文件

python - 如何 "switch to one of the Agg backends"?

swift - 使用 swift 找不到 Bash 命令

python - 在 python 中多次访问 mmap 对象

c - 为什么 MAP_GROWSDOWN 映射不增长?

c - 在 C 中使用嵌套宏