Анализ аварийного дампа

Не все ошибки можно найти до выпуска, что означает, что не все ошибки, которые вызывают исключения, можно найти до выпуска. К счастью, корпорация Майкрософт включила в пакет Platform SDK функцию для помощи разработчикам в собрании информации об исключениях, обнаруженных пользователями. Функция минидумпвритедумп записывает необходимые данные аварийного дампа в файл без сохранения всего пространства процесса. Этот информационный файл аварийного дампа называется мини-дампом. В этой технической статье содержатся сведения о том, как создавать и использовать Малый дамп.

Запись минидампа

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

  • Не делать ничего. Windows автоматически создает малый дамп всякий раз, когда программа создает необработанное исключение. Автоматическое создание минидампа доступно с момента выпуска Windows XP. Если пользователь допускает его, мини-дамп будет отправлен в корпорацию Майкрософт, а не к разработчику с помощью отчеты об ошибках Windows (WER). Разработчики могут получить доступ к этим мини-дампам с помощью классического приложения Windows.

    Для использования WER требуется:

    • Разработчики могут подписывать свои приложения с помощью Authenticode
    • Приложения имеют допустимый ресурс VERSIONINFO в каждом исполняемом файле и библиотеке DLL

    При реализации пользовательской подпрограммы для необработанных исключений вы настоятельно законодателей использовать функцию репортфаулт в обработчике исключений, чтобы также отправить автоматизированный Малый дамп в WER. Функция репортфаулт обрабатывает все проблемы, связанные с подключением и отправкой МИНИДАМПА в WER. Не отправка минидампа в WER нарушает требования игр для Windows.

    Дополнительные сведения о принципах работы WER см. в разделе как работает отчеты об ошибках Windows. Описание сведений о регистрации см. в статье введение отчеты об ошибках Windows в зону ISVMSDN.

  • Используйте продукт из Microsoft Visual Studio Team System. В меню Отладка выберите команду сохранить дамп как , чтобы сохранить копию дампа. Использование локально сохраненного дампа является только параметром для внутреннего тестирования и отладки.

  • Добавьте код в проект. Добавьте функцию минидумпвритедумп и соответствующий код обработки исключений, чтобы сохранить и отправить Малый дамп непосредственно разработчику. В этой статье показано, как реализовать этот параметр. Однако обратите внимание, что в настоящее время минидумпвритедумп не работает с управляемым кодом и доступен только в Windows XP, Windows Vista, Windows 7.

Потокобезопасность

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

Создание минидампа с помощью кода

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

#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>

int GenerateDump(EXCEPTION_POINTERS* pExceptionPointers)
{
    BOOL bMiniDumpSuccessful;
    WCHAR szPath[MAX_PATH]; 
    WCHAR szFileName[MAX_PATH]; 
    WCHAR* szAppName = L"AppName";
    WCHAR* szVersion = L"v1.0";
    DWORD dwBufferSize = MAX_PATH;
    HANDLE hDumpFile;
    SYSTEMTIME stLocalTime;
    MINIDUMP_EXCEPTION_INFORMATION ExpParam;

    GetLocalTime( &stLocalTime );
    GetTempPath( dwBufferSize, szPath );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName );
    CreateDirectory( szFileName, NULL );

    StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", 
               szPath, szAppName, szVersion, 
               stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, 
               stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, 
               GetCurrentProcessId(), GetCurrentThreadId());
    hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, 
                FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

    ExpParam.ThreadId = GetCurrentThreadId();
    ExpParam.ExceptionPointers = pExceptionPointers;
    ExpParam.ClientPointers = TRUE;

    bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
                    hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);

    return EXCEPTION_EXECUTE_HANDLER;
}


void SomeFunction()
{
    __try
    {
        int *pBadPtr = NULL;
        *pBadPtr = 0;
    }
    __except(GenerateDump(GetExceptionInformation()))
    {
    }
}

