SlideShare a Scribd company logo
Раскручиваем
стек
Пономарев Иван, Synesis
1
Что такое стек
вызовов?
2
Стек вызовов
LIFO структура данных, хранящая адреса возврата в подпрограммы
3
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
4
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
● Выделяется:
○ Ядром ОС (для главного потока)
○ Внутри процесса при создании потока (pthread)
5
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
● Выделяется:
○ Ядром ОС (для главного потока)
○ Внутри процесса при создании потока (pthread)
● Вершина стека - регистр Stack Pointer (SP, ESP, RSP)
6
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
● Выделяется:
○ Ядром ОС (для главного потока)
○ Внутри процесса при создании потока (pthread)
● Вершина стека - регистр Stack Pointer (SP, ESP, RSP)
● Размер элемента - машинное слово
7
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
● Выделяется:
○ Ядром ОС (для главного потока)
○ Внутри процесса при создании потока (pthread)
● Вершина стека - регистр Stack Pointer (SP, ESP, RSP)
● Размер элемента - машинное слово
● Наиболее популярен Full Descending стек
○ Stack Pointer указывает на элемент, находящийся на вершине стека
○ Стек растёт вниз (в сторону уменьшения адресов)
8
Как работает стек вызовов
● Стек - область памяти, уникальная для каждого потока (thread)
● Выделяется:
○ Ядром ОС (для главного потока)
○ Внутри процесса при создании потока (pthread)
● Вершина стека - регистр Stack Pointer (SP, ESP, RSP)
● Размер элемента - машинное слово
● Наиболее популярен Full Descending стек
○ Stack Pointer указывает на элемент, находящийся на вершине стека
○ Стек растёт вниз (в сторону уменьшения адресов)
● Операции над стеком:
○ Push = сдвиг SP + запись в память
○ Pop = сдвиг SP в обратную сторону
○ Выделение памяти = сдвиг SP 9
void func3() {
// Мы здесь
}
void func2() {
func3();
}
void func1() {
func2();
}
void func0() {
func1();
}
Простейший стек вызовов
Адрес возврата в func2()
Адрес возврата в func1()
Адрес возврата в func0()
...
Stack Pointer
10
Стековый кадр
● Адреса возврата
● Сохранённые регистры
● Локальные переменные
● Аргументы функции
Локальные переменные func3()
Сохранённые регистры func3()
Адрес возврата в func2()
Аргументы для func3()
Локальные переменные func2()
Сохранённые регистры func2()
Адрес возврата в func1()
Аргументы для func3()
...
Stack Pointer
func3()
func2()
11
Соглашение вызова (calling convention)
● Как передаются аргументы?
○ Регистры?
○ Стек?
○ В каком порядке?
● Кто очищает стек от аргументов?
○ Вызывающая функция? (caller)
○ Вызываемая функция? (callee)
● Как возвращается результат?
○ Регистры?
○ Стек?
● Какие регистры необходимо сохранить в стек?
12
● Проход по содержимому стека
● Перебор стековых кадров в порядке, обратном вызову функций
● Логика над полученными данными
Раскрутка стека вызовов (call stack unwinding)
13
Раскрутка стека вызовов (call stack unwinding)
● Проход по содержимому стека
● Перебор стековых кадров в порядке, обратном вызову функций
● Логика над полученными данными
Применение:
● Обработка C++ исключений
● Получение backtrace (stack trace)
○ Отладчики
○ Системы крэш репортов
○ Профилировщики
14
Сложности раскрутки стека
● Разный формат стековых кадров для разных функций:
○ Различное количество аргументов, передаваемых по-разному
○ Различное число локальных переменных
○ Разные регистры сохраняются в стек
15
Сложности раскрутки стека
● Разный формат стековых кадров для разных функций:
○ Различное количество аргументов, передаваемых по-разному
○ Различное число локальных переменных
○ Разные регистры сохраняются в стек
● Зависимость от архитектуры и ABI
○ Разные соглашения вызова для разных функций
16
Сложности раскрутки стека
● Разный формат стековых кадров для разных функций:
○ Различное количество аргументов, передаваемых по-разному
○ Различное число локальных переменных
○ Разные регистры сохраняются в стек
● Зависимость от архитектуры и ABI
○ Разные соглашения вызова для разных функций
● Оптимизации компилятора
17
Способы применения раскрутки стека
● Для текущего запущенного процесса
○ Получение backtrace (boost stacktrace)
○ Создание crash report (signal handler)
18
Способы применения раскрутки стека
● Для текущего запущенного процесса
○ Получение backtrace (boost stacktrace)
○ Создание crash report (signal handler)
● Для другого запущенного процесса (ptrace, process_vm_readv)
○ Отладчики (gdb, lldb)
○ Профилировщики (perf)
19
Способы применения раскрутки стека
● Для текущего запущенного процесса
○ Получение backtrace (boost stacktrace)
○ Создание crash report (signal handler)
● Для другого запущенного процесса (ptrace, process_vm_readv)
○ Отладчики (gdb, lldb)
○ Профилировщики (perf)
● Для завершенного процесса (postmortem)
○ Отладчик + core dump
○ Google breakpad / crashpad
20
Раскрутка стека в
деталях
Разбор алгоритма
21
● Stack pointer (SP, ESP, RSP)
○ Вершина стека.
○ Может меняться во время исполнения функции
Регистры
22
Регистры
● Stack pointer (SP, ESP, RSP)
○ Вершина стека.
○ Может меняться во время исполнения функции
● Frame pointer, Base pointer (FP, EBP, RBP):
○ Используется для адресации локальных переменных
○ Указывает на начало стекового кадра текущей функции
○ Не меняется во время исполнения функции
○ Может не использоваться (-fomit-frame-pointer)
23
● Stack pointer (SP, ESP, RSP)
○ Вершина стека.
○ Может меняться во время исполнения функции
● Frame pointer, Base pointer (FP, EBP, RBP):
○ Используется для адресации локальных переменных
○ Указывает на начало стекового кадра текущей функции
○ Не меняется во время исполнения функции
○ Может не использоваться (-fomit-frame-pointer)
● Instruction pointer, program counter (PC, IP, EIP, RIP)
○ Указывает на исполняемую инструкцию.
Регистры
24
● Stack pointer (SP, ESP, RSP)
○ Вершина стека.
○ Может меняться во время исполнения функции
● Frame pointer, Base pointer (FP, EBP, RBP):
○ Используется для адресации локальных переменных
○ Указывает на начало стекового кадра текущей функции
○ Не меняется во время исполнения функции
○ Может не использоваться (-fomit-frame-pointer)
● Instruction pointer, program counter (PC, IP, EIP, RIP)
○ Указывает на исполняемую инструкцию.
● Другие регистры в зависимости от архитектуры
○ Link Register (LR) - адрес возврата (ARM 32-bit)
Регистры
25
Виртуальная раскрутка стека (Virtual Unwinding)
26
● Виртуальные регистры (VRs):
○ Копия (snapshot) значений регистров в памяти
○ Все манипуляции происходят с копией
○ Значения извлекаются из стека
Виртуальная раскрутка стека (Virtual Unwinding)
27
● Виртуальные регистры (VRs):
○ Копия (snapshot) значений регистров в памяти
○ Все манипуляции происходят с копией
○ Значения извлекаются из стека
● Доступ к памяти стека:
○ Стековые регистры (SP, FP) содержат адреса элементов стека
○ Чтение - разыменование указателей
Виртуальная раскрутка стека (Virtual Unwinding)
28
● Виртуальные регистры (VRs):
○ Копия (snapshot) значений регистров в памяти
○ Все манипуляции происходят с копией
○ Значения извлекаются из стека
● Доступ к памяти стека:
○ Стековые регистры (SP, FP) содержат адреса элементов стека
○ Чтение - разыменование указателей
● Стек “заморожен”, пока выполняется раскрутка
○ Не можем выйти из функции, пока продолжается раскрутка (текущий поток)
○ Выполнение потока приостановлено (другой поток / процесс)
1. Получаем исходные данные - значения регистров (ip, sp, fp)
2. Выполняем логику над значениями регистров
3. Считываем предыдущий стековый кадр и восстанавливаем
значения регистров для предыдущего стекового кадра
4. Зацикливаем пункт 2
Общий алгоритм раскрутки стека
29
Алгоритм №0
ABI с использованием Frame Pointer
30
ABI с Frame Pointer
31
ABI с Frame Pointer
Локальные переменные func3()
Frame Pointer func2()
Адрес возврата в func2()
Аргументы func3()
Локальные переменные func2()
Frame Pointer func1()
Адрес возврата в func1()
Аргументы func2()
Локальные переменные func0()
Frame Pointer func0()
Адрес возврата
Stack Pointer
Frame Pointer
● Пролог функции сохраняет
предыдущее значение frame
pointer в стеке после адреса
возврата
● Раскрутка стека - проход по
односвязному списку
● Флаг -fno-omit-frame-pointer
● Используется на платформах
Apple
32
ABI с Frame Pointer
Алгоритм раскрутки стека
1. Получаем исходные данные - значения регистров (ip, sp, fp)
2. Выполняем логику над значениями регистров
3. Считываем адрес возврата, Instruction Pointer = *(FP - 2)
4. Считываем предыдущее значение Frame Pointer = *(FP - 1)
5. Зацикливаем пункт 2
33
ABI с Frame Pointer
Преимущества:
● Простота реализации
● Скорость раскрутки стека
Недостатки:
● Дополнительные накладные расходы на вызов функций
● Ограничение возможности оптимизации кода
34
ABI без Frame Pointer
35
Алгоритм №1
Таблицы раскрутки стека
36
Таблицы раскрутки стека
● Секции с дополнительной информацией
● Содержат инструкции раскрутки стека
Форматы:
● DWARF
● ARM EXIDX (32-bit)
● Windows x64 .pdata
○ RUNTIME_FUNCTION
○ UNWIND_INFO
37
Недостатки:
● Необходимость в дополнительных данных
● Скорость раскрутки стека ниже
Преимущества:
● Свобода выбора ABI и соглашения вызова
● Нет ограничений по оптимизации кода
Таблицы раскрутки стека
38
DWARF
● Стандарт http://www.dwarfstd.org/doc/DWARF5.pdf
● Раздел 6.4 “Call Frame Information”
● ELF секция .eh_frame или .debug_frame
● Таблица бинарного поиска - ELF секция .eh_frame_hdr
39
Canonical Frame Address (CFA)
An area of memory that is allocated on a stack called a “call frame.” The call
frame is identified by an address on the stack. We refer to this address as
the Canonical Frame Address or CFA. Typically, the CFA is defined to be the
value of the stack pointer at the call site in the previous frame (which may be
different from its value on entry to the current frame).
http://www.dwarfstd.org/doc/DWARF5.pdf § 6.4
40
Canonical Frame Address (CFA)
41
● Значение Stack Pointer на момент исполнения
инструкции call
● Canonical Frame Address ≈ Frame Pointer
DWARF, § 6.4.1
Abstractly, this mechanism describes a very large table that has the following
structure:
The first column indicates an address for every location that contains code in a
program. (In shared object files, this is an object-relative offset.) The remaining
columns contain virtual unwinding rules that are associated with the indicated location.
LOC CFA R0 R1 ... RN
L0
L1
...
LN
42
DWARF
● Компактный бинарный формат
43
DWARF
● Компактный бинарный формат
● 2 типа записей
44
DWARF
● Компактный бинарный формат
● 2 типа записей
● Frame Description Entry (FDE)
○ Одна запись на функцию
○ Содержит инструкции добавления строк в таблицу и заполнения ячеек
○ Может содержать указатель на LSDA (запись в секции .gcc_except_table) для
обработки C++ исключений
45
DWARF
● Компактный бинарный формат
● 2 типа записей
● Frame Description Entry (FDE)
○ Одна запись на функцию
○ Содержит инструкции добавления строк в таблицу и заполнения ячеек
○ Может содержать указатель на LSDA (запись в секции .gcc_except_table) для
обработки C++ исключений
● Common Information Entry (CIE)
○ Общая для нескольких FDE
○ Содержит общие параметры для всех связанных FDE
○ Может содержать указатель на personality routine для обработки C++
исключений
46
DWARF CIE
$ readelf --debug-dump=frames elf_file
...
00000030 0000000000000014 00000000 CIE
Version: 1
Augmentation: "zR"
Code alignment factor: 1
Data alignment factor: -8
Return address column: 16
Augmentation data: 1b
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_offset: r16 (rip) at cfa-8
DW_CFA_nop
DW_CFA_nop
...
47
DWARF FDE
readelf --debug-dump=frames elf_file
...
000000b0 0000000000000024 00000084 FDE cie=00000030
pc=00000000000015d0..000000000000187e
DW_CFA_advance_loc: 1 to 00000000000015d1
DW_CFA_def_cfa_offset: 16
DW_CFA_offset: r6 (rbp) at cfa-16
DW_CFA_advance_loc: 3 to 00000000000015d4
DW_CFA_def_cfa_register: r6 (rbp)
DW_CFA_advance_loc: 10 to 00000000000015de
DW_CFA_offset: r12 (r12) at cfa-24
DW_CFA_offset: r3 (rbx) at cfa-32
DW_CFA_advance_loc2: 671 to 000000000000187d
DW_CFA_def_cfa: r7 (rsp) ofs 8
DW_CFA_nop
...
48
DWARF FDE Interpreted
readelf --debug-dump=frames-interp elf_file
...
000000b0 0000000000000024 00000084 FDE cie=00000030
pc=00000000000015d0..000000000000187e
LOC CFA rbx rbp r12 ra
00000000000015d0 rsp+8 u u u c-8
00000000000015d1 rsp+16 u c-16 u c-8
00000000000015d4 rbp+16 u c-16 u c-8
00000000000015de rbp+16 c-32 c-16 c-24 c-8
000000000000187d rsp+8 c-32 c-16 c-24 c-8
...
49
DWARF CIE Interpreted
$ readelf --debug-dump=frames-interp elf_file
...
00000030 0000000000000014 00000000 CIE "zR" cf=1 df=-8 ra=16
LOC CFA ra
0000000000000000 rsp+8 c-8
...
50
DWARF
$ objdump -d -S elf_file
00000000000015d0 <_Z5func2fRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>:
15d0: 55 push %rbp
15d1: 48 89 e5 mov %rsp,%rbp
15d4: 41 54 push %r12
15d6: 53 push %rbx
15d7: 48 81 ec 70 10 00 00 sub $0x1070,%rsp
15de: f3 0f 11 85 8c ef ff movss %xmm0,-0x1074(%rbp)
15e5: ff
15e6: 48 89 bd 80 ef ff ff mov %rdi,-0x1080(%rbp)
15ed: 48 8d 85 d0 f7 ff ff lea -0x830(%rbp),%rax
15f4: be 00 01 00 00 mov $0x100,%esi
15f9: 48 89 c7 mov %rax,%rdi
15fc: e8 bf fc ff ff callq 12c0 <backtrace@plt>
1601: 89 45 e4 mov %eax,-0x1c(%rbp)
1604: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%rbp)
...
51
DWARF
Алгоритм раскрутки стека
1. Получаем исходные данные - значения регистров (ip, sp, fp)
2. Выполняем логику над значениями регистров
3. Ищем запись (FDE) по значению регистра Instruction pointer
(Program counter) в .eh_frame (.debug_frame)
4. Восстанавливаем значения регистров для предыдущего стекового
кадра по инструкциям из FDE
5. Зацикливаем пункт 2
52
Флаги
компилятора
53
Флаги компилятора (оптимизация)
Влияют на создание стекового кадра при вызове:
● -foptimize-sibling-calls / -fno-optimize-sibling-calls
● -finline / -fno-inline
Влияют на возможность раскрутки стека:
● -fexceptions, -funwind-tables / -fno-exceptions, -fno-unwind-tables
● -fomit-frame-pointer / -fno-omit-frame-pointer
54
Готовые
библиотеки
55
libc
https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
● Функция backtrace(void** array, int size)
● Содержится в большинстве реализаций libc
● Возвращает адреса возврата
56
libc backtrace
#include <execinfo.h>
void *backtrace_buffer[256];
const int backtrace_size = backtrace(backtrace_buffer, 256);
for (int i = 0; i < backtrace_size; ++i) {
void * const program_counter = backtrace_buffer[i];
cout << program_counter;
Dl_info dl_info;
if (dladdr(program_counter, &dl_info) && dl_info.dli_sname) {
cout << " " << dl_info.dli_sname << " + " << (intptr_t)program_counter -
(intptr_t)dl_info.dli_saddr;
}
cout << endl;
}
57
https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-
generic/baselib--unwind-backtrace.html
● Библиотека компилятора, используемая для обработки C++
исключений
● Функция _Unwind_Backtrace
С++ ABI
58
С++ ABI
#include <unwind.h>
_Unwind_Reason_Code unwind_function(_Unwind_Context *context, void *arg) {
_Unwind_Ptr program_counter = _Unwind_GetIP(context);
cout << reinterpret_cast<void *>(program_counter);
Dl_info dl_info;
if (dladdr(reinterpret_cast<void *>(program_counter), &dl_info) &&
dl_info.dli_sname) {
cout << " " << dl_info.dli_sname << " + " << program_counter -
reinterpret_cast<_Unwind_Ptr>(dl_info.dli_saddr);
}
cout << endl;
return _URC_NO_REASON;
}
...
_Unwind_Backtrace(&unwind_function, NULL);
59
libunwind
https://www.nongnu.org/libunwind
https://github.com/libunwind/libunwind
● Платформы: Linux, FreeBSD, HP-UX
● Язык: C
● Множество архитектур
60
libunwind
#include <libunwind.h>
unw_context_t unwind_context;
unw_getcontext(&unwind_context); // Сохраняем состояние процессора (виртуальные регистры)
unw_cursor_t unwind_cursor; // Инициализируем курсор
if (!unw_init_local(&unwind_cursor, &unwind_context)) {
for (;;) {
// Получаем значение счётчика команд (program counter, instruction pointer)
unw_word_t program_counter;
if (unw_get_reg(&unwind_cursor, UNW_REG_IP, &program_counter)) break;
cout << reinterpret_cast<void *>(program_counter);
// Получаем имя функции и смещение инструкции внутри функции
unw_word_t function_offset;
char function_name[128];
if (!unw_get_proc_name(&unwind_cursor, function_name, sizeof(function_name), &function_offset)) {
cout << " " << function_name << " + " << function_offset;
}
cout << endl;
if (unw_step(&unwind_cursor) <= 0) break;
}
}
61
Windows
● CaptureStackBackTrace https://msdn.microsoft.com/ru-
RU/library/windows/desktop/bb204633
● StackWalk https://docs.microsoft.com/en-
us/windows/desktop/api/dbghelp/nf-dbghelp-stackwalk
● RtlVirtualUnwind (64-bit) https://docs.microsoft.com/en-
us/windows/desktop/api/winnt/nf-winnt-rtlvirtualunwind
62
Спасибо за внимание
Ссылки:
● http://www.dwarfstd.org/doc/DWARF5.pdf раздел 6.4
● https://itanium-cxx-abi.github.io/cxx-abi/abi.html
Контакты:
● E-mail: ivantrue@gmail.com
● Skype: ivan_arh
● Telegram: @ivanarh
● Github: https://github.com/ivanarh
63

