SlideShare a Scribd company logo
1 of 12
Download to read offline
Исключения в С++
Как это устроено
Подзадачи:
1) Как передать управление
в нужный catch блок
2) Как обустроить раскрутку стека
Архитектура Int FP
x86-32 8 8
x86-64 16 16
IBM/360 16 4
z/Architecture 16 16
Itanium 128 128
SPARC 31 32
IBM Cell 4~16 1~4
IBM POWER 32 32
Power Architecture 32 32
Архитектура Int FP
Alpha 32 32
6502 3 0
W65C816S 5 0
PIC microcontroller 1 0
AVR microcontroller 32 0
ARM 32-bit[5]
16 varies
ARM 64-bit[6]
31 32
PDP-11 6 0
MIPS 31 32
<1>: DW_TAG_subprogram
DW_AT_name = foo
<2>: DW_TAG_variable
DW_AT_name = b
DW_AT_type = <4>
DW_AT_location = (DW_OP_reg0)
<3>: DW_TAG_variable
DW_AT_name = c
DW_AT_type = <4>
DW_AT_location = (DW_OP_fbreg: -12)
<4>: DW_TAG_base_type
DW_AT_name = int
DW_AT_byte_size = 4
DW_AT_encoding = signed
<5>: DW_TAG_variable
DW_AT_name = a
DW_AT_type = <4>
DW_AT_external = 1
DW_AT_location = (DW_OP_addr: 0)
1: int a;
2: void foo()
3: {
4: register int b;
5: int c;
6: }
DWARF:
http://www.dwarfstd.org/doc/Debugging%20using%20DWARF.pdf
0x00000083: TAG_formal_parameter [4]
AT_name( "x" )
AT_decl_file( "test.c" )
AT_decl_line( 1 )
AT_type( {0x0000005f} ( int ) )
AT_location( 0x00000000
0x00000000 - 0x00000003: ecx
0x00000003 - 0x00000018: ecx )
0x00000090: TAG_formal_parameter [4]
AT_name( "y" )
AT_decl_file( "test.c" )
AT_decl_line( 1 )
AT_type( {0x0000005f} ( int ) )
AT_location( 0x0000001e
0x00000000 - 0x00000003: edx
0x00000003 - 0x00000018: edx )
int mult (int x, int y) { return x*y; }dwarfdump:
http://stackoverflow.com/questions/12252176/getting-calling-conventions-from-dwarf-info
http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling
http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling
Раскручиваем стек сами
struct jmp_buf_splice {
jmp_buf_splice ();
~jmp_buf_splice ();
jmp_buf buf_;
jmp_buf_splice *prev_;
unw_item_t objs_;
};
try блок:
static jmp_buf_splice *root_slice_ = NULL;
jmp_buf_splice::jmp_buf_splice ()
{
objs_ = NULL;
prev_ = root_slice_;
root_slice_ = this;
}
jmp_buf_splice::~jmp_buf_splice ()
{
root_slice_ = prev_;
}
struct unw_item_t {
unw_item_t ();
virtual ~unw_item_t ();
void unreg();
unw_item_t *prev_;
};
unw_item_t::unw_item_t ()
{
if (NULL != root_slice_)
{
prev_ = root_slice_->objs_;
root_slice_->objs_ = this;
}
}
unw_item_t::~unw_item_t ()
{
if (NULL != root_slice_ &&
(prev_ != reinterpret_cast <unw_item_t *>(~ 0)))
{
root_slice_->objs_ = prev_;
prev_ = reinterpret_cast <unw_item_t *>(~ 0);
}
}
Само(раз)регистрирующийся элемент:
Собственно раскрутка стека:
int throw_slice ( const char *str)
{
jmp_buf_splice *sl = root_slice_;
unw_item_t *obj = root_slice_->objs_;
while (NULL != obj)
{
unw_item_t *tmp = obj;
obj = obj->prev_;
tmp->~unw_item_t ();
}
longjmp (sl->buf_, int(str));
return 0;
}
Пример
TRY_BLOCK {
vec_deleter_t<_A> da(new _A[3]);
TRY_BLOCK {
THROW_IN_BLOCK("errorn");
std::cerr << "notreachedn";
}
CATCH_BLOCK_FIN {
std::cerr << "." << __exc;
RETHROW_IN_BLOCK;
}
FIN_BLOCK;
std::cerr << "notreachedn";
}
CATCH_BLOCK_FIN {
std::cerr << ".." << __exc;
}
FIN_BLOCK;
A::A(1)
A::A(2)
A::A(3)
.error
A::~A(3)
A::~A(2)
A::~A(1)
..error
Чего не хватает?
● Нельзя бросать исключения в деструкторе
● Потокобезопасность отсутствует
● Экземпляр наследованного от unw_item_t класса может
быть только стековым
● Класс, наследованный от unw_item_t нельзя
агрегировать
● Метод не дружит с аппаратными исключениями
● Удалять брошенный объект-исключение должен тот, кто
его поймал

