Как обработка исключений C ++ преобразуется в машинный код

Мысленно я всегда задавался вопросом, как выглядит команда try / throw / catch за кулисами, когда C ++ компилирует ее и переводит на ассемблер. Но так как я никогда им не пользуюсь, у меня никогда не было времени проверить это (некоторые люди сказали бы, что это ленивый).

Используется ли обычный стек для отслеживания trys, или отдельный стек для каждого потока сохраняется только для этой цели? Большая или маленькая реализация между MSVC и g ++? Покажите мне, пожалуйста, какой-нибудь псевдо-ассемблер (IA-32 тоже в порядке), чтобы мне никогда не пришлось проверять его сам! :)

Изменить: Теперь я получил основы реализации MSVC по обработке IA-32. Кто-нибудь знает, что такое g ++ на IA-32 или любой другой процессор в этом отношении?

Редактировать 2 (11 лет спустя): Вот некоторые данные о производительности. Они также сделали бесплатный доступ к исходному коду.


person Jonas Byström    schedule 25.08.2009    source источник


Ответы (3)


Плохие реализации обработчиков исключений помещают какой-то блок обработчика исключений для каждого предложения try в стеке времени выполнения при вводе предложения try и выталкивают его при выходе из предложения try. Также сохраняется местоположение, содержащее адрес самого последнего отправленного блока обработчика исключений. Обычно эти обработчики исключений объединены в цепочку, поэтому их можно найти, перейдя по ссылкам от самых последних к более старым версиям. Когда возникает исключение, обнаруживается указатель на последний нажатый блок обработчика EH и проверяется обработка случаев EH этого предложения try. Попадание в случай EH приводит к тому, что очистка стека происходит обратно до точки нажатого EH, и управление передается к случаю EH. Отсутствие попаданий в EH приводит к обнаружению следующего EH, и процесс повторяется. Схема SEH для 32-разрядной версии Windows является версией этого.

Это плохая реализация, потому что программа оплачивает время выполнения за каждое предложение try (push, затем pop), даже если не возникает исключения.

Хорошие реализации просто записывают таблицу диапазонов, в которых встречаются предложения try. Это означает нулевые накладные расходы на вход / выход из предложения try. (Мой PARLANSE язык параллельного программирования использует эту технику). Исключение ищет ПК точки исключения в таблице и передает управление EH, выбранному таблицей. Код EH сбрасывает стек соответствующим образом. Быстро и красиво. Я думаю, что Windows 64-битная EH относится к этому типу, но я не смотрел внимательно.

[ИЗМЕНИТЬ апрель 2020 г .: Недавно только что измерил стоимость исключений PARLANSE. 0нС (по замыслу), если нет исключения; 25 нс на i7 с тактовой частотой 3 ГГц от броска до захвата до подтверждения (конец пустого улова). OP добавил ссылку, измеряющую обработку исключений C ++ на уровне примерно 1000 нс для простейшего вида, и буквально нестандартную схему обработки, которая синхронизируется с 57 нс для исключения или отсутствия исключения; Тактовая частота ЦП для версий C ++ немного ниже, поэтому эти цифры приведены только для приблизительного сравнения.]

person Ira Baxter    schedule 25.08.2009
comment
Ссылка мертвая. - person Ekrem Dinçel; 30.11.2020
comment
@Kowalski: спасибо, что указали на это. Ссылка исправлена. - person Ira Baxter; 30.11.2020
comment
@IraBaxter Ссылка PARLANSE у меня не работает (время ожидания соединения истекло). Я погуглил, и там возникла такая же проблема. - person Sourav Kannantha B; 15.02.2021
comment
@Sourav: Мы в Остине, штат Техас, только что выпало 6 дюймов снега (рекорд столетия), и во всем городе отключено электричество - ›наши серверы не работают. Задержите дыхание на полдня и попробуйте еще раз. - person Ira Baxter; 15.02.2021
comment
@IraBaxter Предположим, что гипотетический язык предоставляет краткий и понятный синтаксис для написания базового стиля обработки кода ошибок, тогда какой из них вы предпочтете? код ошибки или исключения? - person Sourav Kannantha B; 15.02.2021
comment
Исключения, особенно те, которые имеют нулевую стоимость, когда их не происходит. а) вам не нужно писать тест кода ошибки, который проверяет каждую ошибку в каждой точке, где она может произойти, и б) он снижает стоимость проверки ошибок. ПАРЛАНС владеет этим красивым имением последние 20 лет. - person Ira Baxter; 16.02.2021

Комитет по стандартизации C ++ опубликовал технический отчет «Производительность C ++», чтобы развенчать многие мифы о том, как функции C ++ якобы замедляют работу. Это также включает подробности о том, как может быть реализована обработка исключений. черновик этого технического отчета доступен бесплатно. См. Раздел 5.4.1. «Проблемы и методы реализации обработки исключений».

person sellibitze    schedule 03.10.2009

Asm из обозревателя компилятора Godbolt для вызова x86-64 System V соглашение с C ++ ABI из g ++ 8.2 для функции, которая улавливает, и функции, которая выбрасывает.

x86-64 System V использует раздел .eh_frame для метаданных раскрутки стека, поэтому функции библиотеки-помощника по исключениям знают, как обходить стек и восстанавливать регистры. Вот что делают .cfi директивы.

person Peter Cordes    schedule 03.08.2018
comment
Я не мог решить, публиковать ли этот ответ в виде комментария или нет. Я пошел с ответом, хотя у меня не было времени вдаваться в подробности, показывать и комментировать код. - person Peter Cordes; 03.08.2018