Страницы

Поиск по вопросам

четверг, 9 января 2020 г.

куча mmap в простейшем коде дампа stacktrace

#cpp #linux


здравствуйте, вот решил прогнать через 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 скорее всего делает поправку на таблицу размещения. Механизм линкования библиотек у линукса немного необычный, описывать его - отдельная статья.

Комментариев нет:

Отправить комментарий