本文是講 用VS如何調試.dmp(比較高版本的VS,本文是vs2017):
人爲製造一個崩潰,先直接看效果圖:
下面是實現過程,本文是VS2017爲例:
dump.h:
點擊查看代碼
#pragma once
// dump.h
#include <windows.h>
extern LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo);
dump.cpp:
點擊查看代碼
// dump.cpp
#include <stdio.h>
#include <windows.h>
#include <dbghelp.h>
#include <stdlib.h>
#include "pch.h" //這行看你工程設置,可以去掉
#pragma comment(lib, "Dbghelp.lib")
#include <DbgHelp.h>
//Creatte DUMP File
int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers, PWCHAR pwAppName)
{
BOOL bOwnDumpFile = FALSE;
HANDLE hDumpFile = hFile;
MINIDUMP_EXCEPTION_INFORMATION ExpParam;
typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
HANDLE,
DWORD,
HANDLE,
MINIDUMP_TYPE,
PMINIDUMP_EXCEPTION_INFORMATION,
PMINIDUMP_USER_STREAM_INFORMATION,
PMINIDUMP_CALLBACK_INFORMATION
);
MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
HMODULE hDbgHelp = LoadLibrary(L"DbgHelp.dll");
if (hDbgHelp)
pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if (pfnMiniDumpWriteDump)
{
if (hDumpFile == NULL || hDumpFile == INVALID_HANDLE_VALUE)
{
TCHAR szFileName[MAX_PATH] = { 0 };
TCHAR dwBufferSize = MAX_PATH;
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
CreateDirectory(szFileName, NULL);
wsprintf(szFileName, L"%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
L"v1.0",
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);
bOwnDumpFile = TRUE;
OutputDebugString(szFileName);
}
if (hDumpFile != INVALID_HANDLE_VALUE)
{
ExpParam.ThreadId = GetCurrentThreadId();
ExpParam.ExceptionPointers = pExceptionPointers;
ExpParam.ClientPointers = FALSE;
pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &ExpParam : NULL), NULL, NULL);
if (bOwnDumpFile)
CloseHandle(hDumpFile);
}
}
if (hDbgHelp != NULL)
FreeLibrary(hDbgHelp);
return EXCEPTION_EXECUTE_HANDLER;
}
LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
if (IsDebuggerPresent())
{
return EXCEPTION_CONTINUE_SEARCH;
}
return GenerateMiniDump(NULL, lpExceptionInfo, PWCHAR("test"));
}
//用到的地方加入這個頭文件
#include "dump.h"
//程序初始化時,加入這個代碼:
::SetUnhandledExceptionFilter(ExceptionFilter);
人爲製造一個崩潰:
int *pTest = NULL; (*pTest) = 1;
Release版設置:
VS 工具(T) ->選項(O)…:
把這個.dmp文件,直接用VS打開:
定位到了出錯的代碼行:
發佈時,主要是 4個要素:
1、.exe文件(或.dll)
2、對應的.pdb文件
3、崩潰後的.dmp文件
4、對應的結點代碼(當時編譯出這個exe/dll的代碼,提前留個備份,比如 SVN / git 上的結點、代碼打包rar/zip的備份、代碼文件夾備份……)
本文主體內容至此已完結,下面有興趣可以研究一下,那 4個要素 的對應過程:
首先,一個獨立的.dmp,用vs打開,使用調試,會發生什麼?
好,然後把這個 .exe放到.dmp同目錄下,再調試:
好,然後再把這個.pdb放到.dmp同目錄下,再調試:
找到這個.cpp,並把這個文件小改動一下保存:
在剛VS的打開.cpp對話框中,打開這個.cpp:
先選擇否,把剛.cpp還原至發佈時(即去掉剛加入的那個空格,再保存),再用VS重新打開這個.cpp:
這下明白了那 4要素 的作用了吧?
————————————————
版權聲明:本文爲CSDN博主「maoyeahcom」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/maoyeahcom/article/details/108583124