Mach pager загружает файл в память в файле mmap

после моего вопроса здесь, я расширил свое исследование фактического чтения/записи из файла в память и наоборот при вызове файловой 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 обычно выполняет часть чтения файла, используя vn_rdwr при загрузке нового изображения в execve, но я не смог найти ни одного синонима в дереве функций vnode_pager_map.

поэтому мой вопрос: какой метод на самом деле читает содержимое файла в системном вызове mmap?


person Community    schedule 12.06.2017    source источник
comment
Большинство систем карт памяти просто ждут ошибок страниц, чтобы выполнить фактическое чтение соответствующих частей файла на страницу.   -  person Some programmer dude    schedule 12.06.2017
comment
вы абсолютно правы, я только что поставил точку останова на метод сбоя страницы, и, похоже, он в конечном итоге вызвал VOP_READ, который является командой файловой системы для чтения из содержимого файла. Благодарность !   -  person    schedule 12.06.2017
comment
Вот почему это называется пейджингом по запросу. :)   -  person Some programmer dude    schedule 12.06.2017


Ответы (1)


Итак, после прочтения комментариев к моему вопросу выясняется, что отображение выполняется лениво.. в смысле, когда есть попытка доступа к памяти. Я поставил некоторую точку останова в соответствующих функциях и проверил, что когда я читаю из памяти сопоставленного файла, он сталкивается с ошибкой страницы и в результате извлекает данные (см. След ниже):

* 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
person Community    schedule 12.06.2017