More Related Content

What's hot

024
024024
024JIuc
 
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
corehard_by
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
Mikhail Kurnosov
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...Mikhail Kurnosov
 
023
023023
023JIuc
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
a15464321646213
 
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX ThreadsПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
Alexey Paznikov
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Mikhail Kurnosov
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
Alexey Paznikov
 
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до ZSECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
SECON
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
Alexey Paznikov
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Mikhail Kurnosov
 
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
Roman Tsisyk
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Alexey Paznikov
 
C:\fakepath\кмсзи экз
C:\fakepath\кмсзи   экзC:\fakepath\кмсзи   экз
C:\fakepath\кмсзи экз
darina andr
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
DefconRussia
 
Лекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и HiveЛекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и Hive
Technopark
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
Alexey Paznikov
 

What's hot (20)

024
024024
024
 
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
Шаблоны C++ и базы данных. Сергей Федоров. CoreHard Spring 2019
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...Использование Time-Stamp Counter для измерения времени выполнения кода  на пр...
Использование Time-Stamp Counter для измерения времени выполнения кода на пр...
 
023
023023
023
 
Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...Архитектура и программирование потоковых многоядерных процессоров для научных...
Архитектура и программирование потоковых многоядерных процессоров для научных...
 
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX ThreadsПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до ZSECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
SECON'2016. Кочков Антон, Рютин Борис, Radare2 - от A до Z
 
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
ПВТ - весна 2015 - Лекция 1. Актуальность параллельных вычислений. Анализ пар...
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
 
