45809 (665153)

Файл №665153 45809 (Централизованная обработка исключений)45809 (665153)2016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла

Централизованная обработка исключений

Беляев Алексей

Когда приложение перестает работать в офисе у разработчика, найти ошибку и исправить ее не составляет труда. Когда же приложение отказывает у клиента, то трудно найти общий язык с огорченным пользователем, и понять что ты сделал не так...

Введение

Что такое ошибка? Отвечая на этот вопрос кратко, можно сказать, что ошибка – это отклонение от описанного поведения. Для разработчика это означает, что необходимо искать и исправлять причину этого отклонения. Для программиста контроля качества ПО это означает, что необходимо доработать тесты и включить их в базовый цикл тестирования приложения. Для руководства это означает увеличение времени и затрат на разработку продукта.

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

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

Windows и необработанные исключения

Когда в приложении, работающем под управлением ОС Windows (от 9х до ХР), возникает необработанное исключение, операционная система обрабатывает его, создает dump-файл и записывает в него информацию, анализируя которую можно восстановить состояние приложения и быстро найти ошибку. К информации, которую сохраняет операционная система, относится:

информация о потоках;

информация о загруженных модулях;

информация об исключении;

информация о системе;

информация о памяти.

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

Каким образом Windows XP определяет, что в приложении произошло необработанное исключение? Ответить на этот вопрос можно, если разобраться с механизмом структурированной обработки исключений (SEH). Все версии Windows, начиная с версии Windows 95 и Windows NT, поддерживают этот механизм обработки исключений, позволяющий операционной системе и приложению тесно взаимодействовать в случае возникновения исключительной ситуации. И если в каком-либо приложении возникает необработанное исключение, операционная система обрабатывает его и завершает приложение.

Структурированная обработка ошибок

Структурированная обработка исключений (SEH) – это предоставляемый системой сервис, вокруг которого библиотеки современных языков программирования реализуют свои собственные функции для работы с исключениями.

C++-программисты наверняка знакомы с SEH в основном по использованию конструкций __try ... __except. Встретив в теле функции конструкцию __try … __except, компилятор, поддерживающий SEH, генерирует код для регистрации обработчика исключения. Затем, после возникновения исключения, операционная система ищет подходящий обработчик. Если подходящий обработчик не найден, операционная система создает dump-файл и завершает работу приложения.

Таким образом, перед нами стоит задача – сделать так, чтобы после возникновения в приложении необработанного исключения вызывался наш обработчик.

Для решения этой задачи необходимо выяснить, как операционная система ищет обработчик исключения. В поисках ответа на этот вопрос я углублялся в документацию по механизму структурированных исключений, анализировал системный ассемблерный код, смотрел, что генерирует компилятор, когда встречает конструкцию __try … __except, но подходящего решения не находилось. Ни в SDK, ни в DDK я не нашел ничего, что могло бы ответить на этот вопрос. Анализируя код, генерируемый компилятором для конструкции __try … __except, я увидел, что для каждого нового обработчика исключений в стеке создается запись, которая помещается в связанный список. Вот пример простой функции, который поможет понятнее объяснить это:

void foo()

{

__try

{

}

__except(1)

{

}

}

Код, который был сгенерирован компилятором VC 7.0:

void foo()

{

00411DE0 push ebp

00411DE1 mov ebp,esp

00411DE3 push 0FFFFFFFFh

00411DE5 push 424140h

00411DEA push offset @ILT+390(__except_handler3) (41118Bh)

00411DEF mov eax,dword ptr fs:[00000000h]

00411DF5 push eax

00411DF6 mov dword ptr fs:[0],esp

00411DFD add esp,0FFFFFF38h

00411E03 push ebx

00411E04 push esi

00411E05 push edi

00411E06 lea edi,[ebp-0D8h]

00411E0C mov ecx,30h

00411E11 mov eax,0CCCCCCCCh

00411E16 rep stos dword ptr [edi]

00411E18 mov dword ptr [ebp-18h],esp

__try

00411E1B mov dword ptr [ebp-4],0

00411E22 mov dword ptr [ebp-4],0FFFFFFFFh

00411E29 jmp $L19329+0Ah (411E3Bh)

{

}

__except(1)

00411E2B mov eax,1

$L19330:

00411E30 ret

$L19329:

00411E31 mov esp,dword ptr [ebp-18h]

00411E34 mov dword ptr [ebp-4],0FFFFFFFFh

{

}

}

00411E3B mov ecx,dword ptr [ebp-10h]

00411E3E mov dword ptr fs:[0],ecx

00411E45 pop edi

00411E46 pop esi

00411E47 pop ebx

00411E48 mov esp,ebp

00411E4A pop ebp

00411E4B ret

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

00411DE3 push 0FFFFFFFFh

00411DE5 push 424140h

