Системное программирование в среде Windows
Шрифт:
PEXCEPTION_POINTERS — адрес структуры EXCEPTION_POINTERS, которая содержит как информацию, зависящую от типа процессора, так и информацию общего характера. Это та же структура, которую возвращает функция GetExceptionInformation и которая уже использовалась нами в программе 4.4.
От функции VEH-обработчика требуется, чтобы она выполнялась быстро и никогда не получала доступа к объектам синхронизации, таким как мьютекс (см. главу 8). В большинстве случаев VEH-обработчики просто обращаются к структуре исключения, выполняют некоторую минимальную обработку (например,
1. EXCEPTION_CONTINUE_EXECUTION — обработчики далее не выполняются, обработка средствами SEH не производится, и управление передается в ту точку программы, в которой возникло исключение. Как и в случае SEH, это оказывается возможным не всегда.
2. EXCEPTION_CONTINUE_SEARCH — выполняется следующий VEH-обработчик, если таковой имеется. Если обработчиков больше нет, разворачивается стек для поиска SEH-обработчиков.
В упражнении 4.9 вам предлагается добавить VEH в программы 4.3 и 4.4.
Резюме
Структурная обработка исключений в Windows предоставляет в распоряжение разработчиков механизм повышения надежности, благодаря которому С-программы могут адекватно реагировать на ошибки и исключения и восстанавливаться после возникновения сбоев в процессе выполнения. Методы обработки исключений отличаются высокой эффективностью, и их применение делает структуру программ более понятной, что облегчает их сопровождение и улучшает их качественные характеристики. В большинстве других языков и ОС также реализованы аналогичные подходы, однако решение Windows обеспечивает возможность точного анализа природы возникающих исключений.
Обработчики управляющих сигналов консоли позволяют реагировать на внешние события, наступление которых не сопровождается генерацией исключений. Векторная обработка исключений является новейшим средством, обеспечивающим выполнение соответствующих функций еще до того, как начнется выполнение SEH-процедур. Механизм VEH аналогичен обычному механизму векторных прерываний.
В следующих главах
Функция ReportException, a также обработчики исключений и завершения будут неоднократно использоваться в последующих примерах, когда в этом возникнет необходимость. Глава 5 посвящена вопросам управления памятью, а в приведенных в ней в качестве примера программах для обнаружения ошибок, которые могут возникать в процессе распределения памяти, используется механизм SEH.
Упражнения
4.1. Расширьте возможности программы 4.2 путем предоставления при каждом вызове функции ReportException достаточно большого объема информации, чтобы обработчик исключений в своих сообщениях указывал точную природу возникающих ошибок и удалял выходные файлы, если их содержимое оказывается незначащим.
4.2. Расширьте возможности программы 4.3 за счет генерации таких исключений, связанных с нарушениями доступа к памяти, как выход индекса за пределы допустимого диапазона, а также исключений, обусловленных сбоями при выполнении арифметических операций, и других FP-исключений, не предусмотренных в программе 4.3.
4.3. Дополните программу 4.3 таким образом, чтобы она выводила на печать фактическое значение FP-маски после разрешения исключений. Все ли исключения оказались действительно разрешенными? Объясните результаты.
4.4. Какие значения вы в действительности получаете после возникновения таких FP-исключений, как деление на ноль? Можете ли вы установить результат в функции фильтра, как это пытается делать программа 4.3?
4.5. Что произойдет при выполнении программы 4.3, если не сбросить FP-исключение? Объясните результат. Подсказка. Запросите дополнительное исключение после возникновения FP-исключения.
4.6. Расширьте возможности программы 4.5 таким образом, чтобы процедура обработчика формировала исключение, а не возврат из функции. Объясните полученные результаты.
4.7. Расширьте возможности программы 4.5 таким образом, чтобы она могла обрабатывать сигналы, указывающие на выход пользователя из системы и завершение работы системы.
4.8. Экспериментальным путем убедитесь в том, что процедура обработчика в программе 4.5 выполняется параллельно с основной программой.
4.9. Усовершенствуйте программы 4.3 и 4.4. В частности, организуйте обработку арифметических и FP-исключений до активизации SEH.
ГЛАВА 5
Управление памятью, отображение файлов и библиотеки DLL
Управление динамической памятью в той или иной форме требуется в большинстве программ. Необходимость в этом возникает всякий раз, когда требуется создавать структуры данных, размер которых не может быть определен заранее на стадии создания программы. Типичными примерами динамических структур данных могут служить деревья поиска, таблицы имен и связанные списки.
В Windows предусмотрены гибкие механизмы управления динамической памятью программы. Кроме того, Windows предоставляет средства отображения файлов, которые позволяют ассоциировать файл непосредственно с виртуальным адресным пространством процесса, благодаря чему ОС может управлять любыми перемещениями данных между файлом и памятью, так что программисту вообще не приходится иметь дело с функциями ReadFile, WriteFile, SetFilePointer и другими функциями ввода/вывода.
В случае использования отображения файлов программе удобно сохранять внутренние динамические структуры данных в виде постоянно существующих файлов, а все алгоритмы обработки применять к создаваемой в памяти копии файла. Более того, отображение файлов может значительно ускорить последовательную обработку файлов и предоставляет механизм, обеспечивающий совместное использование областей памяти одновременно несколькими процессами.
Важным специальным случаем отображения файлов и разделения памяти являются динамически компонуемые библиотеки (dynamic linked libraries, DLL), обеспечивающие возможность отображения файлов (обычно, когда они используются только для чтения) на адресное пространство процесса для их выполнения.
В этой главе описывается система управления памятью и функции отображения файлов Windows, что иллюстрируется целым рядом примеров их использования, а также обсуждаются явно и неявно связанные библиотеки DLL.
Архитектура системы управления памятью в Win32 и Win64
Win32 (в данном случае различия между Win32 и Win64 становятся существенными) — это API 32-разрядных ОС семейства Windows. "32-разрядность" проявляет себя при адресации памяти тем, что указатели (LPSTR, LPDWORD и так далее) являются 4-байтовыми (32-битовыми) объектами. Win64 API предоставляет виртуальное адресное пространство гораздо большего объема, и 64-битовые указатели являются естественным результатом эволюции Win32. Тем не менее, о переносимости приложений на платформу Win64 необходимо заботиться отдельно. Настоящее обсуждение будет относиться только к Win32; вопросы миграции приложений на платформу Win64 обсуждаются в главе 16, где также приводятся ссылки на соответствующие источники информации.