C:\fakepath\кмсзи экз
C:\fakepath\кмсзи   экзC:\fakepath\кмсзи   экз
C:\fakepath\кмсзи экз
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
 
Лекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и HiveЛекция 7. Введение в Pig и Hive
Лекция 7. Введение в Pig и Hive
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 

Similar to Раскручиваем стек. Иван Пономарев. CoreHard Spring 2019

Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Лекция №3 Организация ЭВМ и систем
Лекция №3 Организация ЭВМ и системЛекция №3 Организация ЭВМ и систем
Лекция №3 Организация ЭВМ и системpianist2317
 
Лекция № 3 Организация ЭВМ и систем
Лекция № 3 Организация ЭВМ и системЛекция № 3 Организация ЭВМ и систем
Лекция № 3 Организация ЭВМ и систем
Александр Силантьев
 
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...Mikhail Kurnosov
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
Ontico
 
prezlec_Історія.ppt
prezlec_Історія.pptprezlec_Історія.ppt
prezlec_Історія.ppt
ssusere2bc36
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаPositive Hack Days
 
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ontico
 
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
corehard_by
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кода
Anastasia Lubennikova
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3it-people
 
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Ontico
 
025
025025
025JIuc
 
Обзор современных микроконтроллеров и их архитектур
Обзор современных микроконтроллеров и их архитектурОбзор современных микроконтроллеров и их архитектур
Обзор современных микроконтроллеров и их архитектур
IoT Community
 
Бинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVMБинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVM
SmartDec
 
Бинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVMБинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVM
Positive Hack Days
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Tanya Denisyuk
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
Smolensk Computer Science Club
 
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Ontico
 

Similar to Раскручиваем стек. Иван Пономарев. CoreHard Spring 2019 (20)

Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Лекция №3 Организация ЭВМ и систем
Лекция №3 Организация ЭВМ и системЛекция №3 Организация ЭВМ и систем
Лекция №3 Организация ЭВМ и систем
 
Лекция № 3 Организация ЭВМ и систем
Лекция № 3 Организация ЭВМ и системЛекция № 3 Организация ЭВМ и систем
Лекция № 3 Организация ЭВМ и систем
 
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...
Лекция 2: Оптимизация ветвлений и циклов (Branch prediction and loops optimiz...
 
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
BigMemory - работа с сотнями миллионов бизнес-объектов / Дмитрий Хмаладзе (Ag...
 
prezlec_Історія.ppt
prezlec_Історія.pptprezlec_Історія.ppt
prezlec_Історія.ppt
 
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кодаРазвитие технологий генерации эксплойтов на основе анализа бинарного кода
Развитие технологий генерации эксплойтов на основе анализа бинарного кода
 
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
Ликбез по Эльбрусу, Константин Трушкин (МЦСТ)
 
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
Жилье комфорт-класса для акторов и хендлеров. Максим Хижинский. CoreHard Spri...
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кода
 
ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3ekbpy'2012 - Михаил Коробов - Python 3
ekbpy'2012 - Михаил Коробов - Python 3
 
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
Как обслужить 60 миллионов абонентов, Артем Руфанов (ПЕТЕР-СЕРВИС)
 
025
025025
025
 
Обзор современных микроконтроллеров и их архитектур
Обзор современных микроконтроллеров и их архитектурОбзор современных микроконтроллеров и их архитектур
Обзор современных микроконтроллеров и их архитектур
 
Бинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVMБинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVM
 
Бинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVMБинарный анализ с декомпиляцией и LLVM
Бинарный анализ с декомпиляцией и LLVM
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
 
CUDA Best Practices (2-3)
CUDA Best Practices (2-3)CUDA Best Practices (2-3)
CUDA Best Practices (2-3)
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
Оптимизация программ для современных процессоров и Linux, Александр Крижановс...
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
corehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
corehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
corehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
corehard_by
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
corehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
corehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
corehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
corehard_by
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan ČukićC++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 

Раскручиваем стек. Иван Пономарев. CoreHard Spring 2019

  • 3. Стек вызовов LIFO структура данных, хранящая адреса возврата в подпрограммы 3
  • 4. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) 4
  • 5. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) ● Выделяется: ○ Ядром ОС (для главного потока) ○ Внутри процесса при создании потока (pthread) 5
  • 6. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) ● Выделяется: ○ Ядром ОС (для главного потока) ○ Внутри процесса при создании потока (pthread) ● Вершина стека - регистр Stack Pointer (SP, ESP, RSP) 6
  • 7. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) ● Выделяется: ○ Ядром ОС (для главного потока) ○ Внутри процесса при создании потока (pthread) ● Вершина стека - регистр Stack Pointer (SP, ESP, RSP) ● Размер элемента - машинное слово 7
  • 8. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) ● Выделяется: ○ Ядром ОС (для главного потока) ○ Внутри процесса при создании потока (pthread) ● Вершина стека - регистр Stack Pointer (SP, ESP, RSP) ● Размер элемента - машинное слово ● Наиболее популярен Full Descending стек ○ Stack Pointer указывает на элемент, находящийся на вершине стека ○ Стек растёт вниз (в сторону уменьшения адресов) 8
  • 9. Как работает стек вызовов ● Стек - область памяти, уникальная для каждого потока (thread) ● Выделяется: ○ Ядром ОС (для главного потока) ○ Внутри процесса при создании потока (pthread) ● Вершина стека - регистр Stack Pointer (SP, ESP, RSP) ● Размер элемента - машинное слово ● Наиболее популярен Full Descending стек ○ Stack Pointer указывает на элемент, находящийся на вершине стека ○ Стек растёт вниз (в сторону уменьшения адресов) ● Операции над стеком: ○ Push = сдвиг SP + запись в память ○ Pop = сдвиг SP в обратную сторону ○ Выделение памяти = сдвиг SP 9
  • 10. void func3() { // Мы здесь } void func2() { func3(); } void func1() { func2(); } void func0() { func1(); } Простейший стек вызовов Адрес возврата в func2() Адрес возврата в func1() Адрес возврата в func0() ... Stack Pointer 10
  • 11. Стековый кадр ● Адреса возврата ● Сохранённые регистры ● Локальные переменные ● Аргументы функции Локальные переменные func3() Сохранённые регистры func3() Адрес возврата в func2() Аргументы для func3() Локальные переменные func2() Сохранённые регистры func2() Адрес возврата в func1() Аргументы для func3() ... Stack Pointer func3() func2() 11
  • 12. Соглашение вызова (calling convention) ● Как передаются аргументы? ○ Регистры? ○ Стек? ○ В каком порядке? ● Кто очищает стек от аргументов? ○ Вызывающая функция? (caller) ○ Вызываемая функция? (callee) ● Как возвращается результат? ○ Регистры? ○ Стек? ● Какие регистры необходимо сохранить в стек? 12
  • 13. ● Проход по содержимому стека ● Перебор стековых кадров в порядке, обратном вызову функций ● Логика над полученными данными Раскрутка стека вызовов (call stack unwinding) 13
  • 14. Раскрутка стека вызовов (call stack unwinding) ● Проход по содержимому стека ● Перебор стековых кадров в порядке, обратном вызову функций ● Логика над полученными данными Применение: ● Обработка C++ исключений ● Получение backtrace (stack trace) ○ Отладчики ○ Системы крэш репортов ○ Профилировщики 14
  • 15. Сложности раскрутки стека ● Разный формат стековых кадров для разных функций: ○ Различное количество аргументов, передаваемых по-разному ○ Различное число локальных переменных ○ Разные регистры сохраняются в стек 15
  • 16. Сложности раскрутки стека ● Разный формат стековых кадров для разных функций: ○ Различное количество аргументов, передаваемых по-разному ○ Различное число локальных переменных ○ Разные регистры сохраняются в стек ● Зависимость от архитектуры и ABI ○ Разные соглашения вызова для разных функций 16
  • 17. Сложности раскрутки стека ● Разный формат стековых кадров для разных функций: ○ Различное количество аргументов, передаваемых по-разному ○ Различное число локальных переменных ○ Разные регистры сохраняются в стек ● Зависимость от архитектуры и ABI ○ Разные соглашения вызова для разных функций ● Оптимизации компилятора 17
  • 18. Способы применения раскрутки стека ● Для текущего запущенного процесса ○ Получение backtrace (boost stacktrace) ○ Создание crash report (signal handler) 18
  • 19. Способы применения раскрутки стека ● Для текущего запущенного процесса ○ Получение backtrace (boost stacktrace) ○ Создание crash report (signal handler) ● Для другого запущенного процесса (ptrace, process_vm_readv) ○ Отладчики (gdb, lldb) ○ Профилировщики (perf) 19
  • 20. Способы применения раскрутки стека ● Для текущего запущенного процесса ○ Получение backtrace (boost stacktrace) ○ Создание crash report (signal handler) ● Для другого запущенного процесса (ptrace, process_vm_readv) ○ Отладчики (gdb, lldb) ○ Профилировщики (perf) ● Для завершенного процесса (postmortem) ○ Отладчик + core dump ○ Google breakpad / crashpad 20
  • 22. ● Stack pointer (SP, ESP, RSP) ○ Вершина стека. ○ Может меняться во время исполнения функции Регистры 22
  • 23. Регистры ● Stack pointer (SP, ESP, RSP) ○ Вершина стека. ○ Может меняться во время исполнения функции ● Frame pointer, Base pointer (FP, EBP, RBP): ○ Используется для адресации локальных переменных ○ Указывает на начало стекового кадра текущей функции ○ Не меняется во время исполнения функции ○ Может не использоваться (-fomit-frame-pointer) 23
  • 24. ● Stack pointer (SP, ESP, RSP) ○ Вершина стека. ○ Может меняться во время исполнения функции ● Frame pointer, Base pointer (FP, EBP, RBP): ○ Используется для адресации локальных переменных ○ Указывает на начало стекового кадра текущей функции ○ Не меняется во время исполнения функции ○ Может не использоваться (-fomit-frame-pointer) ● Instruction pointer, program counter (PC, IP, EIP, RIP) ○ Указывает на исполняемую инструкцию. Регистры 24
  • 25. ● Stack pointer (SP, ESP, RSP) ○ Вершина стека. ○ Может меняться во время исполнения функции ● Frame pointer, Base pointer (FP, EBP, RBP): ○ Используется для адресации локальных переменных ○ Указывает на начало стекового кадра текущей функции ○ Не меняется во время исполнения функции ○ Может не использоваться (-fomit-frame-pointer) ● Instruction pointer, program counter (PC, IP, EIP, RIP) ○ Указывает на исполняемую инструкцию. ● Другие регистры в зависимости от архитектуры ○ Link Register (LR) - адрес возврата (ARM 32-bit) Регистры 25
  • 26. Виртуальная раскрутка стека (Virtual Unwinding) 26 ● Виртуальные регистры (VRs): ○ Копия (snapshot) значений регистров в памяти ○ Все манипуляции происходят с копией ○ Значения извлекаются из стека
  • 27. Виртуальная раскрутка стека (Virtual Unwinding) 27 ● Виртуальные регистры (VRs): ○ Копия (snapshot) значений регистров в памяти ○ Все манипуляции происходят с копией ○ Значения извлекаются из стека ● Доступ к памяти стека: ○ Стековые регистры (SP, FP) содержат адреса элементов стека ○ Чтение - разыменование указателей
  • 28. Виртуальная раскрутка стека (Virtual Unwinding) 28 ● Виртуальные регистры (VRs): ○ Копия (snapshot) значений регистров в памяти ○ Все манипуляции происходят с копией ○ Значения извлекаются из стека ● Доступ к памяти стека: ○ Стековые регистры (SP, FP) содержат адреса элементов стека ○ Чтение - разыменование указателей ● Стек “заморожен”, пока выполняется раскрутка ○ Не можем выйти из функции, пока продолжается раскрутка (текущий поток) ○ Выполнение потока приостановлено (другой поток / процесс)
  • 29. 1. Получаем исходные данные - значения регистров (ip, sp, fp) 2. Выполняем логику над значениями регистров 3. Считываем предыдущий стековый кадр и восстанавливаем значения регистров для предыдущего стекового кадра 4. Зацикливаем пункт 2 Общий алгоритм раскрутки стека 29
  • 30. Алгоритм №0 ABI с использованием Frame Pointer 30
  • 31. ABI с Frame Pointer 31
  • 32. ABI с Frame Pointer Локальные переменные func3() Frame Pointer func2() Адрес возврата в func2() Аргументы func3() Локальные переменные func2() Frame Pointer func1() Адрес возврата в func1() Аргументы func2() Локальные переменные func0() Frame Pointer func0() Адрес возврата Stack Pointer Frame Pointer ● Пролог функции сохраняет предыдущее значение frame pointer в стеке после адреса возврата ● Раскрутка стека - проход по односвязному списку ● Флаг -fno-omit-frame-pointer ● Используется на платформах Apple 32
  • 33. ABI с Frame Pointer Алгоритм раскрутки стека 1. Получаем исходные данные - значения регистров (ip, sp, fp) 2. Выполняем логику над значениями регистров 3. Считываем адрес возврата, Instruction Pointer = *(FP - 2) 4. Считываем предыдущее значение Frame Pointer = *(FP - 1) 5. Зацикливаем пункт 2 33
  • 34. ABI с Frame Pointer Преимущества: ● Простота реализации ● Скорость раскрутки стека Недостатки: ● Дополнительные накладные расходы на вызов функций ● Ограничение возможности оптимизации кода 34
  • 35. ABI без Frame Pointer 35
  • 37. Таблицы раскрутки стека ● Секции с дополнительной информацией ● Содержат инструкции раскрутки стека Форматы: ● DWARF ● ARM EXIDX (32-bit) ● Windows x64 .pdata ○ RUNTIME_FUNCTION ○ UNWIND_INFO 37
  • 38. Недостатки: ● Необходимость в дополнительных данных ● Скорость раскрутки стека ниже Преимущества: ● Свобода выбора ABI и соглашения вызова ● Нет ограничений по оптимизации кода Таблицы раскрутки стека 38
  • 39. DWARF ● Стандарт http://www.dwarfstd.org/doc/DWARF5.pdf ● Раздел 6.4 “Call Frame Information” ● ELF секция .eh_frame или .debug_frame ● Таблица бинарного поиска - ELF секция .eh_frame_hdr 39
  • 40. Canonical Frame Address (CFA) An area of memory that is allocated on a stack called a “call frame.” The call frame is identified by an address on the stack. We refer to this address as the Canonical Frame Address or CFA. Typically, the CFA is defined to be the value of the stack pointer at the call site in the previous frame (which may be different from its value on entry to the current frame). http://www.dwarfstd.org/doc/DWARF5.pdf § 6.4 40
  • 41. Canonical Frame Address (CFA) 41 ● Значение Stack Pointer на момент исполнения инструкции call ● Canonical Frame Address ≈ Frame Pointer
  • 42. DWARF, § 6.4.1 Abstractly, this mechanism describes a very large table that has the following structure: The first column indicates an address for every location that contains code in a program. (In shared object files, this is an object-relative offset.) The remaining columns contain virtual unwinding rules that are associated with the indicated location. LOC CFA R0 R1 ... RN L0 L1 ... LN 42
  • 44. DWARF ● Компактный бинарный формат ● 2 типа записей 44
  • 45. DWARF ● Компактный бинарный формат ● 2 типа записей ● Frame Description Entry (FDE) ○ Одна запись на функцию ○ Содержит инструкции добавления строк в таблицу и заполнения ячеек ○ Может содержать указатель на LSDA (запись в секции .gcc_except_table) для обработки C++ исключений 45
  • 46. DWARF ● Компактный бинарный формат ● 2 типа записей ● Frame Description Entry (FDE) ○ Одна запись на функцию ○ Содержит инструкции добавления строк в таблицу и заполнения ячеек ○ Может содержать указатель на LSDA (запись в секции .gcc_except_table) для обработки C++ исключений ● Common Information Entry (CIE) ○ Общая для нескольких FDE ○ Содержит общие параметры для всех связанных FDE ○ Может содержать указатель на personality routine для обработки C++ исключений 46
  • 47. DWARF CIE $ readelf --debug-dump=frames elf_file ... 00000030 0000000000000014 00000000 CIE Version: 1 Augmentation: "zR" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16 Augmentation data: 1b DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_offset: r16 (rip) at cfa-8 DW_CFA_nop DW_CFA_nop ... 47
  • 48. DWARF FDE readelf --debug-dump=frames elf_file ... 000000b0 0000000000000024 00000084 FDE cie=00000030 pc=00000000000015d0..000000000000187e DW_CFA_advance_loc: 1 to 00000000000015d1 DW_CFA_def_cfa_offset: 16 DW_CFA_offset: r6 (rbp) at cfa-16 DW_CFA_advance_loc: 3 to 00000000000015d4 DW_CFA_def_cfa_register: r6 (rbp) DW_CFA_advance_loc: 10 to 00000000000015de DW_CFA_offset: r12 (r12) at cfa-24 DW_CFA_offset: r3 (rbx) at cfa-32 DW_CFA_advance_loc2: 671 to 000000000000187d DW_CFA_def_cfa: r7 (rsp) ofs 8 DW_CFA_nop ... 48
  • 49. DWARF FDE Interpreted readelf --debug-dump=frames-interp elf_file ... 000000b0 0000000000000024 00000084 FDE cie=00000030 pc=00000000000015d0..000000000000187e LOC CFA rbx rbp r12 ra 00000000000015d0 rsp+8 u u u c-8 00000000000015d1 rsp+16 u c-16 u c-8 00000000000015d4 rbp+16 u c-16 u c-8 00000000000015de rbp+16 c-32 c-16 c-24 c-8 000000000000187d rsp+8 c-32 c-16 c-24 c-8 ... 49
  • 50. DWARF CIE Interpreted $ readelf --debug-dump=frames-interp elf_file ... 00000030 0000000000000014 00000000 CIE "zR" cf=1 df=-8 ra=16 LOC CFA ra 0000000000000000 rsp+8 c-8 ... 50
  • 51. DWARF $ objdump -d -S elf_file 00000000000015d0 <_Z5func2fRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE>: 15d0: 55 push %rbp 15d1: 48 89 e5 mov %rsp,%rbp 15d4: 41 54 push %r12 15d6: 53 push %rbx 15d7: 48 81 ec 70 10 00 00 sub $0x1070,%rsp 15de: f3 0f 11 85 8c ef ff movss %xmm0,-0x1074(%rbp) 15e5: ff 15e6: 48 89 bd 80 ef ff ff mov %rdi,-0x1080(%rbp) 15ed: 48 8d 85 d0 f7 ff ff lea -0x830(%rbp),%rax 15f4: be 00 01 00 00 mov $0x100,%esi 15f9: 48 89 c7 mov %rax,%rdi 15fc: e8 bf fc ff ff callq 12c0 <backtrace@plt> 1601: 89 45 e4 mov %eax,-0x1c(%rbp) 1604: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%rbp) ... 51
  • 52. DWARF Алгоритм раскрутки стека 1. Получаем исходные данные - значения регистров (ip, sp, fp) 2. Выполняем логику над значениями регистров 3. Ищем запись (FDE) по значению регистра Instruction pointer (Program counter) в .eh_frame (.debug_frame) 4. Восстанавливаем значения регистров для предыдущего стекового кадра по инструкциям из FDE 5. Зацикливаем пункт 2 52
  • 54. Флаги компилятора (оптимизация) Влияют на создание стекового кадра при вызове: ● -foptimize-sibling-calls / -fno-optimize-sibling-calls ● -finline / -fno-inline Влияют на возможность раскрутки стека: ● -fexceptions, -funwind-tables / -fno-exceptions, -fno-unwind-tables ● -fomit-frame-pointer / -fno-omit-frame-pointer 54
  • 56. libc https://www.gnu.org/software/libc/manual/html_node/Backtraces.html ● Функция backtrace(void** array, int size) ● Содержится в большинстве реализаций libc ● Возвращает адреса возврата 56
  • 57. libc backtrace #include <execinfo.h> void *backtrace_buffer[256]; const int backtrace_size = backtrace(backtrace_buffer, 256); for (int i = 0; i < backtrace_size; ++i) { void * const program_counter = backtrace_buffer[i]; cout << program_counter; Dl_info dl_info; if (dladdr(program_counter, &dl_info) && dl_info.dli_sname) { cout << " " << dl_info.dli_sname << " + " << (intptr_t)program_counter - (intptr_t)dl_info.dli_saddr; } cout << endl; } 57
  • 59. С++ ABI #include <unwind.h> _Unwind_Reason_Code unwind_function(_Unwind_Context *context, void *arg) { _Unwind_Ptr program_counter = _Unwind_GetIP(context); cout << reinterpret_cast<void *>(program_counter); Dl_info dl_info; if (dladdr(reinterpret_cast<void *>(program_counter), &dl_info) && dl_info.dli_sname) { cout << " " << dl_info.dli_sname << " + " << program_counter - reinterpret_cast<_Unwind_Ptr>(dl_info.dli_saddr); } cout << endl; return _URC_NO_REASON; } ... _Unwind_Backtrace(&unwind_function, NULL); 59
  • 60. libunwind https://www.nongnu.org/libunwind https://github.com/libunwind/libunwind ● Платформы: Linux, FreeBSD, HP-UX ● Язык: C ● Множество архитектур 60
  • 61. libunwind #include <libunwind.h> unw_context_t unwind_context; unw_getcontext(&unwind_context); // Сохраняем состояние процессора (виртуальные регистры) unw_cursor_t unwind_cursor; // Инициализируем курсор if (!unw_init_local(&unwind_cursor, &unwind_context)) { for (;;) { // Получаем значение счётчика команд (program counter, instruction pointer) unw_word_t program_counter; if (unw_get_reg(&unwind_cursor, UNW_REG_IP, &program_counter)) break; cout << reinterpret_cast<void *>(program_counter); // Получаем имя функции и смещение инструкции внутри функции unw_word_t function_offset; char function_name[128]; if (!unw_get_proc_name(&unwind_cursor, function_name, sizeof(function_name), &function_offset)) { cout << " " << function_name << " + " << function_offset; } cout << endl; if (unw_step(&unwind_cursor) <= 0) break; } } 61
  • 62. Windows ● CaptureStackBackTrace https://msdn.microsoft.com/ru- RU/library/windows/desktop/bb204633 ● StackWalk https://docs.microsoft.com/en- us/windows/desktop/api/dbghelp/nf-dbghelp-stackwalk ● RtlVirtualUnwind (64-bit) https://docs.microsoft.com/en- us/windows/desktop/api/winnt/nf-winnt-rtlvirtualunwind 62
  • 63. Спасибо за внимание Ссылки: ● http://www.dwarfstd.org/doc/DWARF5.pdf раздел 6.4 ● https://itanium-cxx-abi.github.io/cxx-abi/abi.html Контакты: ● E-mail: ivantrue@gmail.com ● Skype: ivan_arh ● Telegram: @ivanarh ● Github: https://github.com/ivanarh 63