# Hitchhiker's Guide to C++ in Arcadia: Exceptions

![](../img/dont_panic.png)

## Больше информации об unhandled exception
По умолчанию, если программа падает из-за не обработанного исключения, из полезной информации остается максимум `what()` из `std::exception`.

В Аркадии есть библиотека, призванная улучшить эту ситуацию: `library/cpp/terminate_handler`. Достаточно подключить ее в `PEERDIR` своей программы, и она добавит обработчик `std::terminate`, который выведет не только текст исключения, но и стек вызовов c названиями функций в момент падения.
Часто это помогает понять с одного взгляда, что пошло не так, даже не открывая дебагер.

## Информация о стеке вызовов между `throw` и `catch`
Есть метод [TBackTrace::FromCurrentException](https://arcanum.yandex-team.ru/arc_vcs/util/system/backtrace.cpp?rev=r9278850#L298), который возвращает этот кусочек стектрейса. Он доступен на x86_64 Linux и работает для всех исключений.
Для этого сделана поддержка сбора адресов функций при раскрутке стека в `libunwind`. Сами адреса хранятся в буфере, который выделяется перед объектом `__cxa_exception`.

  * При `catch (...) { throw; }` история стека сохраняется.
  * При `catch (...) { std::rethrow_exception(std::current_exception()); }` история тоже сохраняется, но только один раз. Точнее так: история сохраняется от `throw` до первого `std::current_exception()` и от последнего `std::rethrow_exception()` до последнего `catch`. История во премя промежуточных перебрасываний теряется, это пока ограничение метода.
     Это вызвано тем, что при каждом `std::rethrow_exception` создается новый `__cxa_dependent_exception`, в котором находит отдельный буфер backtrace'а. При получении backtrace'а мы можем склеить несколько буферов, но нам доступны только буфер от исходно исключения и от последнего dependent. Возможно, в будущем мы придумаем, как обойти это ограничение.

Также есть метод [FormatCurrentException](https://arcanum.yandex-team.ru/arc_vcs/util/generic/yexception.h?rev=r9278850#L168), форматирующий текущее исключение, выводя сообщение исключения и соответствующий ему стектрейс. Его удобно использовать, в случае когда нужно разом вывести всю информацию о возникшем исключении. Под капотом метод использует `TBackTrace::FromCurrentException`. Вывод стектрейса не гарантируется, поскольку `TBackTrace::FromCurrentException` работает только на x86_64 Linux (флаг `_YNDX_LIBUNWIND_ENABLE_EXCEPTION_BACKTRACE`). На остальных платформах метод будет печатать только сообщение исключения. Стоит использовать данный метод только в целях логирования, поскольку вывод данного метода может меняться. Y_VERIFY в методе проверяет, что он был вызван с существующим исключением, в противном случае вызывает abort.  
У метода есть более эффективный вариант использования [FormatCurrentExceptionTo](https://arcanum.yandex-team.ru/arc_vcs/util/generic/yexception.h?rev=r9278850#L169), который форматирует исключение в IOutputStream вместо аллоцирования строки.
