win下dmp生成和调试

 

1、使用多字节字符集
2、预处理添加:

_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_DEPRECATE

 

#pragma once
#include <windows.h>
#include <stdio.h>
#include <imagehlp.h>
#include <stdlib.h>

#pragma comment(lib, "dbghelp.lib")

inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName)
{
    if (pModuleName == 0)
    {
        return FALSE;
    }

    WCHAR szFileName[_MAX_FNAME] = L"";
    _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);
    if (wcsicmp(szFileName, L"ntdll") == 0)
        return TRUE;

    return FALSE;
}

inline BOOL CALLBACK MiniDumpCallback(PVOID                            pParam,
    const PMINIDUMP_CALLBACK_INPUT   pInput,
    PMINIDUMP_CALLBACK_OUTPUT        pOutput)
{
    if (pInput == 0 || pOutput == 0)
        return FALSE;

    switch (pInput->CallbackType)
    {
    case ModuleCallback:
        if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg)

            if (!IsDataSectionNeeded(pInput->Module.FullPath))

                pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);

    case IncludeModuleCallback:
    case IncludeThreadCallback:
    case ThreadCallback:
    case ThreadExCallback:
        return TRUE;

    default:;
    }

    return FALSE;
}

//创建Dump文件
inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName)
{
    HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
    {
        MINIDUMP_EXCEPTION_INFORMATION mdei;
        mdei.ThreadId = GetCurrentThreadId();
        mdei.ExceptionPointers = pep;
        mdei.ClientPointers = FALSE;
        MINIDUMP_CALLBACK_INFORMATION mci;
        mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
        mci.CallbackParam = 0;
        // MiniDumpNormal 会有线程调用堆栈的信息,MiniDumpWithDataSegs会在 MiniDumpNormal 的基础上加上全局变量
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithDataSegs, &mdei, NULL, &mci);

        CloseHandle(hFile);
    }
}

LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
    return NULL;
}

BOOL PreventSetUnhandledExceptionFilter()
{
#ifdef _WIN64
    return TRUE;
#else
    HMODULE hKernel32 = LoadLibrary("kernel32.dll");
    if (hKernel32 == NULL)
        return FALSE;


    void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
    if (pOrgEntry == NULL)
        return FALSE;


    unsigned char newJump[100];
    DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
    dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far


    void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
    DWORD dwNewEntryAddr = (DWORD)pNewFunc;
    DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;


    newJump[0] = 0xE9;  // JMP absolute
    memcpy(&newJump[1], &dwRelativeAddr, sizeof(pNewFunc));
    SIZE_T bytesWritten;
    BOOL bRet = WriteProcessMemory(GetCurrentProcess(), pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
    return bRet;
#endif
}


LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
    SYSTEMTIME stSysTime;
    memset(&stSysTime, 0, sizeof(SYSTEMTIME));
    GetLocalTime(&stSysTime);
    //根据字符集,有时候可能为WCHAR
    TCHAR szFile[MAX_PATH] = { 0 };
    wsprintf(szFile, "%0.4d-%0.2d-%0.2d-%0.2d-%0.2d-%0.2d-%0.3d.dmp", \
        stSysTime.wYear, stSysTime.wMonth, stSysTime.wDay, stSysTime.wHour, \
        stSysTime.wMinute, stSysTime.wSecond, stSysTime.wMilliseconds);

    CreateMiniDump(pException, szFile);

    return EXCEPTION_CONTINUE_SEARCH;
}

//运行异常处理
void RunCrashHandler()
{
    SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
    PreventSetUnhandledExceptionFilter();
}

 

#include <iostream>
#include "minidmp.h"

int main()
{
    RunCrashHandler();

    int* pTest = NULL;
    *pTest = 1;
}

 

 

调试

 

 

posted @ 2020-07-19 11:54  osbreak  阅读(276)  评论(0编辑  收藏  举报