我是靠谱客的博主 端庄豌豆,最近开发中收集的这篇文章主要介绍win程序捕获系统异常防止突然闪退,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#include <QApplication>
#include <QDir>
#include <QString>
#include <QMessageBox>
#include <winsock2.h>
#include <dbghelp.h>
#include <windows.h>
#include <winnt.h>
#include <tlhelp32.h>

LONG ExceptionCap(EXCEPTION_POINTERS *pException)
{
    const int TIMESTRLEN = 32;
    WCHAR timeStr[TIMESTRLEN];
    SYSTEMTIME time;
    GetLocalTime(&time);
    swprintf_s(timeStr, TIMESTRLEN, L"%4d%02d%02d%02d%02d%02d", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
    WCHAR strname[MAX];
    swprintf_s(strname, MAX, L"application_%s.dmp", timeStr);
    LOG("create core dump file: application_%4d%02d%02d%02d%02d%02d.dmp", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);

    //创建 Dump 文件
    HANDLE hDumpFile = CreateFile(strname, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
    if( hDumpFile != INVALID_HANDLE_VALUE)
    {
        //Dump信息
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;
        //写入Dump文件内容
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, nullptr, nullptr);
    }

    WCHAR		Module_Name[MAX];
    GetModuleFileName(NULL, Module_Name, MAX);
    OG("Module_Name: %s", QString::fromWCharArray(Module_Name).toStdString().c_str());

    if (IsNotNullPtr(pException))
    {
        EXCEPTION_RECORD& exccptionRecord = *pException->ExceptionRecord;
        CONTEXT& contextRecord = *pException->ContextRecord;

        LOG("Exception Addr:  %016X", (uint64_t)exccptionRecord.ExceptionAddress);
        LOG("Exception Code:  %08X", exccptionRecord.ExceptionCode);

        if (exccptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
        {
            // Access violation type - Write/Read.
            LOG("%s Address:  %016X", (exccptionRecord.ExceptionInformation[0]) ? "Write" : "Read", (uint64_t)exccptionRecord.ExceptionInformation[1]);
        }
        
    	QString tString;
    	char szBuffer[512] = { 0 };
        tString.clear();
        for (int i = 0; i < 16; i++)
        {
            sprintf(szBuffer, " %02X",  PBYTE(exccptionRecord.ExceptionAddress)[i]);
            tString.append(szBuffer);
        }
        LOG("Instruction: %s", tString.toStdString().c_str());
        LOG("Registers:");
        sprintf(szBuffer, "RAX: %016X  RBX: %08X  RCX: %08X  RDX: %08X",  contextRecord.Rax, contextRecord.Rbx,  contextRecord.Rcx, contextRecord.Rdx);
        sprintf(szBuffer, "RSI: %016X  RDI: %016X  RSP: %016X  RBP: %016X", contextRecord.Rsi, contextRecord.Rdi, contextRecord.Rsp, contextRecord.Rbp);
        sprintf(szBuffer, "RIP: %016X  EFlags: %016X", contextRecord.Rip, contextRecord.EFlags);
    }

    //弹出错误对话框并退出程序
    EXCEPTION_RECORD* record = pException->ExceptionRecord;
    QString errCode(QString::number(record->ExceptionCode,16)), errAdr(QString::number(reinterpret_cast<uint64_t>(record->ExceptionAddress),16)), errMod;
    QMessageBox::critical(NULL, "Application Crashed!!!","<FONT size=4><div><b>程序异常!</b><br/></div>" + QString("<div>错误代码:%1</div><div>错误地址:%2</div></FONT>").arg(errCode).arg(errAdr),QMessageBox::Ok);

    return EXCEPTION_EXECUTE_HANDLER;
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    //[注冊异常捕获函数]
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ExceptionCap);
    return app.exec();
}

最后

以上就是端庄豌豆为你收集整理的win程序捕获系统异常防止突然闪退的全部内容,希望文章能够帮你解决win程序捕获系统异常防止突然闪退所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(59)

评论列表共有 0 条评论

立即
投稿
返回
顶部