More Related Content

What's hot

Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 

What's hot (20)

Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
хитрости выведения типов
хитрости выведения типовхитрости выведения типов
хитрости выведения типов
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Когда в C# не хватает C++ . Часть 2.
Когда в C# не хватает C++. Часть 2.Когда в C# не хватает C++. Часть 2.
Когда в C# не хватает C++ . Часть 2.
 
Пояснения к статье про Copy-Paste
Пояснения к статье про Copy-PasteПояснения к статье про Copy-Paste
Пояснения к статье про Copy-Paste
 
Когда в C# не хватает C++
Когда в C# не хватает C++Когда в C# не хватает C++
Когда в C# не хватает C++
 
Когда в C# не хватает C++ . Часть 3.
Когда в C# не хватает C++. Часть 3. Когда в C# не хватает C++. Часть 3.
Когда в C# не хватает C++ . Часть 3.
 

Viewers also liked

HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
Platonov Sergey
 

Viewers also liked (20)

QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практике
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутов
 
HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
 
Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 

Similar to C++ exceptions

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
Andrey Karpov
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
Technopark
 
Разработка приложений для Android на С++. Юрий Береза, Shturmann
Разработка приложений для Android на С++. Юрий Береза, ShturmannРазработка приложений для Android на С++. Юрий Береза, Shturmann
Разработка приложений для Android на С++. Юрий Береза, Shturmann
yaevents
 

Similar to C++ exceptions (20)

20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov20130429 dynamic c_c++_program_analysis-alexey_samsonov
20130429 dynamic c_c++_program_analysis-alexey_samsonov
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)11 встреча — Введение в GPGPU (А. Свириденков)
11 встреча — Введение в GPGPU (А. Свириденков)
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
 
