[Qt5.15.2][0.1]捕获异常信息并进行错误定位

注意:部分代码收集于网络。

.pro

#生成dump文件需要
LIBS += -lDbgHelp

swcrash.h

#ifndef SWCRASH_H
#define SWCRASH_H

#include <windows.h>
//
#include "qdebug.h"
#include "qmessagebox.h"
#include <dbghelp.h> //捕获异常地址,用addr2line进行查找具体代码位置
#include <signal.h> //捕获SIGSEGV

void swcrashInit();

#endif // SWCRASH_H

swcrash.cpp

#include "swcrash.h"

/**
 *  @brief  程序异常捕获
 *  @param
 *  @retval
 */
LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException) {
  // 创建 Dump 文件
  qWarning() << "=========================异常信息==========================";
  QString createPath = QCoreApplication::applicationDirPath() + "/dumps";
  QDir dir;
  dir.mkpath(createPath);
  createPath = QString("%1/dump_%2.dmp")
                   .arg(createPath)
                   .arg(QDateTime::currentDateTime().toString(
                       "yyyy_MM_dd_hh_mm_ss_zzz"));
  std::wstring wlpstr = createPath.toStdWString();
  LPCWSTR lpcwStr = wlpstr.c_str();

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

    qWarning() << "ExceptionPointers:" << dumpInfo.ExceptionPointers;
  }
  // 这里弹出一个错误对话框并退出程序
  EXCEPTION_RECORD *record = pException->ExceptionRecord;
  QString errCode(QString::number(record->ExceptionCode, 16)),
      errAdr(QString::number((UINT)((UINT_PTR)record->ExceptionAddress), 16));

  qWarning() << "ExceptionCode:" << errCode;
  qWarning() << "ExceptionAddress:" << errAdr;
  qWarning() << "ExceptionInformation:" << record->ExceptionInformation;
  qWarning() << "NumberParameters:" << record->NumberParameters;
  qWarning() << "========================================================";

  QMessageBox::critical(NULL, "异常信息",
                        "<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;
}

/**
 *  @brief  打印异常信息
 *  @param
 *  @retval
 */
void SegmentationHandle(int sig) {
  qWarning() << "=========================致命错误==========================";
  qWarning() << "Segmentation value:" << sig;
  switch (sig) {
  case 11:
    qWarning() << "SIGSEGV";
    break;
    // 其它错误号码,以后遇到在增加
  default:
    break;
  }
  qWarning() << "========================================================";
}

/**
 *  @brief  初始化异常信息捕获
 *  @param
 *  @retval
 */
void swcrashInit() {
  // 注冊异常捕获函数
  SetUnhandledExceptionFilter(
      (LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);

  // 系统异常信号
  signal(SIGSEGV, SegmentationHandle);
  signal(SIGINT, SegmentationHandle);
  // 后续遇到其它信号再增加
}

使用方法

#include <QApplication>

#include "mainwindow.h"
#include "swlog.h"
#include "swcrash.h"

int main(int argc, char *argv[]) {
  LogFileInit();  // 生成log.txt
  swcrashInit(); // 捕获异常信息
  QApplication a(argc, argv);
  MainWindow w;
  w.show();
  return a.exec();
}

然后用addr2line -f -e xxxx.exe 40c463去定位故障位置。

提示:

1.自动在执行文件的目录新建一个dumps的文件夹。

2.该方法不可以获取 class的空指针,例如:   QPushButton *ab = nullptr。

3.对于int类型空指针有效,例如: int *a = nullptr。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值