Почему printf() выполняет sys_mmap(), а затем копирует содержимое строки в кусках (1024) в новое адресное пространство для sys_write()?Почему mmap выполняется во время вызовов printfs?
Показатель простой статической программы «привет» показан ниже.
> gcc -o hello -static hello.c
> strace ./hello
execve("./hello", ["./hello"], [/* 71 vars */]) = 0
uname({sys="Linux", node="Kumar", ...}) = 0
brk(0) = 0x1ce8000
brk(0x1ce91c0) = 0x1ce91c0
arch_prctl(ARCH_SET_FS, 0x1ce8880) = 0
readlink("/proc/self/exe", "/home/admin/hello", 4096) = 18
brk(0x1d0a1c0) = 0x1d0a1c0
brk(0x1d0b000) = 0x1d0b000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 28), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7feda2130000
write(1, "Hello", 5Hello) = 5
exit_group(0) = ?
+++ exited with 0 +++
Objdump из rodata
> objdump -s --start-address=0x4935a0 ./hello | head -5
./hello: file format elf64-x86-64
Contents of section .rodata:
4935a0 01000200 48656c6c 6f006c69 62632d73 ....Hello.libc-s
Если подключить адрес sys_write() системного вызова на уровне ядра, мы видим, что адрес передается к нему из ттар - адресной области. Разве это не просто трата нового адресного пространства, учитывая, что строка уже выходит в разделе .rodata в первом загружаемом сегменте двоичного файла. Имеет ли он что-то отношение к NO write permissions и т. Д.? Тогда почему бы не заставить компилятор помещать строку в .data раздел (который также доступен для записи) на первом месте?
UPDATE:
ММАП-эд адрес действительно для sys_write() которая может быть проверена в более простой способ, когда мы делаем строку большего размера (скажем, ~ 1500 символов). GDB подтвердит адрес данных печатается [Обратите внимание на вторую точку останова]
(gdb) c
Continuing.
Hello World hhhhhhhhhhalhfafeuirafheuhrgiegieguehguergjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwwwwwwwwwwwwwwwwwwwwww pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuiiiiiiiiiiiiiiiiiiiiiiiiiiiiiwqiuwqiuwiquwiqhchasnvjnavjanvjdanvjdanvjdanjfanvjaddijuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuquweuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunnnnnnnnnnnnnnnnnnnnnnnnnnnzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz,,,,,,,,,,,,,,,,,,,,,,
Breakpoint 1, _IO_new_file_write (f=0x6b8300 <_IO_2_1_stdout_>, data=0x7ffff7ffc000, n=706) at fileops.c:1257
1257 {
Спасибо большое! Но я не совсем понял это. Вы хотите сказать, что mmap-ed адрес stdout (FILE *)? –
Нет, 'mmap' используется из' malloc', вызываемого из 'fopen' или' printf' или 'puts'; 'malloc' используется для выделения буфера данных' stdout'. –
[См. Мое обновление] Новая смонтированная область действительно предназначена для хранения данных. Обратите внимание, что происходит, когда строка становится больше. Параметр data указывает на адрес MMAP. Поэтому мой вопрос остается в силе. –