Performance optimization of virtual network infrastructure (RUS, OpenStack Me...
Performance optimization of virtual network infrastructure (RUS, OpenStack Me...Performance optimization of virtual network infrastructure (RUS, OpenStack Me...
Performance optimization of virtual network infrastructure (RUS, OpenStack Me...
 
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)Семинар 5. Многопоточное программирование на OpenMP (часть 5)
Семинар 5. Многопоточное программирование на OpenMP (часть 5)
 
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
Статический анализ и написание качественного кода на C/C++ для встраиваемых с...
 
C++ весна 2014 лекция 2
C++ весна 2014 лекция 2C++ весна 2014 лекция 2
C++ весна 2014 лекция 2
 
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ... Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
 
DSLs in Lisp and Clojure
DSLs in Lisp and ClojureDSLs in Lisp and Clojure
DSLs in Lisp and Clojure
 
введение в Gpu
введение в Gpuвведение в Gpu
введение в Gpu
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Разработка приложений для Android на С++. Юрий Береза, Shturmann
Разработка приложений для Android на С++. Юрий Береза, ShturmannРазработка приложений для Android на С++. Юрий Береза, Shturmann
Разработка приложений для Android на С++. Юрий Береза, Shturmann
 
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
 

More from Platonov Sergey

Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
Platonov Sergey
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
Platonov Sergey
 

More from Platonov Sergey (14)

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система Qt
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratch
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 
Библиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLLБиблиотека Boost с нуля на примере Boost.DLL
Библиотека Boost с нуля на примере Boost.DLL
 
Оптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templatesОптимизация трассирования с использованием Expression templates
Оптимизация трассирования с использованием Expression templates
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 

C++ exceptions

  • 1. Исключения в С++ Как это устроено
  • 2. Подзадачи: 1) Как передать управление в нужный catch блок 2) Как обустроить раскрутку стека
  • 3. Архитектура Int FP x86-32 8 8 x86-64 16 16 IBM/360 16 4 z/Architecture 16 16 Itanium 128 128 SPARC 31 32 IBM Cell 4~16 1~4 IBM POWER 32 32 Power Architecture 32 32 Архитектура Int FP Alpha 32 32 6502 3 0 W65C816S 5 0 PIC microcontroller 1 0 AVR microcontroller 32 0 ARM 32-bit[5] 16 varies ARM 64-bit[6] 31 32 PDP-11 6 0 MIPS 31 32
  • 4. <1>: DW_TAG_subprogram DW_AT_name = foo <2>: DW_TAG_variable DW_AT_name = b DW_AT_type = <4> DW_AT_location = (DW_OP_reg0) <3>: DW_TAG_variable DW_AT_name = c DW_AT_type = <4> DW_AT_location = (DW_OP_fbreg: -12) <4>: DW_TAG_base_type DW_AT_name = int DW_AT_byte_size = 4 DW_AT_encoding = signed <5>: DW_TAG_variable DW_AT_name = a DW_AT_type = <4> DW_AT_external = 1 DW_AT_location = (DW_OP_addr: 0) 1: int a; 2: void foo() 3: { 4: register int b; 5: int c; 6: } DWARF: http://www.dwarfstd.org/doc/Debugging%20using%20DWARF.pdf
  • 5. 0x00000083: TAG_formal_parameter [4] AT_name( "x" ) AT_decl_file( "test.c" ) AT_decl_line( 1 ) AT_type( {0x0000005f} ( int ) ) AT_location( 0x00000000 0x00000000 - 0x00000003: ecx 0x00000003 - 0x00000018: ecx ) 0x00000090: TAG_formal_parameter [4] AT_name( "y" ) AT_decl_file( "test.c" ) AT_decl_line( 1 ) AT_type( {0x0000005f} ( int ) ) AT_location( 0x0000001e 0x00000000 - 0x00000003: edx 0x00000003 - 0x00000018: edx ) int mult (int x, int y) { return x*y; }dwarfdump: http://stackoverflow.com/questions/12252176/getting-calling-conventions-from-dwarf-info
  • 8. Раскручиваем стек сами struct jmp_buf_splice { jmp_buf_splice (); ~jmp_buf_splice (); jmp_buf buf_; jmp_buf_splice *prev_; unw_item_t objs_; }; try блок: static jmp_buf_splice *root_slice_ = NULL; jmp_buf_splice::jmp_buf_splice () { objs_ = NULL; prev_ = root_slice_; root_slice_ = this; } jmp_buf_splice::~jmp_buf_splice () { root_slice_ = prev_; }
  • 9. struct unw_item_t { unw_item_t (); virtual ~unw_item_t (); void unreg(); unw_item_t *prev_; }; unw_item_t::unw_item_t () { if (NULL != root_slice_) { prev_ = root_slice_->objs_; root_slice_->objs_ = this; } } unw_item_t::~unw_item_t () { if (NULL != root_slice_ && (prev_ != reinterpret_cast <unw_item_t *>(~ 0))) { root_slice_->objs_ = prev_; prev_ = reinterpret_cast <unw_item_t *>(~ 0); } } Само(раз)регистрирующийся элемент:
  • 10. Собственно раскрутка стека: int throw_slice ( const char *str) { jmp_buf_splice *sl = root_slice_; unw_item_t *obj = root_slice_->objs_; while (NULL != obj) { unw_item_t *tmp = obj; obj = obj->prev_; tmp->~unw_item_t (); } longjmp (sl->buf_, int(str)); return 0; }
  • 11. Пример TRY_BLOCK { vec_deleter_t<_A> da(new _A[3]); TRY_BLOCK { THROW_IN_BLOCK("errorn"); std::cerr << "notreachedn"; } CATCH_BLOCK_FIN { std::cerr << "." << __exc; RETHROW_IN_BLOCK; } FIN_BLOCK; std::cerr << "notreachedn"; } CATCH_BLOCK_FIN { std::cerr << ".." << __exc; } FIN_BLOCK; A::A(1) A::A(2) A::A(3) .error A::~A(3) A::~A(2) A::~A(1) ..error
  • 12. Чего не хватает? ● Нельзя бросать исключения в деструкторе ● Потокобезопасность отсутствует ● Экземпляр наследованного от unw_item_t класса может быть только стековым ● Класс, наследованный от unw_item_t нельзя агрегировать ● Метод не дружит с аппаратными исключениями ● Удалять брошенный объект-исключение должен тот, кто его поймал