程序员

C++-Dump文件的创建和调试

2019-03-17  本文已影响0人  JasonLiThirty

Dump文件的创建方法

Windows创建Dump文件的API-MiniDumpWriteDump

BOOL
WINAPI
MiniDumpWriteDump(
    _In_ HANDLE hProcess,
    _In_ DWORD ProcessId,
    _In_ HANDLE hFile,
    _In_ MINIDUMP_TYPE DumpType,
    _In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
    _In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
    _In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    );

Windows保存Dump信息结构体-MINIDUMP_EXCEPTION_INFORMATION

typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
    DWORD ThreadId; 
    PEXCEPTION_POINTERS ExceptionPointers;
    BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;

编写创建生成Dump文件的函数

bool CreateDumpFile(std::string filePath , PEXCEPTION_POINTERS pExcept)
{
    MINIDUMP_EXCEPTION_INFORMATION exceptInfo;
    exceptInfo.ExceptionPointers = pExcept;
    exceptInfo.ThreadId = GetCurrentThreadId();
    exceptInfo.ClientPointers = TRUE;

    HANDLE dumpFile = ::CreateFile((LPCSTR)filePath.c_str(), GENERIC_WRITE, 0, NULL,
                    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (dumpFile != INVALID_HANDLE_VALUE)
    {
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, MiniDumpNormal, &exceptInfo, NULL, NULL);
        CloseHandle(dumpFile);
        return true;
    }
    return false;
}

创建生成Dump 文件的文件名函数

std::string GetDumpFileName()
{
    std::stringstream fn;
    std::time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    fn << GetTempFolder() << "SysCrash_" << std::put_time(std::localtime(&tt), "%Y-%m-%d-%H.%M.%S") << ".dmp";
    return fn.str().c_str();
}

创建需要交给windows(程序崩溃时)的回调函数

LONG WINAPI SysExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
    if (IsDebuggerPresent())
    {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    std::string filename = GetDumpFileName();
    dhlLog.LOG_ERR("System Crashed!");
    if (CreateDumpFile(filename, lpExceptionInfo))
    {
        dhlLog.LOG_INFO("Dump File: %s", filename.c_str());
    }
    
    return EXCEPTION_EXECUTE_HANDLER; //stop in the crash point
    //return EXCEPTION_CONTINUE_EXECUTION; //continue runing to next step
    //return EXCEPTION_CONTINUE_SEARCH; //continuous running the crash point
}

在应用程序中设置异常发生时调用的函数

SetUnhandledExceptionFilter(SysExceptionFilter); //start
SetUnhandledExceptionFilter(NULL); //end opt

Dump文件的调试

保留pdb文件

调试

Release工程下如何生成PDB

VS工程设置Release下生成PDB

CMake设置VS工程的Release下生成PDB

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")

对应于

set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")

set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")

对应于

关于工程设置选项的解释

Use of /Zi does not affect optimizations. However, /Zi does imply /debug;
https://docs.microsoft.com/en-us/cpp/build/reference/z7-zi-zi-debug-information-format?view=vs-2015


https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info?view=vs-2015


https://docs.microsoft.com/en-us/cpp/build/reference/opt-optimizations?view=vs-2015

参考了以下大神的文章

https://blog.csdn.net/bingqingsuimeng/article/details/73497198

上一篇下一篇

猜你喜欢

热点阅读