Стражная страница исключений в Delphi? - PullRequest
6 голосов
/ 19 апреля 2009

Есть сообщение Раймонда Чена, где он рассказывает, насколько плоха функция IsBadXxxPtr, употребляя исключение охранной страницы .

Я не совсем понимаю, как это применяется к Delphi. Кто и как должен обычно (т.е. без вызова IsBadXxxPtr) обрабатывать это исключение? Я знаю, что Delphi вставляет код, который (например) обращается к памяти для больших статических массивов - именно по этой причине: для расширения стека.

Но если возникает исключение для защитной страницы: кто будет обрабатывать это в приложении Delphi? Разве я не могу случайно связываться с ним, используя try / иначе, не по назначению? Будет ли отладчик Delphi сообщать мне об этих исключениях?

Ответы [ 2 ]

14 голосов
/ 19 апреля 2009

Обработка структурированных исключений Windows (SEH) имеет двухфазную структуру. Когда возникает исключение, Windows сначала ищет обработчик для исключения, следуя зарегистрированной цепочке обработчиков исключений (заголовок которой хранится в fs: [0] на x86, то есть первое слово в сегменте, на которое указывает сегмент FS регистр - вся эта уродливая 16-битная логика смещения сегментов не исчезла в 32-битной, она просто стала менее актуальной).

Поиск выполняется путем вызова функции с определенным флагом, указатель на который сохраняется в каждом кадре исключения в стеке. fs: [0] указывает на самый верхний кадр. Каждый кадр указывает на предыдущий кадр. В конечном счете, последний кадр в списке - это тот, который был предоставлен ОС (этот обработчик вызовет диалоговое окно сбоя приложения, если его достигнет необработанное исключение).

Эти функции обычно проверяют тип исключения и возвращают код, указывающий, что делать. Один из кодов, который может быть возвращен, по сути, «игнорировать это исключение и продолжить». Если Windows увидит это, она сбросит указатель инструкций до точки исключения и возобновит выполнение. Другой код указывает, что этот кадр исключения должен обрабатывать данное исключение. Третий код: «Я не собираюсь ловить это исключение, продолжайте поиск». Windows продолжает вызывать эти функции фильтра исключений, пока не найдет ту, которая обрабатывает исключение тем или иным способом.

Если Windows находит то, которое обрабатывает исключение, перехватывая его, тогда она продолжит разматывать стек обратно к этому обработчику, который состоит из повторного вызова всех функций, только передавая другой флаг. Именно в этот момент функции выполняют логику finally вплоть до обработчика, который выполняет логику except.

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

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

Вы можете прочитать больше о SEH в Отличная статья Мэтта Пьетрека в MSJ более десяти лет назад .

2 голосов
/ 19 апреля 2009

При просмотре комментариев мне кажется, что беспорядок "исключение страницы защиты" происходит полностью внутри ядра, и это не то, о чем вам нужно беспокоиться из пользовательского пространства.

Вы должны помнить, что эта статья была написана для C ++, который далеко не так совершенен, как Delphi в области управления памятью. Проблема неинициализированных указателей в Delphi намного меньше, чем в C / C ++ по двум причинам:

  1. Delphi проверяет неинициализированные переменные во время компиляции, с которыми (по любой причине) многие компиляторы C, как правило, сталкиваются с проблемами.
  2. Delphi инициализирует всю свою динамическую память равной 0, поэтому у вас нет случайного кучи мусора, с которым можно справиться, который может выглядеть как хороший указатель, когда это действительно не так. Это означает, что большинство плохих указателей дают вам нарушения доступа, которые легко отлаживать, вместо того, чтобы молча отказывать и портить память.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...