Подтвердить что ты не робот

Как написать пример кода, который приведет к сбою и созданию файла дампа?

Я начал изучать windbg, и я нашел этот хороший пост Как использовать WinDbg для анализа дампа сбоя для приложения VС++?

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

Как написать такой код?

void Example4()
{
    int* i = NULL;
    *i = 80;
}

Вышеуказанный код немедленно сработает; однако, я не знаю, где найти файл дампа?

Спасибо

4b9b3361

Ответ 1

#include <Windows.h>
#include <Dbghelp.h>

void make_minidump(EXCEPTION_POINTERS* e)
{
    auto hDbgHelp = LoadLibraryA("dbghelp");
    if(hDbgHelp == nullptr)
        return;
    auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
    if(pMiniDumpWriteDump == nullptr)
        return;

    char name[MAX_PATH];
    {
        auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
        SYSTEMTIME t;
        GetSystemTime(&t);
        wsprintfA(nameEnd - strlen(".exe"),
            "_%4d%02d%02d_%02d%02d%02d.dmp",
            t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
    }

    auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if(hFile == INVALID_HANDLE_VALUE)
        return;

    MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
    exceptionInfo.ThreadId = GetCurrentThreadId();
    exceptionInfo.ExceptionPointers = e;
    exceptionInfo.ClientPointers = FALSE;

    auto dumped = pMiniDumpWriteDump(
        GetCurrentProcess(),
        GetCurrentProcessId(),
        hFile,
        MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
        e ? &exceptionInfo : nullptr,
        nullptr,
        nullptr);

    CloseHandle(hFile);

    return;
}

LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e)
{
    make_minidump(e);
    return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
    SetUnhandledExceptionFilter(unhandled_handler);

    return *(int*)0;
}

Ответ 3

Если вы хотите увидеть дамп сбоя, вам нужно создать его. См. Heisenbug: сбой WinApi на некоторых компьютерах. Хотя вы можете получить дамп сбоя, предназначенный для отправки WER без прохождения WinQual, это немного беспорядочно (в основном вы можете скопировать его из временного местоположения до его отправки, точные данные зависят от вашей операционной системы), Я бы рекомендовал создать собственный crashdump, используя предоставленные функции Win API MiniDump. Весь код, необходимый для этого, можно найти на Страница CodeProject, упомянутая в связанном ответе.

Ответ 4

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

Параметр реестра, определяющий отладчик после вскрытия, HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

Посмотрите на строку Debugger, и вы будете на пути к поиску мини-дисков.

Ответ 5

Файл дампа может быть создан либо программным способом, либо средством отладки программной ошибки. В первом случае вы можете использовать функцию MiniDumpWriteDump, а во втором вы можете использовать Dr. Watson (для XP: посмотрите на это описание и это очень описательное video, для Vista, посмотрите здесь)

Ответ 6

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

  • Приведенный ниже код работает и будет генерировать аварийный дамп
  • Существует две функции, позволяющие видеть трассировку стека с очевидной цепочкой функций.
  • Чтобы найти дампы сбоев, найдите *.dmp или *.mdmp в C:\Users
  • Вероятно, лучше всего позволить ОС генерировать дамп для вас. Вероятно, это будет сгенерировано большинство реальных аварийных дампов.
  • Код работает, сначала выделяя 1 KiB памяти, затем записывая как это, так и следующее 1 KiB с распознаваемым шестнадцатеричным значением. Обычно это попадает на страницу с памятью, отмеченную ОС, как не записываемую, что приведет к сбою.

#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"

void Function2(int * ptr2)
{
    for(int i=0; i < (2 * 1024); i++)
    {
        *ptr2++ = 0xCAFECAFE;
    }
}

void Function1()
{
    int * ptr1 = (int *)malloc(1024 * sizeof(int));

    Function2(ptr1);
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("Press enter to allocate and corrupt.\r\n");
    getc(stdin);

    printf("Allocating and corrupting...\r\n");
    Function1();

    printf("Done.  Press enter to exit process.\r\n");
    getc(stdin);

    return 0;
}

Ответ 7

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

a) в случае переполнения буфера или код, который обрабатывает необработанное исключение, может быть поврежден. В случае исключения OutOfMemoryException, как вы можете загрузить другую библиотеку, такую ​​как DbgHelp.dll?

b) код, который вы написали, может быть ошибочным. Проверяет ли этот код свободное место на диске перед записью дампа? Как вы тестируете код для создания аварийного дампа? У вас есть unit test для этого? Как ваш unit test проверяет правильность дампа?

c) зачем писать код вообще, если Windows может сделать это за вас?

В MSDN есть статья о Сбор дампов режима пользователя. В основном, есть некоторые настройки реестра, которые вы можете сделать. Преимущество: Windows создаст аварийный дамп операционной системой, а не каким-то поврежденным кодом внутри вашего собственного приложения.

Ответ 8

В большинстве случаев вы обнаружите, что все приложения выгружаются в C:\windows\minidumps.

Чтобы создать файл дампа, вы можете использовать простое решение:

  • Открыть windbg
  • Файл- > Открыть исполняемый файл
  • Вы запускаете приложение, которое будет аварийно завершено
  • Точка останова вызовет
  • Теперь вы можете использовать .dump в windbg для создания файла dmp

или

  • Запустите приложение и подождите, чтобы сбой
  • Откройте windbg и присоедините к процессу (File- > Attach to process)
  • запустить .dump

Таким образом, вы сможете анализировать этот сбой в любое время:)

Ответ 9

Попробуйте следующее:

int main()
{
   int v[5];

   printf("%d", v[10]);
   return 0;
}

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