MiniDump

Posted 秋月的私语

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MiniDump相关的知识,希望对你有一定的参考价值。

#pragma once

void RunCrashHandler();
#include "MiniDump.h"
#include <windows.h>
#include <imagehlp.h>
#include <stdlib.h>
#include <tchar.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);
    _wsplitpath_s(pModuleName, NULL, 0, NULL, 0, szFileName, 0, NULL, 0);
    //if (wcsicmp(szFileName, L"ntdll") == 0)
    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;
        MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)0x0000ffff;
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, &mci);
        CloseHandle(hFile);
    }
}

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

BOOL PreventSetUnhandledExceptionFilter()
{
    HMODULE hKernel32 = LoadLibrary(_T("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;
}

LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
    TCHAR szMbsFile[MAX_PATH] = { 0 };
    ::GetModuleFileName(NULL, szMbsFile, MAX_PATH);
    TCHAR* pFind = _tcsrchr(szMbsFile, \\);
    if (pFind)
    {
        *(pFind + 1) = 0;
        //_tcscat(szMbsFile, _T("CreateMiniDump.dmp"));
        _tcscat_s(szMbsFile, _T("CreateMiniDump.dmp"));
        CreateMiniDump(pException, szMbsFile);
    }
    // TODO: MiniDumpWriteDump
    FatalAppExit(-1, _T("Fatal Error"));
    return EXCEPTION_CONTINUE_SEARCH;
}

//运行异常处理
void RunCrashHandler()
{
    static bool bIni = false;
    if (!bIni)
    {
        SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
        PreventSetUnhandledExceptionFilter();
        bIni = true;
    }
}

 

以上是关于MiniDump的主要内容,如果未能解决你的问题,请参考以下文章

Windows 应用生成MiniDump文件的方法笔记

MiniDump

linux下使用dmp输出堆栈信息方法说明

以下是有windbg分析的蓝屏代码,请高手分析下原因

Effective minidump

Effective minidump