Процедура очистки
Массив кода очистки сортируется в убывающем порядке.При возникновении исключения полный контекст сохраняется операционной системой в записи контекста.После этого вызывается логика обработки исключений, несколько раз выполняющая следующие операции по поиску обработчика исключения.
Для поиска записи в таблице RUNTIME_FUNCTION, описывающей текущую функцию (или часть функции, в случае связанных записей UNWIND_INFO) следует использовать текущую версию защиты остаточных данных (RIP), сохраняемых в записи контекста.
Если записи в таблице функций не найдено, то она находится в конечной функции, а RSP обращается напрямую к указателю возврата.Указатель возврата в [RSP] сохраняется в обновленном контексте, смоделированный RSP получает приращение на 8, и шаг 1 повторяется.
Если запись в таблице функций найдена, то RIP может лежать в трех областях — a) в заключительной части, b) в прологе или c) в коде, доступном обработчику исключений.
Случай a) Если RIP находится в заключительной части, то элемент управления выходит из функции, отсутствует обработчик исключения для этой функции, а результаты заключительной части должны обрабатываться и далее до вычисления контекста вызывающей функции.Чтобы определить, лежит ли RIP в заключительной части, необходимо исследовать поток кода из включенного RIP.Если поток кода может соответствовать конечной части допустимого эпилога, то это будет эпилог, а остальная часть эпилога будет смоделирована, при этом запись контекста будет обновляться при обработке каждой инструкции.После этого повторяется выполнение шага 1.
Случай b) Если RIP находится в прологе, то элемент управления не вошел в функцию, отсутствует обработчик исключения для этой функции, а результаты пролога должны быть отменены для вычисления контекста вызывающей функции.RIP лежит в прологе, если расстояние от начала функции до RIP меньше либо равно размеру пролога, закодированному в информации об очистке.Результаты в прологе очищаются при просмотре вперед по массиву кода очистки для первой записи со смещением, меньшим либо равным смещению RIP от начала функции, после чего выполняется отмена результата для всех остальных элементов в массиве кода очистки.После этого повторяется выполнение шага 1.
Случай c) Если RIP не лежит в прологе или в заключительной части, и для функции имеется обработчик исключений (установлен флаг UNW_FLAG_EHANDLER), то вызывается обработчик конкретного языка.Обработчик просматривает данные и вызывает соответствующие функции фильтра.Обработчик, специфичный для конкретного языка, может возвращать результат, указывающий на то, что исключение было обработано, либо на то, что поиск следует продолжить.Он может также инициировать очистку напрямую.
Если обработчик, специфичный для конкретного языка, возвращает состояние "обработано", то выполнение продолжается с использованием исходной записи контекста.
Если обработчик, специфичный для конкретного языка, отсутствует, либо если возвращает результат "продолжить поиск", запись контекста должна быть очищена до состояния вызывающего объекта.Эта выполняется путем обработки всех элементов массива кода очистки с отменой результата для каждого элемента.После этого повторяется выполнение шага 1.
Если используются связанные данные очистки, то выполнение этих основных операций продолжается.Единственное отличие заключается в том, что при прохождении массива кода очистки с целью отмены результатов для пролога, как только достигнут конец массива, он присоединяется к главной информации по очистке, и выполняется прохождение по всему обнаруженному массиву очистки.Это присоединение продолжается до состояния очистки без флага UNW_CHAINED_INFO и завершения прохождения по массиву кода очистки.
Наименьший набор данных очистки имеет размер в 8 байтов. Это позволило бы создать функцию, занимающую в стеке не более 128 байтов, и сэкономить независимый регистр.Это также показывает размер связанной структуры данных очистки для пролога нулевой длины без кодов очистки.