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();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值