Этот пример демонстрирует базовое использование минидумпвритедумп и минимальную информацию, необходимую для ее вызова. Имя файла дампа является разработчиком; Однако, чтобы избежать конфликтов имен файлов, рекомендуется создать имя файла из имени и номера версии приложения, идентификатора процесса и потока, а также даты и времени. Это также поможет защитить малые дампы, сгруппированные по приложениям и версиям. Разработчик может решить, какой объем информации используется для различения имен файлов минидампа.

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

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

  1. В левой части страницы свойств проекта щелкните C/C++. По умолчанию отображаются Общие параметры. В правой части страницы свойств проекта задайте для параметра Формат отладочной информации значение база данных программы (/Zi).
  2. В левой части страницы свойств разверните узел Компоновщик, а затем щелкните Отладка. В правой части страницы свойств задайте для параметра создать отладочную информацию значение Да (/Debug).
  3. Щелкните Оптимизация и задайте ссылки на лиминате данные без ссылок (/OPT: REF).
  4. Установите флажок Включить сворачивание записей COMDAT , чтобы удалить избыточные COMDAT (/OPT: ICF).

В MSDN содержится более подробная информация о структуре _ _ сведений об исключениях минидампа и функции минидумпвритедумп .

Использование Dumpchk.exe

Dumpchk.exe — это служебная программа командной строки, которую можно использовать для проверки правильности создания файла дампа. Если Dumpchk.exe создает ошибку, файл дампа поврежден и не может быть проанализирован. Сведения об использовании Dumpchk.exe см. в разделе использование Dumpchk.exe для проверки файла дампа памяти.

Dumpchk.exe входит в состав компакт-диска Windows XP, и его можно установить на системные \ файлы программы \ поддержки \ , запустив Setup.exe в \ папке средства поддержки \ на компакт-диске Windows XP. Вы также можете получить последнюю версию Dumpchk.exe, загрузив и установив средства отладки, доступные в средствах отладки Windows в центре разработчиков оборудования Windows.

Анализ минидампа

Открытие минидампа для анализа — это так же просто, как создание такого дампа.

Анализ минидампа

  1. Запустите Visual Studio.
  2. В меню файл выберите команду Открыть проект.
  3. Задайте файлы типа для дампа файлов, перейдите к файлу дампа, выберите его и нажмите кнопку Открыть.
  4. Запустите отладчик.

Отладчик создаст имитацию процесса. Имитация процесса будет остановлена в инструкции, вызвавшей сбой.

Использование общедоступного сервера символов Майкрософт

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

Установка пути к серверу символов Майкрософт

  1. В меню Отладка выберите пункт Параметры.
  2. В диалоговом окне Параметры откройте узел Отладка и щелкните символы.
  3. Убедитесь, что Поиск в указанных выше расположениях выполняется, только если символы загружаются вручную , если не требуется загружать символы вручную при отладке.
  4. Если вы используете символы на удаленном сервере символов, можно повысить производительность, указав локальный каталог, в который могут быть скопированы символы. Для этого введите путь для кэширования символов с сервера символов в этот каталог. Чтобы подключиться к общедоступному серверу символов Майкрософт, необходимо включить этот параметр. Обратите внимание, что при отладке программы на удаленном компьютере каталог кэша ссылается на каталог на удаленном компьютере.
  5. Нажмите кнопку ОК.
  6. Поскольку используется общедоступный сервер символов Майкрософт, появляется диалоговое окно с лицензионным соглашением. Нажмите кнопку Да , чтобы принять условия соглашения и скачать символы в локальный кэш.

Отладка минидампа с помощью WinDbg

Вы также можете использовать WinDbg, отладчик, который является частью средств отладки Windows, для отладки минидампа. WinDbg позволяет выполнять отладку без использования Visual Studio. Сведения о загрузке средств отладки Windows см. в разделе средства отладки Windows в центре разработчиков оборудования для Windows.

После установки средств отладки Windows необходимо ввести путь к символам в WinDbg.

Ввод пути к символам в WinDbg

  1. В меню файл выберите пункт путь к символам.

  2. В окне путь поиска символов введите следующее:

    SRV * c: \ кэш * https://msdl.microsoft.com/download/symbols ;

Использование средств Copy-Protection с мини минидампа

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

Сводка

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