Обработчик исключений

Есть этот код:

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 введен/выведен) - компилятор добавляет инструкцию, которая модифицирует эту структуру (более правильно - изменяет ее расширение). Но больше ничего не выделяется в стеке.