Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Рихтер Дж., Назар К. - Windows via C C++. Программирование на языке Visual C++ - 2009

.pdf
Скачиваний:
6268
Добавлен:
13.08.2013
Размер:
31.38 Mб
Скачать

838 Часть V. Структурная обработка исключений

Табл. 26-4. Флаги, связанные с добавляемыми файлами

Флаг

Описание

DELETE_WHEN_DONE = 1

После отправки отчета файл следует удалить

ANONYMOUS_DATA = 2

Файл не содержит персональной информации, по

 

которой можно определить пользователя. Если

 

этот флаг не задан, при первом запросе сервера

 

Майкрософт на передачу этого файла система

 

спрашивает разрешение у пользователя. Если

 

пользователь соглашается, параметру Consent в

 

системном реестре присевается значение 3. После

 

этого все файлы, помеченные этим флагом, будут

 

отправляться без запроса подтверждения у пользо-

 

вателя

Зарегистрированные таким образом файлы будут сохранены в отчете. Заметьте, что функцию WerRegisterFile можно вызывать многократно, чтобы добавить к отчету несколько файлов.

Примечание. Число элементов отчета WER, регистрируемых вызовами

WerRegisterMemoryBlock и WerRegisterFile, не может быть больше, чем за-

дано параметром WER_MAX_REGISTERED_ENTRIES (в настоящее время — 512). Возвращаемое в случае этой ошибки значение HRESULT можно сопоставить с кодом ошибки Win32 следующим образом: if ( HRESULT_ CODE(hr) == ERROR_INSUFFICIENT_BUFFER).

В завершение замечу, что для удаления из отчетов блоков данных и файлов служат следующие функции:

HRESULT WerUnregisterMemoryBlock(PVOID pvAddress);

HRESULT WerUnregisterFile(PCWSTR pwzFilePath);

Создание и настройка отчетов о сбоях

В этом разделе я расскажу, как создавать нестандартные отчеты о сбоях в собственных приложениях. Соответствующие функции позволяют создавать отчеты не только о необработанных исключениях, но и о проблемах, никак с ними не связанных. Кроме того, после генерации отчета приложения не обязано завершаться, и может спокойно работать дальше. Так что стоит подумать об использовании службы Windows Error Reporting вместо добавления непонятных сообщений в журнал событий Windows. Однако инфраструктура WER ограничивает число и размеры отчетов посредством параметров системного реестра, расположенных в разделе HKEY_ CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting (табл. 26-5).

 

Глава 26. Отчеты об ошибках и восстановление приложений.docx 839

Табл. 26-6. Параметры реестра, управляющие хранением данных WER

Параметр

Описание

MaxArchiveCount

Максимальное число файлов в архиве (допустимые значения — 1-5000;

 

значение по умолчанию — 1000)

MaxQueueCount

Максимальное число отчетов, которое можно поставить в очередь на ло-

 

кальном компьютере до отправки их в Майкрософт (допустимые значе-

 

ния — 1-500; значение по умолчанию — 50)

Примечание. Результаты трассировки отчетов, отправленных в Microsoft (за исключением вложенных в отчет файлов), архивируется в каталоге

AppData\Local\Microsoft\Windows\WER\ReportArchive профиля текущего пользователя. Очередь отчетов, которые еще не отправлены, хранится в папке AppData\Local\Microsoft\Windows\WER\ReportQueue текущего поль-

зователя. К сожалению, API, который консоль WER использует для работы с этими отчетами, не задокументирован, поэтому вы не сможете перебрать отчеты в своем коде. Будем надеяться, что в будущих версиях Windows это изменится.

Создание, настройка и передача отчетов о сбоях службе WER осуществляется путем вызова следующих функций в указанной последовательности:

1.Вызов WerReportCreate создает новый отчет о сбое.

2.Функция WerReportSetParameter служит для настройки параметров отчета.

3.Вызов WerReportAddDump добавляет к отчету мини-дамп.

4.Функция WerReportAddFile добавляет к отчету произвольные файлы (например, пользовательские документы).

5.Функция WerReportSetUIOption модифицирует текст, который отображается пользователю при вызове WerReportSubmit.

6.Вызов WerReportSubmit передает отчет WER. В зависимости от заданных флагов, Windows может поставить запрос в очередь, либо запросить у пользователя подтверждение и отправить отчет в Майкрософт.

7.Вызов WerReportCloseHandle закрывает отчет.

Атеперь разберем эту процедуры подробнее. При чтении следующих разделов вам, возможно, пригодится описание функции GenerateWerReport, применяемой в приложении-примере Customized WER (см. ниже).

После запуска этой программы откройте консоль WER и щелкните ссылку View Problem History, Чтобы получить список отчетов (рис. 26-5).

В записи о сбоях, вызванных программой 23-SEHTerm.exe, имя продукта соответствует имени исполняемого файла программы. В отличие от нее, отчет о сбое 25-HandleUnhandled.exe выводится в секции Wintellect Applications Suite. В

столбце Problem также выводится информация о сбое, но более подробная, чем комментарий по умолчанию «Stopped working».

Если двойным щелчком отрыть подробности отчета, будет видно, что его содержимое также изменено (рис. 26-6) с помощью Wer*-функций (сравните рис.

26-6 и 26-3).

840 Часть V. Структурная обработка исключений

Рис. 26-5. Список отчетов в консоли WER, отсортированный по названию продукта

Заголовок отчета и название сбоя — те же, что в сводке, отображаемой в списке консоли WER. Новое поле Description выводит краткое описание сбоя, а значение Problem Event Name теперь содержит больше полезной информации (а не только строку APPCRASH, как прежде).

Рис. 26-6. Нестандартный отчет в консоли WER

Глава 26. Отчеты об ошибках и восстановление приложений.docx 841

Создание собственного отчета о сбое: функция WerReportCreate

Чтобы создать собственный отчет, вызовите функцию WerReportCreate и передайте ей сведения об отчете, который требуется создать:

HRESULT WerReportCreate(

PCWSTR pwzEventType,

WER_REPORT_TYPE repType,

PWER_REPORT_INFORMATION pReportInformation,

HREPORT *phReport);

Параметр pwzEventType — это Unicode-строка, которая представляет собой первый элемент Problem Signature. Заметьте: чтобы ваш отчет был доступен для просмотра на сайте Windows Quality Web (http://WinQual.Microsoft.com), соответ-

ствующий тип события должен быть зарегистрирован в Майкрософт (подробнее см. в описании WerReportCreate на сайте MSDN по ссылке http://msdn2.microsoft.com/en-us/library/bb513625.aspx).

Внимание! Все Wer*-функции принимают только Unicode-строки, поэтому в их именах нет суффиксов А и W.

Параметр repType принимает значения, перечисленные в табл. 26-6.

Табл. 26-6. Значения параметра repType

Значение

Описание

WerReportNonCritical = 0

Отчет «молча» добавляется в очередь и отправ-

 

ляется в Майкрософт согласно значению пара-

 

метра Consent

WerReportCritical = 1

Отчет добавляется в локальную очередь с уве-

 

домлением пользователя и, при необходимости,

 

завершением приложения

WerReportApplicationCrash = 2

Идентичен WerReportCritical, но в уведомлении

 

пользователя выводится понятное имя приложе-

 

ния, а не его исполняемого файла

WerReportApplicationHang = 3

Идентичен WerReportApplicationCrash, но ис-

 

пользуется при зависаниях и взаимных блоки-

 

ровках

Параметр pReportInformation указывает на структуру

WER_REPORT_INFORMATION, содержащую Unicode-поля, перечисленные в табл. 26-7.

842 Часть V. Структурная обработка исключений

Табл. 26-7. Поля структуры WER_REPORT_INFORMATION

Поле

Описание

wzApplicationName

Продукт отображается в столбце Problem History консоли

 

WER и рядом со значком приложения в описании сбоя

wzApplicationPath

Содержимое не отображается на локальной системе, но

 

доступно на сайте Windows Quality

wzDescription

Содержимое отображается в поле Problem Description

wzFriendlyEventName

Содержимое отображается в поле Event Name секции Prob-

 

lem Signature отчета

Как и все Wer*-функции, WerReportCreate возвращает HRESULT и, если вызов завершился успешно, — описатель отчета (в параметр phReport).

Настройка параметров отчета: функция WerReportSetParameter

После поля Problem Event Name, но перед OS Version и Locale ID в секции отчета

Problem Signature содержится набор пар «ключ-значение», которые задают с помощью следующих функций:

HRESULT WerReportSetParameter(

HREPORT hReport,

DWORD dwParamID,

PCWSTR pwzName,

PCWSTR pwzValue);

В параметре hReport передается описатель, ранее полученный вызовом WerReportCreate. Параметр dwParamID задает пару «ключ-значение», которую необходимо определить. Эта функция позволяет определять до 10 пар, которые задаются объявленными в werapi.h макросами WER_P0—WER_P9 (со значениями 0- 9). В параметрах pwzName к pwzValue вы можете передать нужные вам Unicodeстроки.

Заметьте, что при передаче целого числа, которое меньше 0 или больше 9, WerReportSetParameter возвращает E_INYALIDARG. Также нельзя пропускать идентификаторы, то есть, устанавливая WERP2, необходимо также установить WERP1 и WER_P0. Порядок установки не важен, но если вы пропустите идентификатор, вызов WerReportSubmit закончится неудачей и возвратом HRESULT с

значением 0x8008FF05.

По умолчанию, для стандартного отчета WER устанавливает параметры, перечисленные в табл. 26-8.

 

Глава 26. Отчеты об ошибках и восстановление приложений.docx 843

Табл. 26-8. Параметры по умолчанию отчета о сбое

Номер

Описание

1

Имя сбойного приложения

2

Версия сбойного приложения

3

Временная отметка сборки двоичного файла

4

Имя сбойного модуля

5

Версия сбойного модуля

6

Временная отметка сборки двоичного файла

7

Код возникшего исключения

8

Смещение в модуле, по которому возникло исключение. Рассчитывается путем вы-

 

читания из EIP-указателя (или его эквивалента для компьютеров с архитектурой, от-

 

личной от х86) сбоя адреса, по которому загружен сбойный модуль

Добавление к отчету мини-дампа: функция WerReportAddDump

Добавить к отчету о сбое мини-дамп можно вызовом функции

WerReportAddDump:

HRESULT WerReportAddDump(

HREPORT hReport,

HANDLE hProcess,

HANDLE hThread,

WER_DUMP_TYPE dumpType,

PWER_EXCEPTION_INFORMATION pel,

PWER_DUMP_CUSTOM_OPTIONS pDumpCustomOptions,

DWORD dwFlags);

Параметр hReport задает отчет, к которому следует добавить мини-дамп. Параметр hProcess задает описатель процесса, дамп которого следует добавить (для этого описателя должны быть назначены права доступа STANDARD_RIGHTS_READ и PROCESS_QUERY_INFORMATION). Обычно этой функции передают описатель, полученный вызовом GetCurrentProcess — такие описатели получают все права, имеющиеся у процессов.

Параметр hThread задает поток процесса, заданного параметром hProcess; функция WerReportAddDump проходит по стеку вызовов этого потока. При «посмертной» отладке этот стек используется отладчиком для поиска команды, вызвавшей исключение. Помимо сохраненного стека вызовов, WerReportAddDump нужна дополнительная информация, которую вы должны ей передать через пара-

метр pExceptionParam:

WER_EXCEPTION INFORMATION wei; weiTbClientPointers = FALSE; wei.pExceptionPointers = pExceptionlnfo;

//мы находимся в процессе, для которого

//указатель pExceptionInfo действителен

844Часть V. Структурная обработка исключений

Вэтом примере кода pExceptionInfo задает сведения об исключении, возвращаемые функцией GetExceptionInformation; ту же самую информацию, как правило, передают фильтру исключений. Далее &wei передается параметру pei функции WerReportAddDump. Тип дампа определяется параметрами dumpType и pDumpCustomOptions (подробнее см. в соответствующих статьях MSDN).

Впараметре dwFlags передают 0 или WER_DUMP_NOHEAP_ONQUEUE.

Обычно в мини-дамп включают содержимое кучи, но флаг

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

Добавление к отчету произвольных файлов: функция WerReportAddFile

В разделе о настройке отчетов, я рассказал, как добавить произвольные файлы во все отчеты о сбоях заданного процесса. Однако вызовом функции WerReportAddFile вы можете добавить к отчету изрядное число файлов (даже больше, чем 512):

HRESULT WerReportAddFile(

HREPORT hReport,

PCWSTR pwzFilename,

WER_FILE_TYPE addFileType,

DWORD dwFileFlags);

В параметре hReport передают описатель отчета, к которому следует добавить файл, заданный параметром pwzFilename. Значения параметра addFileType перечислены в табл. 26-9.

Табл. 26-9. Типы добавляемых к отчету файлов

Тип

Описание

WerFileTypeMicrodump = 1

Пользовательский микро-дамп

WerFileTypeMinidump = 2

Пользовательский мини-дамп

WerFileTypeHeapdump = 3

Пользовательский дамп кучи

WerFileTypeUserDocument = 4

Файл, в котором могут быть конфиденциальные пользова-

 

тельские данные. По умолчанию такие файлы не отправляют-

 

ся в Майкрософт, но в будущем планируется открыть к ним

 

доступ для разработчиков через сайт Windows Quality

WerFileTypeOther = 5

Любой другой файл

Не путайте флаги WerFileTypeMicrodump, WerFileTypeMinidump и WerFileTypeHeapdump. При отправке отчета на сервер Майкрософт последний вступает в довольно сложный диалог с пользовательским компьютером для согласования списка отправляемых файлов. В некоторых случаях сервер запрашивает файлы дампов. Тогда локальное хранилище использует эти фла-

Глава 26. Отчеты об ошибках и восстановление приложений.docx 845

ги для отбора пользовательских дампов, генерированных приложением без использования функции WerReportAddDump. Дополнительные сведения о коммуникационном протоколе, по которому осуществляется отправка отчетов о сбоях, см. на сайте Windows Quality. Параметр dwFileFlags выполняет те же функции, что и одноименный параметр WerRegisterFile (см. табл. 26-4).

Модификация текста элементов интерфейса: функция

WerReportSetUIOption

Чтобы настроить текст, отображаемый в окне запроса разрешения на отправку отчета WER, вызовите следующую функцию:

HRESULT WerReportSetUIOption(

HREPORT hReport,

WER_REPORT_UI repUITypeID,

PCWSTR pwzValue);

Параметр hReport задает отчет, для которого необходимо модифицировать текст пользовательского интерфейса. Параметр repUITypeID определяет элемент, текст которого требуется изменить, а параметр pwzValue — текст (в формате Unicode), который необходимо вывести в этом элементе интерфейса.

Функцию WerReportSetUIOption следует вызывать для каждого из элементов интерфейса, который вы хотите изменить. Заметьте, что текст некоторых надписей и кнопок изменить невозможно. Примеры изменения текстовых полей показаны на экранных снимках ниже. Дополнительные сведения см. в описании функ-

ции WerReportSetUIOption в документации Platform SDK.

Передача отчета о сбое: функция WerReportSubmit

Теперь можно отправить отчет о сбое, вызвав функцию:

HRESULT WerReportSubmit(

HREPORT hReport,

WER_CONSENT consent,

DWORD dwFlags,

PWER_SUBMIT_RESULT pSubmitResult);

846 Часть V. Структурная обработка исключений

Параметр hReport задает описатель отчета, который требуется передать. Параметр consent принимает одно из следующих значений: WerConsentNotAsked, WerConsentApproved или WerConsentDenied. Как сказано выше, будет ли отчет от-

правлен в Майкрософт, зависит от значения параметра Consent в системном реестре, но окна, которые открывает WER при передаче отчета, определяются одноименным параметром функции WerReportSubmit. Если он равен

WerConsentDenied, отчет не отправляется, а если WerConsentApproved — откры-

ваются стандартные окна с уведомлениями о генерации отправке отчетов (рис. 25- 2 и 25-3). Если параметру consent присваивается значение WerConsentNotAsked, а одноименный параметр реестра равен 1 (то есть, система всегда должна запрашивать у пользователя разрешение, см. рис. 25-5), открывается окно, показанное на рис. 25-6. При этом пользователь должен сам решить, следует ли отправлять отчет о сбое в Майкрософт для поиска способа его устранения либо выбрать отладку или завершение приложения. Параметр dwFlags — это битовая маска, описанная в табл. 26-10.

Табл. 26-10. Параметры передачи отчета о сбое

Параметр

Описание

HONOR_RECOVERY = 1

Разрешает восстановление после критических сбоев (см.

 

ниже)

HONOR_RESTART = 2

Разрешает перезапуск приложения после критических

 

сбоев (см. ниже)

SHOW_DEBUG = 8

Если этот флаг не установлен, кнопка Debug не отобража-

 

ется

NO_CLOSE_UI = 64

Кнопка Close не отображается

START_MINIMIZED = 512

Окно уведомления открывается в свернутом виде и мигает

 

на панели задач Windows

QUEUE = 4

Отчет ставится в очередь без уведомления. Если в реестре

 

Consent = 1, отчет генерируется, но не отправляется в

 

Майкрософт

NO_QUEUE = 128

Запрещает постановку отчета в очередь

NO_ARCHIVE = 256

Передает обработку отчета другому процессу

 

(wermgr.exe)

OUTOFPROCESS_ASYNC = 1024

Передает обработку отчета другому процессу

 

(wermgr.exe), после чего WerReportSubmit немедленно

 

возвращает управление, не дожидаясь завершения обра-

 

ботки

ADD REGISTERED DATA = 16

Добавляет к отчету зарегистрированные данные. Заметь-

 

те, что если это флаг установлен вместе с флагом, пере-

 

дающим обработку отчета другому процессу, добавлен-

 

ные с помощью функции WerRegisterFile файлы попадут в

 

отчет дважды. Эта ошибка будет устранена в будущих

 

версиях Windows

Глава 26. Отчеты об ошибках и восстановление приложений.docx 847

Об успешном или неудачном завершении вызова WerReportSubmit сообщает возвращаемое ей значение HRESULT. Однако, собственно, результат возвращается в параметре pSubmitResult как ссылка на переменную WER_SUBMIT_RESULT (подробнее об этом см. в документации MSDN). Параметр pSubmitResult бесполезен, только когда в dwFlags установлен флаг

WER_SUBMIT_OUTOFPROCESS_ASYNC. В этом случае WerReportSubmit воз-

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

WER_SUBMIT_OUTOFPROCESS_ASYNC обычно применяется для процессов,

отслеживающих возникновение сбоев в других процессах. Например, Service Control Manager (SCM) в Windows использует этот флаг для уведомления о зависании процессов служб.

Закрытие отчета о сбое: функция WerReportCloseHandle

После отправки отчета не забудьте передать его описатель функции WerReportCloseHandle, чтобы освободить связанные с ним внутренние структуры данных:

HRESULT WerReportCloseHandle(HREPORT hReportHandle);

Программа-пример Customized WER

Эта программа (26-CustomizedWER.exe) демонстрирует создание отчетов о сбоях при возникновении необработанного исключения. На ее примере я также показываю прием, гарантирующий исполнение кода в блоке finally. Эта программа изменяет стандартный интерфейс WER и выводит собственное окно, в котором пользователь может выбрать между закрытием приложения и его отладкой. Изменив этот код, можно по умолчанию лишить пользователя возможности выбора отладки, а также создать локализованные версии окон WER для языка интерфейса приложения (а не операционной системы). Файлы исходного кода и ресурсов этой программы находятся в каталоге 26-CustomizedWER внутри архива, доступного на веб-сайте поддержки этой книги.

Примечание. Если ваше приложение должно работать в версиях Windows, предшествующих Vista, используйте функцию ReportFault. У этой функции намного меньше возможностей, чем у вышеописанных Wer*-функций. В приложениях для Windows Vista использовать ReportFault не рекомендуется.

Соседние файлы в предмете Программирование на C++