查看完整版本: [-- qt 获取windows下崩溃日志的三种方法 --]

QTCN开发网 -> Qt基础编程 -> qt 获取windows下崩溃日志的三种方法 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

shixingya 2018-05-07 10:39

qt 获取windows下崩溃日志的三种方法

long __stdcall   MinGW_Callback(_EXCEPTION_POINTERS*   excp)
{
    CCrashStack crashStack(excp);
    QString sCrashInfo = crashStack.GetExceptionInfo();
    qDebug()<<"发生错误MinGW_Callback:\n"<<sCrashInfo;


    QMessageBox box;
    QString msg ="";
    msg.append("亲,我死了,重新启动下吧!");
  
    qDebug()<<msg;
    box.setWindowTitle("错误报告");
    box.setText(msg);
    ::SetCursor(LoadCursor(NULL,   IDC_ARROW));
    box.exec();


    return   EXCEPTION_EXECUTE_HANDLER;
}
参考帖子 https://blog.csdn.net/wangshubo1989/article/details/52586516

shixingya 2018-05-07 10:41
方式二

方式二
static LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)
{
    ::SetCursor(LoadCursor(NULL,   IDC_NO));
    //And output crash information
    EXCEPTION_RECORD *record = pException->ExceptionRecord;
    QString errCode(QString::number(record->ExceptionCode, 16));
    QString errAddr(QString::number((uint)record->ExceptionAddress, 16));
    QString errFlag(QString::number(record->ExceptionFlags, 16));
    QString errPara(QString::number(record->NumberParameters, 16));
    qDebug()<<"errCode: "<<errCode;
    qDebug()<<"errAddr: "<<errAddr;
    qDebug()<<"errFlag: "<<errFlag;
    qDebug()<<"errPara: "<<errPara;
    //Create the dump file
    QString DumpFilePath =UserCacheDataDir;
    DumpFilePath.append("/").append(QString::number(getTimeStamp())).append(".dmp");

    HANDLE hDumpFile = CreateFile((LPCWSTR)DumpFilePath.utf16(),
                                  GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    QString errUrl="";
    if(hDumpFile != INVALID_HANDLE_VALUE) {
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;
        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
        CloseHandle(hDumpFile);
        qDebug()<<"生成DMP文件"<<DumpFilePath;  

    QMessageBox box;
    QString msg ="";
    msg.append("亲,我死了,重新启动下吧!").append(" \n详细错误信息见: ").append(DumpFilePath);
    if(errUrl !="")
    {
        msg.append(" ;错误文件已经上传,地址为:").append(errUrl);
    }
    qDebug()<<msg;
    box.setText(msg);
    ::SetCursor(LoadCursor(NULL,   IDC_ARROW));
    box.exec();
    return EXCEPTION_EXECUTE_HANDLER;
}

九重水 2018-05-07 14:42

shixingya 2018-05-07 16:54
方式三 : 主要针对VS下pdb文件

#include "preheader.h"
#include "MiniDump.h"
#include <DbgHelp.h>
#include <strsafe.h>

MiniDump::MiniDump(void)
{
    SetErrorMode(SEM_FAILCRITICALERRORS);
    SetUnhandledExceptionFilter(&MiniDump::UnhandledExceptionFilter);
}


MiniDump::~MiniDump(void)
{
}


LONG WINAPI MiniDump::UnhandledExceptionFilter(LPEXCEPTION_POINTERS lpExceptionInfo)
{
    if(IsDebuggerPresent())
    {
        return EXCEPTION_CONTINUE_SEARCH;
    }

    return GenerateMiniDump(NULL, lpExceptionInfo);
}

int MiniDump::GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExceptionPointers)
{
    char szErrorMsg[MAX_PATH];
    StringCchPrintfA(szErrorMsg, MAX_PATH, "An unexpected error has occured: \n\nFETAL ERROR!\n\nException: 0x%08x at 0x%p\n\nPressing OK will terminate the application and save the helpful debugging information that may help us resolve this issue in the future.", pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionAddress);

    QMessageBox box(QMessageBox::Question,"批改系统崩溃","亲,我死了,是否生成错误报告?");
    box.setStandardButtons (QMessageBox::Ok|QMessageBox::Cancel);
    box.setDefaultButton(QMessageBox::Ok);
    box.setButtonText (QMessageBox::Ok,QString("确 定"));
    box.setButtonText (QMessageBox::Cancel,QString("取 消"));
    box.setWindowFlags(Qt::WindowStaysOnTopHint);

    if(box.exec () ==QMessageBox::Ok)
    {
        qDebug()<<"生成Dump文件中";
        BOOL bOwnDumpFile = FALSE;
        HANDLE hDumpFile = hFile;
        MINIDUMP_EXCEPTION_INFORMATION ExpParam;

        typedef BOOL (WINAPI * MiniDumpWriteDump)(
                    HANDLE,
                    DWORD ,
                    HANDLE ,
                    MINIDUMP_TYPE ,
                    PMINIDUMP_EXCEPTION_INFORMATION ,
                    PMINIDUMP_USER_STREAM_INFORMATION ,
                    PMINIDUMP_CALLBACK_INFORMATION
                    );

        MiniDumpWriteDump pfnMiniDumpWriteDump = NULL;
        HMODULE hDbgHelp = LoadLibraryA("DbgHelp.dll");
        if (hDbgHelp)
            pfnMiniDumpWriteDump = (MiniDumpWriteDump)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
        else
            MessageBoxA(NULL, "Error", "File 'DbgHelp.dll' failed to load", MB_OK | MB_ICONERROR);

        if (pfnMiniDumpWriteDump)
        {
            if (hDumpFile == NULL || hDumpFile == INVALID_HANDLE_VALUE)
            {
                char szPath[MAX_PATH] = {0};
                GetModuleFileNameA(NULL, szPath, MAX_PATH);
                char* pChar = strrchr(szPath, '\\');
                if (NULL != pChar)
                {
                    int iPos = pChar - szPath;
                    szPath[iPos + 1] = '\0';
                }

                char szFileName[MAX_PATH] = {0};
                const char* szAppName = "BIM5D Crash Report-";
                SYSTEMTIME stLocalTime;
                GetLocalTime(&stLocalTime);

                StringCchPrintfA(szFileName, MAX_PATH, "%s%s-%04d%02d%02d-%02d%02d%02d.dmp", szPath, szAppName,
                                 stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
                                 stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);

                hDumpFile = CreateFileA(szFileName, GENERIC_READ|GENERIC_WRITE,
                                        FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

                bOwnDumpFile = TRUE;
            }

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

    }
    qDebug()<<"程序退出";
    return   EXCEPTION_EXECUTE_HANDLER;

}


查看完整版本: [-- qt 获取windows下崩溃日志的三种方法 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled