здравствуйте, вот решил прогнать через strace бинарник хелловорлда:
#include
int main(int argc, char *argv[]) {
std::cout<<"hello world";
}
с -О2 генерируется в это:
.LC0:
.string "hello world\n"
main:
subq $8, %rsp
movl $.LC0, %esi
movl std::cout, %edi
call std::basic_ostream >& std::operator<<
>(std::basic_ostream >&, char const*)
xorl %eax, %eax
addq $8, %rsp
ret
_GLOBAL__sub_I_main:
subq $8, %rsp
movl std::__ioinit, %edi
call std::ios_base::Init::Init()
movl $__dso_handle, %edx
movl std::__ioinit, %esi
movl std::ios_base::Init::~Init(), %edi
addq $8, %rsp
jmp __cxa_atexit
и вот теперь совершенно не ясно откуда такой выхлоп у strace:
execve("./exceptions", ["./exceptions"], [/* 39 vars */]) = 0
brk(NULL) = 0x1d4d000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a31000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=150385, ...}) = 0
mmap(NULL, 150385, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff6f4a0c000
close(3) = 0
open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6",
O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\t\t\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2051952, ...}) = 0
mmap(NULL, 4161184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4419000
mprotect(0x7ff6f45fe000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f47fd000, 69632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x1e4000) = 0x7ff6f47fd000
mmap(0x7ff6f480e000, 11936, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x7ff6f480e000
close(3) = 0
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260V\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1062976, ...}) = 0
mmap(NULL, 3158248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4115000
mprotect(0x7ff6f4218000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f4417000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x102000) = 0x7ff6f4417000
close(3) = 0
open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220*\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=92312, ...}) = 0
mmap(NULL, 2188320, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f3efe000
mprotect(0x7ff6f3f14000, 2093056, PROT_NONE) = 0
mmap(0x7ff6f4113000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x15000) = 0x7ff6f4113000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\3\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1656280, ...}) = 0
mmap(NULL, 3762456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f3b67000
mprotect(0x7ff6f3cf4000, 2097152, PROT_NONE) = 0
mmap(0x7ff6f3ef4000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x18d000) = 0x7ff6f3ef4000
mmap(0x7ff6f3efa000, 14616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x7ff6f3efa000
close(3) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a0a000
arch_prctl(ARCH_SET_FS, 0x7ff6f4a0b5c0) = 0
mprotect(0x7ff6f3ef4000, 16384, PROT_READ) = 0
mprotect(0x7ff6f4113000, 4096, PROT_READ) = 0
mprotect(0x7ff6f4417000, 4096, PROT_READ) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a08000
mprotect(0x7ff6f47fd000, 53248, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7ff6f4a33000, 4096, PROT_READ) = 0
munmap(0x7ff6f4a0c000, 150385) = 0
brk(NULL) = 0x1d4d000
brk(0x1d7f000) = 0x1d7f000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
write(1, "hello world", 11hello world) = 11
exit_group(0) = ?
+++ exited with 0 +++
поясните, пожалуйста, откуда такая куча mmap?
Ответы
Ответ 1
strace — это утилита, отслеживающая системные вызовы, которые представляют собой
механизм трансляции, обеспечивающий интерфейс между процессом и операционной системой
(ядром). Эти вызовы могут быть перехвачены и прочитаны. Это позволяет лучше понять,
что процесс пытается сделать в заданное время. Перехватывая эти вызовы, мы можем добиться
лучшего понимания поведения процессов, особенно если что-то идет не так. Функциональность
операционной системы, позволяющая отслеживать системные вызовы, называется ptrace.
Про неё можно почитать Wiki, Ман и хабр.
Теперь прокоментирую некоторые строчки дампа
execve("./exceptions", ["./exceptions"], [/* 39 vars */]) = 0
brk(NULL) = 0x1d4d000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff6f4a31000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 открытие файла, возврат дескриптора №3.
fstat(3, {st_mode=S_IFREG|0644, st_size=150385, ...}) = 0 посмотреть размер
mmap(NULL, 150385, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff6f4a0c000 Отобразить весь
модуль кеша в гдеугодно памяти -> Размещён по адресу 7ff6f4a0c000
close(3) Закрыть дескриптор 3
open("/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libstdc++.so.6",
O_RDONLY|O_CLOEXEC) = 3 открыть модуль, выдан снова уже свободный дескриптор №3.
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\t\t\0\0\0\0\0"..., 832)
= 832 читаем заголовок файла (elf), дальше идёт расчёт секций
fstat(3, {st_mode=S_IFREG|0755, st_size=2051952, ...}) = 0 Получить размер файла
mmap(NULL, 4161184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ff6f4419000
Помещаем одну из readonly секций в память
mprotect(0x7ff6f45fe000, 2093056, PROT_NONE) = 0 резервируем секцию (? незнаю зачем,
скорее всего для помещения туда данных c помощью mmap)
mmap(0x7ff6f47fd000, 69632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0x1e4000) = 0x7ff6f47fd000
эту секцию на полный доступ
mmap(0x7ff6f480e000, 11936, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,
-1, 0) = 0x7ff6f480e000 и эту секцию на полный доступ
close(3) закрыли файл
...
brk(0x1d7f000) = 0x1d7f000
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 это похоже подготовка
консоли к работе.
write(1, "hello world", 11hello world) собственно ваш вывод в консоль
exit_group(0) ну и выход с программы.
О дескрипторах можно сказать что 1=STDOUT. 3=файл или свободный после close. 2 -
не могу сказать что там. И последнее, mmap скорее всего делает поправку на таблицу
размещения. Механизм линкования библиотек у линукса немного необычный, описывать его
- отдельная статья.