vs2019+qt工程中如何生成dump文件及調(diào)試詳解
一、調(diào)試前置條件
1、在編譯之后,exe和pdb文件均需要發(fā)布給用戶;
二、抓取異常的系統(tǒng)函數(shù)區(qū)分
AddVectoredExceptionHandler和SetUnhandledExceptionFilter
AddVectoredExceptionHandler 是“第一現(xiàn)場觀察者”,
SetUnhandledExceptionFilter 是“最后兜底處理者”。
當(dāng)一個(gè)異常發(fā)生時(shí),Windows 內(nèi)部順序是:
``1?? Vectored Exception Handlers (VEH)
↓
2?? 線程的 SEH (__try / __except)
↓
3?? C++ try / catch
↓
4?? UnhandledExceptionFilter (UEF)
↓
5?? Windows 默認(rèn)異常處理(彈框 / 進(jìn)程終止)`
| 對比項(xiàng) | VEH | UEF |
|---|---|---|
| 調(diào)用時(shí)機(jī) | 最早 | 最后 |
| 是否能看到 first-chance | ? 能 | ? 不能 |
| 是否會(huì)被覆蓋 | ? 不會(huì) | ? 經(jīng)常 |
| 穩(wěn)定性 | ????? | ?? |
| 使用難度 | 高 | 低 |
| 線上推薦 | ? | ? |
三、可直接復(fù)用的代碼:
CrashDump.h:
#pragma once
#include <Windows.h>
class CrashDump
{
public:
static void Install();
private:
static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ep);
static void WriteDump(PEXCEPTION_POINTERS ep);
private:
static volatile LONG s_dumped;
};
CrashDump.cpp
#include "CrashDump.h"
#include <DbgHelp.h>
#include <strsafe.h>
#pragma comment(lib, "Dbghelp.lib")
volatile LONG CrashDump::s_dumped = 0;
void CrashDump::Install()
{
AddVectoredExceptionHandler(1, VectoredHandler);
}
static bool IsFatalException(DWORD code, DWORD flags)
{
// 明確忽略的異常(正常流程)
switch (code)
{
case EXCEPTION_BREAKPOINT:
case EXCEPTION_SINGLE_STEP:
case 0xE06D7363: // C++ Exception
return false;
default:
break;
}
// 不可繼續(xù)異常 → 一定是致命的
if (flags & EXCEPTION_NONCONTINUABLE)
return true;
// 常見致命異常
switch (code)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
case EXCEPTION_DATATYPE_MISALIGNMENT:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_IN_PAGE_ERROR:
case EXCEPTION_STACK_OVERFLOW:
return true;
default:
return false;
}
}
LONG CALLBACK CrashDump::VectoredHandler(PEXCEPTION_POINTERS ep)
{
if (!ep || !ep->ExceptionRecord)
return EXCEPTION_CONTINUE_SEARCH;
DWORD code = ep->ExceptionRecord->ExceptionCode;
DWORD flags = ep->ExceptionRecord->ExceptionFlags;
// ? 只處理真正致命異常
if (!IsFatalException(code, flags))
return EXCEPTION_CONTINUE_SEARCH;
if (InterlockedCompareExchange(&s_dumped, 1, 0) == 0)
{
WriteDump(ep);
// ?真正崩潰點(diǎn),立即終止
TerminateProcess(GetCurrentProcess(), code);
}
return EXCEPTION_CONTINUE_SEARCH;
}
void CrashDump::WriteDump(PEXCEPTION_POINTERS ep)
{
wchar_t dir[MAX_PATH] = { 0 };
GetModuleFileNameW(nullptr, dir, MAX_PATH);
wchar_t* slash = wcsrchr(dir, L'\\');
if (slash) *slash = 0;
SYSTEMTIME st;
GetLocalTime(&st);
DWORD pid = GetCurrentProcessId();
DWORD tid = GetCurrentThreadId();
wchar_t path[MAX_PATH] = { 0 };
StringCchPrintfW(
path,
MAX_PATH,
L"%s\\DumpFile-%04d%02d%02d-%02d%02d%02d-P%u-T%u.dmp",
dir,
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond,
pid, tid);
HANDLE hFile = CreateFileW(
path,
GENERIC_WRITE,
0,
nullptr,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr);
if (hFile == INVALID_HANDLE_VALUE)
return;
MINIDUMP_EXCEPTION_INFORMATION mei = {};
mei.ThreadId = tid;
mei.ExceptionPointers = ep;
mei.ClientPointers = FALSE;
MINIDUMP_TYPE type = (MINIDUMP_TYPE)(
MiniDumpWithFullMemory |
MiniDumpWithThreadInfo |
MiniDumpWithHandleData |
MiniDumpWithUnloadedModules);
MiniDumpWriteDump(
GetCurrentProcess(),
pid,
hFile,
type,
&mei,
nullptr,
nullptr);
CloseHandle(hFile);
}
在main函數(shù)中調(diào)用:
CrashDump::Install(); QApplication a(argc, argv); ...
四、調(diào)試:
1、將dump文件放在對應(yīng)的exe、pdb文件同級目錄下;
2、
1)使用Visual Studio打開dump文件,然后設(shè)置符號路徑,路徑下需要有exe、pdb、dump;

2)點(diǎn)擊“使用僅限本機(jī)進(jìn)行調(diào)試”,即可重新異常情況;
總結(jié)
到此這篇關(guān)于vs2019+qt工程中如何生成dump文件及調(diào)試的文章就介紹到這了,更多相關(guān)vs2019 qt生成dump文件及調(diào)試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(123.買股票的最佳時(shí)間之三)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(123.買股票的最佳時(shí)間之三),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++實(shí)現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解
這篇文章主要介紹了如何利用C++實(shí)現(xiàn)帶頭雙向循環(huán)鏈表,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-12-12
一篇文章教你自己動(dòng)手實(shí)現(xiàn)C語言庫函數(shù)
這篇文章主要介紹了C語言庫函數(shù)的相關(guān)資料,小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2021-09-09
淺談c++性能測試工具之計(jì)算時(shí)間復(fù)雜度
有時(shí)候除了測量算法的具體性能指數(shù),我們也會(huì)希望測試出算法的時(shí)間復(fù)雜度,以便我們對待測試的算法的性能有一個(gè)更加直觀的了解。本文將介紹c++性能測試工具之計(jì)算時(shí)間復(fù)雜度。2021-06-06

