Подтвердить что ты не робот

Как gcc реализует разворачивание стека для исключений С++ в Linux?

Как gcc реализует развертывание стека для исключений С++ в Linux? В частности, как он узнает, какие деструкторы должны вызывать при разворачивании фрейма (то есть, какая информация хранится и где она хранится)?

4b9b3361

Ответ 1

См. раздел 6.2 x86_64 ABI. Это детализирует интерфейс, но не много базовых данных. Это также не зависит от С++ и может также использоваться для других целей.

В основном есть два раздела двоичного файла ELF, испускаемые gcc, которые представляют интерес для обработки исключений. Они .eh_frame и .gcc_except_table.

.eh_frame следует за форматом DWARF (формат отладки, который в первую очередь входит в игру, когда вы используете gdb). Он имеет тот же формат, что и раздел .debug_frame, который генерируется при компиляции с помощью -g. По существу, он содержит информацию, необходимую для возврата в состояние машинных регистров и стека в любой точке выше стека вызовов. Дополнительную информацию об этом см. В стандарте Dwarf на dwarfstd.org.

.gcc_except_table содержит информацию об обработке "посадочных площадок" обработки исключений в местах расположения обработчиков. Это необходимо, чтобы знать, когда нужно прекратить раскручивание. К сожалению, этот раздел плохо документирован. Единственные фрагменты информации, которую я смог получить, поступают из списка рассылки gcc. См., В частности, этот пост

Остальная часть информации - это то, что фактический код интерпретирует информацию, найденную в этих разделах данных. Соответствующий код живет в libstdС++ и libgcc. В настоящий момент я не могу вспомнить, какие фигуры живут в этом. Интерпретатор для информации кадра вызова DWARF можно найти в исходном коде gcc в файле gcc/unwind-dw.c

Ответ 3

В настоящее время доступно мало документации, однако основная система заключается в том, что GCC переводит блоки try/catch в вызовы функций, а затем ссылки в библиотеке с необходимой поддержкой времени выполнения (документация о древовидной структуре код включает в себя утверждение "бросание исключения не представлено непосредственно в GIMPLE, поскольку оно реализуется вызовом функции" ).

К сожалению, я не знаком с этими функциями и не могу рассказать вам, что посмотреть (кроме источника для libgcc, который включает в себя время выполнения обработки исключений).

Доступен Исключение для новичков.