Обработчик исключений
Есть этот код:
char text[] = "zim";
int x = 777;
Если я посмотрю на стек, где размещены x и текст, вывод будет следующим:
09 03 00 00 7a 69 6d 00
Где:
- 09 03 00 00 = 0x309 = 777 < - int x = 777
- 7a 69 6d 00 = char текст [] = "zim" (код ASCII)
Теперь есть код с try..catch:
char text[] = "zim";
try{
int x = 777;
}
catch(int){
}
Stack
09 03 00 00 **97 85 04 08** 7a 69 6d 00
Теперь между текстом и x помещается новое 4-байтовое значение. Если я добавлю еще один улов, тогда будет что-то вроде:
09 03 00 00 **97 85 04 08** **xx xx xx xx** 7a 69 6d 00
и т.д. Я думаю, что это некоторая ценность, связанная с обработкой исключений, и используется во время разворачивания стека, чтобы найти соответствующий catch, когда исключение выбрасывается в блок try. Однако вопрос в том, что именно такое 4-байтовое значение (может быть, какой-то адрес для структуры обработчика исключений или какой-то id)?
Я использую g++ 4.6 на 32-разрядной машине Linux.
Ответы
Ответ 1
AFAICT, указатель на "таблицу разматывания". В рекомендации по внедрению Itanium ABI, процесс" [использует] таблицу разматывания, [чтобы] находить информацию о том, как обрабатывать исключения, которые происходят в этот ПК и, в частности, получить адрес индивидуальной подпрограммы для этого диапазона адресов.
Идея разматывания таблиц заключается в том, что данные, необходимые для разматывания стека, редко используются. Таким образом, более эффективно указывать указатель на стек и сохранять данные о ресурсах на другой странице. В лучших случаях эта страница может оставаться на диске и даже не нужно загружать в ОЗУ. Для сравнения, обработка ошибок стиля C часто заканчивается в кэше L1, потому что все они встроены.
Ответ 2
Излишне говорить, что все это зависит от платформы и т.д.
Это может быть адрес. Он может указывать либо на секцию кода (некоторый адрес обработчика), либо на раздел данных (указатель на структуру, сгенерированную по времени с информацией о кадре), или стек того же потока (указатель на таблицу, созданную во время выполнения информация о кадре).
Или это может быть мусор, оставленный из-за требования к выравниванию, которое может потребовать EH.
Например, на Win32/x86 нет такого промежутка. Для каждой функции, использующей обработку исключений (имеет либо try/catch
, либо __try/__except/__finally
, либо объекты с d'tors) - компилятор генерирует структуру EXCEPTION_RECORD
, которая выделяется в стеке (по пролог-функции функции). Затем, всякий раз, когда что-то изменяется внутри функции (объект создается/уничтожается, try/catch
block введен/выведен) - компилятор добавляет инструкцию, которая модифицирует эту структуру (более правильно - изменяет ее расширение). Но больше ничего не выделяется в стеке.