Я пытаюсь понять, как printf
работает в C для простого случая. Я написал следующую программу:
#include "stdio.h"
int main(int argc, char const *argv[])
{
printf("Test %s\n", argv[1]);
return 0;
}
Запуск objdump
в двоичном файле. Я заметил, что Test %s\n
находится в .rodata
objdump -sj .rodata bin
bin: file format elf64-x86-64
Contents of section .rodata:
08e0 01000200 54657374 2025730a 00 ....Test %s..
Таким образом, форматированная печать выполняет дополнительное копирование шаблона из rodata
в другое место.
После компиляции и запуска с stare ./bin rr
я заметил системный вызов brk
перед фактической записью. Так что запустив его с
gdb catch syscall brk
gdb catch syscall write
показывает, что в моем случае текущий разрыв равен 0x555555756000
, но затем он устанавливается на 0x555555777000
. Когда появляется write
, отформатированная строка
x/s $rsi
0x555555756260: "Test rr\n"
Находится между «старым» и «новым» перерывом. После завершения записи программы завершают работу.
ВОПРОС: Почему мы выделяем столько страниц и почему разрыв не возвращается к предыдущей после записи системного вызова? Есть ли причина использовать brk
вместо mmap
для такого форматирования?