ltrace -S
анализ минимального примера показывает, что mmap
используется в glibc 2.23
В glibc 2.23, Ubuntu 16.04, запуск latrace -S
в минимальной программе, которая использует dlopen
с:
ltrace -S./dlopen.out
показывает:
dlopen("libcirosantilli_ab.so", 1
SYS_open("./x86_64/libcirosantilli_ab.so", 524288, 06267650550) = -2
SYS_open("./libcirosantilli_ab.so", 524288, 06267650550) = 3
SYS_read(3, "\177ELF\002\001\001", 832) = 832
SYS_brk(0) = 0x244c000
SYS_brk(0x246d000) = 0x246d000
SYS_fstat(3, 0x7fff42f9ce30) = 0
SYS_getcwd("/home/ciro/bak/git/cpp-cheat"..., 128) = 54
SYS_mmap(0, 0x201028, 5, 2050) = 0x7f1c323fe000
SYS_mprotect(0x7f1c323ff000, 2093056, 0) = 0
SYS_mmap(0x7f1c325fe000, 8192, 3, 2066) = 0x7f1c325fe000
SYS_close(3) = 0
SYS_mprotect(0x7f1c325fe000, 4096, 1) = 0
поэтому мы сразу видим, что dlopen
вызывает open
+ mmap
.
Удивительный инструмент ltrace
отслеживает как библиотечные, так и системные вызовы, и поэтому идеально подходит для изучения того, что происходит в данном случае.
Более тщательный анализ показывает, что open
возвращает файловый дескриптор3
(следующий свободный после stdin, out и err ).
Затем
read
использует этот дескриптор файла, но TODO, почему аргументы mmap
ограничены четырьмя, и мы не можем видеть, какой fd там использовался, поскольку это 5-й аргумент . strace
подтверждает, как и ожидалось, что 3
— это тот самый, и порядок во Вселенной восстанавливается.
Смельчаки тоже могут попробовать код glibc, но я не смог найти mmap
после быстрого поиска, а мне лень.
Протестировано на этом минимальном примере с шаблоном сборки на GitHub .