00411DEA push offset @ILT+390(__except_handler3) (41118Bh)

00411DEF mov eax,dword ptr fs:[00000000h]

00411DF5 push eax

00411DF6 mov dword ptr fs:[0],esp

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

00411E3B mov ecx,dword ptr [ebp-10h]

00411E3E mov dword ptr fs:[0],ecx

Таким образом, если функция имеет в себе конструкцию __try … __except, то компилятор создает в стеке запись о новом обработчике исключений и помещает информацию о ней в список обработчиков. Придя к такому выводу, я начал искать хоть какую-то информацию об обработчиках исключений и нашел публикацию, написанную Matt Pietrek-ом 7 лет назад (A Crash Course on the Depths of Win32 Structured Exception Handling). В этой статье описана структура SEH, и подтверждаются выводы, сделанные путем анализа кода приведенной выше функции. Изучив эту статью и проверив написанное в ней, я обнаружил, что с тех пор в области обработки исключений практически ничего не изменилось.

Из статьи следует, что по адресу fs:[0], находится начало связанного списка зарегистрированных обработчиков исключения, элементами которого являются структуры типа _EXCEPTION_REGISTRATION, расположенные в стеке.

struct _EXCEPTION_REGISTRATION

{

// указатель на следующую запись

_EXCEPTION_REGISTRATION *prev;

// обработчик исключения, созданный Runtime библиотекой

SEHHandler handler;

// указатель на структуру, описывающий блок __try…__except

PSCOPETABLE scopetable;

// уровень вложенности текущего блока try

int trylevel;

// указатель на следующую запись

int _ebp;

};

В этой структуре handler является процедурой обработки исключения. Прототип этой функции приведен ниже:

typedef int (*SEHHandler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION, PCONTEXT, void*);

Как видите, функция обработчика исключения принимает 4 параметра. Первый параметр имеет тип PEXCEPTION_RECORD – это указатель на структуру, содержащую информацию об исключении. Вы можете найти объявление этой структуры в заголовочном файле winnt.h:

typedef struct _EXCEPTION_RECORD {

DWORD ExceptionCode;

DWORD ExceptionFlags;

_EXCEPTION_RECORD *ExceptionRecord;

PVOID ExceptionAddress;

DWORD NumberParameters;

ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS];

} EXCEPTION_RECORD;

Описание наиболее значимых полей этой структуры приведено ниже:

ExceptionCode – тип исключения.

ExceptionFlags – флаг исключения.

ExceptionAddress – адрес участка кода, где возникло исключение.

Второй параметр функции содержит в себе указатель на структуру PEXCEPTION_REGISTRATION. Ее описание и назначение было приведено выше.

Третий параметр указывает на переменную типа PCONTEXT и несет информацию о состоянии регистров во время исключения.

Таким образом, механизм обработки исключений становится более или менее ясным, т.е. когда в приложении возникает исключение, операционная система берет текущий указатель по адресу fs:[0] и просматривает список обработчиков в поисках нужного обработчика исключения. Если обработчик найден, она передает ему управление. В противном случае операционная система выполняет свой обработчик, который вызывает функцию UnhandledExceptionFilter. Значит, для получения управления в случае возникновения необработанного исключения, нужно зарегистрировать свой обработчик и расположить его в вершине этого списка. Но мир программирования не был бы таким интересным, если бы все было так просто! Давайте пройдем дальше и посмотрим, что происходит во время старта приложения, и какую роль в обработке исключений играет runtime-библиотека.

Старт приложения и инициализация runtime

Когда операционная система загружает приложение, она считывает содержимое файла с диска в память, загружает все необходимые для работы приложения внешние библиотеки и инициализирует таблицу импорта адресами реальных функций. После этого загрузчик передает управление на точку входа приложения. В случае С++-приложений, написанных с использованием Microsoft Visual Studio 6.0 (7.x, 8.0), управление передается функции WinMainCRTStartup или wWinMainCRTStartup, в зависимости от версии runtime-библиотеки – UNICODE или Multi-Byte Character Set (MBCS). Эта функция подготавливает приложение к работе, инициализирует runtime, выполняет конструкторы всех статических переменных и передает управление на точку входа, определенную разработчиком. Если внимательно рассмотреть эту функцию, можно увидеть, что инициализация пользовательских статических переменных и передача управления на пользовательскую точку входа осуществляется внутри блока __try … __except. Углубившись в исследование фильтра исключений runtime-библиотеки, я обнаружил, что в случае возникновения необработанного исключения он вызывает функцию UnhandledExceptionFilter.

Характеристики

Тип файла
Документ
Размер
111,05 Kb
Тип материала
Учебное заведение
Неизвестно

Тип файла документ

Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.

Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.

Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.

Список файлов реферата

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6540
Авторов
на СтудИзбе
301
Средний доход
с одного платного файла
Обучение Подробнее