QT--崩溃原因分析

news2025/2/26 14:23:56

本文为学习记录,若有错误,请联系作者,谦虚受教。

文章目录

  • 前言
  • 一、目的
  • 二、实现步骤
    • 1 add2line.exe
    • 2 分析文件
    • 3 crash文件
  • 三、相关代码
    • 1 pro文件
    • 2.ccrashstack.h
    • 3.ccrashstack.cpp
    • 4.main.cpp
  • 总结


前言

你从来来去自由,若你不想要了跑开便是。


一、目的

发布的客户版本里分析崩溃原因,便于解决问题。

二、实现步骤

1 add2line.exe

在自己QT安装的目录下,例如:D:\Qt\Qt5.12.3\Tools\mingw730_32\bin,找到adde2line.exe。
在这里插入图片描述
将add2line.exe复制到自己发布的版本中。
在这里插入图片描述

2 分析文件

在代码里添加一个类和发布版本所在文件夹里添加addr2line.exe,后续程序崩溃后,会在工程文件中,代码生成一个MyApp文件夹,里面包含一个crash文件
在这里插入图片描述
在这里插入图片描述

3 crash文件

打开crash文件,找到自己addr。
在这里插入图片描述
打开QT的cmd,进入自己发布版本的路径。例如
1、cd D:\TEST\1QTTEST\Thermopile_HM\32X32\Client\V1.0.1Client\release
2、addr2line.exe -f -e 软件文件名 crash崩溃地址 (提示:中间要空格)
3、提示错误信息
在这里插入图片描述

三、相关代码

1 pro文件

在pro文件添加以下代码:

QMAKE_CFLAGS_RELEASE += -g
QMAKE_CXXFLAGS_RELEASE += -g
QMAKE_CFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_LFLAGS_RELEASE = -mthreads -W

2.ccrashstack.h

#ifndef CCRASHSTACK_H
#define CCRASHSTACK_H
#include <windows.h>
#include <QString>

class ccrashstack
{
private:
    PEXCEPTION_POINTERS m_pException;
private:
    QString GetModuleByRetAddr(PBYTE Ret_Addr, PBYTE & Module_Addr);
    QString GetCallStack(PEXCEPTION_POINTERS pException);
    QString GetVersionStr();
    bool GetHardwareInaformation(QString &graphics_card, QString &sound_deivce);
public:
    ccrashstack(PEXCEPTION_POINTERS pException);
    QString GetExceptionInfo();
};

#endif // CCRASHSTACK_H

3.ccrashstack.cpp

#include "ccrashstack.h"
#include <tlhelp32.h>
#include <stdio.h>

#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>

//#include<base/constants.h>
#include "qdebug.h"

ccrashstack::ccrashstack(PEXCEPTION_POINTERS pException)
{
    m_pException = pException;
}


QString ccrashstack::GetModuleByRetAddr(PBYTE Ret_Addr, PBYTE & Module_Addr)
{
    MODULEENTRY32   M = {sizeof(M)};
    HANDLE  hSnapshot;

    wchar_t Module_Name[MAX_PATH] = {0};

    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);

    if ((hSnapshot != INVALID_HANDLE_VALUE) &&
            Module32First(hSnapshot, &M))
    {
            do
            {
                    if (DWORD(Ret_Addr - M.modBaseAddr) < M.modBaseSize)
                    {
                            lstrcpyn(Module_Name, M.szExePath, MAX_PATH);
                            Module_Addr = M.modBaseAddr;
                            break;
                    }
            } while (Module32Next(hSnapshot, &M));
    }

    CloseHandle(hSnapshot);

    QString sRet = QString::fromWCharArray(Module_Name);
    return sRet;
}

QString ccrashstack::GetCallStack(PEXCEPTION_POINTERS pException)
{
        PBYTE   Module_Addr_1;
        char bufer[256]={0};
        QString sRet;

        typedef struct STACK
        {
                STACK * Ebp;
                PBYTE   Ret_Addr;
                DWORD   Param[0];
        } STACK, * PSTACK;

        STACK   Stack = {0, 0};
        PSTACK  Ebp;

        if (pException)     //fake frame for exception address
        {
                Stack.Ebp = (PSTACK)pException->ContextRecord->Ebp;
                Stack.Ret_Addr = (PBYTE)pException->ExceptionRecord->ExceptionAddress;
                Ebp = &Stack;
        }
        else
        {
                Ebp = (PSTACK)&pException - 1;  //frame addr of Get_Call_Stack()

                // Skip frame of Get_Call_Stack().
                if (!IsBadReadPtr(Ebp, sizeof(PSTACK)))
                        Ebp = Ebp->Ebp;     //caller ebp
        }

        // Break trace on wrong stack frame.
        for (; !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr));
                 Ebp = Ebp->Ebp)
        {
            // If module with Ebp->Ret_Addr found.
            memset(bufer,0, sizeof(0));
            sprintf(bufer, "\n%08X  ", (unsigned int)Ebp->Ret_Addr);
            sRet.append(bufer);

            QString moduleName = this->GetModuleByRetAddr(Ebp->Ret_Addr, Module_Addr_1) ;
            if (moduleName.length() > 0)
            {
                sRet.append(moduleName);
            }

        }

        return sRet;
} //Get_Call_Stack

QString ccrashstack::GetVersionStr()
{
        OSVERSIONINFOEX V = {sizeof(OSVERSIONINFOEX)};  //EX for NT 5.0 and later

        if (!GetVersionEx((POSVERSIONINFO)&V))
        {
                ZeroMemory(&V, sizeof(V));
                V.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
                GetVersionEx((POSVERSIONINFO)&V);
        }

        if (V.dwPlatformId != VER_PLATFORM_WIN32_NT)
                V.dwBuildNumber = LOWORD(V.dwBuildNumber);  //for 9x HIWORD(dwBuildNumber) = 0x04xx

        QString sRet;
        sRet.append(QString("Windows:  %1.%2.%3, SP %4.%5, Product Type %6\n")
                .arg(V.dwMajorVersion).arg(V.dwMinorVersion).arg(V.dwBuildNumber)
                .arg(V.wServicePackMajor).arg(V.wServicePackMinor).arg(V.wProductType));

//        QString graphics_module = "GraphicsCard: ";
//        QString sound_module = "SoundDevice: ";
//        GetHardwareInaformation(graphics_module, sound_module);
//        sRet.append(graphics_module);
//        sRet.append(sound_module);

        return sRet;
}

QString ccrashstack::GetExceptionInfo()
{
        WCHAR       Module_Name[MAX_PATH];
        PBYTE       Module_Addr;

        QString sRet;
        char buffer[512]={0};

        QString sTmp = GetVersionStr();
        sRet.append(sTmp);
        sRet.append("Process:  ");

        GetModuleFileName(NULL, Module_Name, MAX_PATH);
        sRet.append(QString::fromWCharArray(Module_Name));
        sRet.append("\n");

        // If exception occurred.
        if (m_pException)
        {
                EXCEPTION_RECORD &  E = *m_pException->ExceptionRecord;
                CONTEXT &           C = *m_pException->ContextRecord;

                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "Exception Addr:  %08X  ", (int)E.ExceptionAddress);
                sRet.append(buffer);
                // If module with E.ExceptionAddress found - save its path and date.
                QString module = GetModuleByRetAddr((PBYTE)E.ExceptionAddress, Module_Addr);
                if (module.length() > 0)
                {
                    sRet.append(" Module: ");

                    sRet.append(module);
                }

                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "\nException Code:  %08X\n", (int)E.ExceptionCode);
                sRet.append(buffer);

                if (E.ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
                {
                        // Access violation type - Write/Read.
                    memset(buffer, 0, sizeof(buffer));
                    sprintf(buffer,"%s Address:  %08X\n",
                            (E.ExceptionInformation[0]) ? "Write" : "Read", (int)E.ExceptionInformation[1]);
                    sRet.append(buffer);
                }


                sRet.append("Instruction: ");
                for (int i = 0; i < 16; i++)
                {
                    memset(buffer, 0, sizeof(buffer));
                    sprintf(buffer, " %02X",  PBYTE(E.ExceptionAddress)[i]);
                    sRet.append(buffer);
                }

                sRet.append("\nRegisters: ");

                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "\nEAX: %08X  EBX: %08X  ECX: %08X  EDX: %08X",  (unsigned int)C.Eax,(unsigned int) C.Ebx, (unsigned int)C.Ecx, (unsigned int)C.Edx);
                sRet.append(buffer);

                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "\nESI: %08X  EDI: %08X  ESP: %08X  EBP: %08X", (unsigned int)C.Esi, (unsigned int)C.Edi, (unsigned int)C.Esp, (unsigned int)C.Ebp);
                sRet.append(buffer);

                memset(buffer, 0, sizeof(buffer));
                sprintf(buffer, "\nEIP: %08X  EFlags: %08X", (unsigned int)C.Eip,(unsigned int) C.EFlags);
                sRet.append(buffer);

        } //if (pException)

        sRet.append("\nCall Stack:");
        QString sCallstack = this->GetCallStack(m_pException);
        sRet.append(sCallstack);

        return sRet;
}

4.main.cpp

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SetUnhandledExceptionFilter(callback);
    MainWindow w;
    w.show();
    return a.exec();
}

总结

善于总结,多进一步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/862824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】WeUI DatePicker时间组件绑定方法以及chatGPT回答

2023年&#xff0c;第33周&#xff0c;第1篇文章。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; WeUI DatePicker&#xff0c;这个组件在纯html静态文件js里用的比较少&#xff0c;也忘记默认绑定值怎么设置&#xff0c;就用chatGPT来找答…

flutter相关URL schemes

先看效果 使用 url_launcher库 做唤起其他app操作 url_launcher | Flutter Package 配置 安卓 flutter 项目目录下的 android\app\src\main\AndroidManifest.xml 如果不配置的话 有些手机就打不开app 微信有两个 一个是weixin 一个是wechat <queries><!-- If you…

积木报表集成前端加载js文件404

项目场景&#xff1a; 在集成积木报表和shiro时候&#xff1a; 集成积木报表&#xff0c;shrio&#xff0c;shrio是定义在另一个模块下的&#xff0c;供另一个启动类使用&#xff0c;积木报表集成shrio的时候&#xff0c;需要依赖存放shrio的核心包&#xff0c;该核心包除了存…

异步编排CompletableFuture

文章目录 一.简介二.并行加载1.为何需要并行加载2.并行加载的实现方式 三.CompletableFuture使用与原理1.背景和定义2.常用方法3.CompletableFuture的使用3.CompletableFuture原理4.实践总结 一.简介 CompletableFuture由Java 8提供&#xff0c;是实现异步化的工具类&#xff…

JVM—内存管理(运行时数据区)

背景介绍 当JVM类加载器加载完字节码文件之后&#xff0c;会交给执行引擎执行&#xff0c;在执行的过程中会有一块JVM内存区域来存放程序运行过程中的数据&#xff0c;也就是我们图中放的运行时数据区&#xff0c;那这一块运行时数据区究竟帮我们做了哪些工作&#xff1f;我们…

rancher + k3s + docker私有仓库搭建K8环境(百分之百成功)

1.环境准备&#xff08;4台机器&#xff09; 文档准备了4台虚拟机&#xff0c;系统是ubuntu server: ubuntu-22.04.1-live-server-amd64.iso 然后进行安装4台虚拟机&#xff0c;如图&#xff1a; 其中一台用于rancher、其余三台跑K8&#xff0c;一台master&#xff0c;两台工作…

写测试用例、重构函数、生成SQL查询……原来CodeGeeX还能做这些!

CodeGeeX中的智能问答功能“Ask CodeGeeX”可以帮助程序员解答开发过程中遇到的问题。但是“Ask CodeGeeX”的能力不止于此&#xff0c;用它还能帮助程序员高效编写测试用例&#xff0c;添加代码调试信息&#xff0c;实现SQL语句等等。 如果你还不知道如何实现&#xff0c;下面…

途乐证券-新股行情持续火爆,哪些因素影响首日表现?

全面注册制以来&#xff0c;参加打新的投资者数量全体呈现下降。打新收益下降&#xff0c;破发频出的布景下&#xff0c;投资者打新策略从逢新必打逐步向优选个股改变。 经过很多历史数据&#xff0c;从商场定价、参加者热度以及机构重视度维度揭秘了上市后股价体现优秀的个股具…

启动springboot,出现Unable to start embedded Tomcat

报错信息 org.apache.catalina.core.ContainerBase : A child container failed during startjava.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbedd…

AMEYA:ROHM新增5款100V耐压双MOSFET,实现业界超低导通电阻

全球知名半导体制造商ROHM(总部位于日本京都市)面向通信基站和工业设备等的风扇电机驱动应 用&#xff0c;开发出将两枚100V耐压MOSFET* 1一体化封装的双MOSFET新产品。新产品分“HP8KEx/HT8KEx (NchNch)系列”和“HP8MEx(NchPch*2)系列”两个系列&#xff0c;共5款新机型。 近…

知了汇智携手20余所高校开展实习实训,助力数字化人才培养

随着数字化转型推进的深入&#xff0c;企业对数字化人才的需求量大幅增长&#xff0c;人才需求结构也发生显著变化。知了汇智作为一家以就业为导向的产教融合服务机构&#xff0c;始终活跃于“育人”与“用人”的生态圈&#xff0c;通过与高校进行产业学院建设、共建实验室、共…

东南亚海外跨境物流管理,移动支付、数据处理程序开发

境外虚拟物流跨境支付平台快速搭建、集成后台采集功能的步骤如下&#xff1a; 一、项目规划与需求分析 在开始搭建境外虚拟物流跨境支付平台之前&#xff0c;需要进行详细的规划和分析。这包括确定项目的目标、了解客户需求、分析市场环境、确定系统架构和技术选型等。通过深…

一文带你快速了解和入门 Apinto 网关!

Apinto 网关快速入门 是 Eolink 旗下一款专门为微服务架构设计的开源 API 网关&#xff0c;完全由 Go 语言开发&#xff0c; 本文主要带大家认识 Apinto 网关以及如何实现快速入门操作。 首先&#xff0c;让我们一起了解 API 网关的概念。它类似于一个门户&#xff0c;用于管理…

finfet grid

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 90nm 及以下的工艺都要求储存器&#xff0c;IP&#xff0c;IO 的多晶硅方向必须和标准单元的多晶 硅方向保持一致&#xff0c;无法像过去工艺一样随意旋转方向。在 22nm 及以下…

shopee虾皮电商十个选品渠道!Get到了!

今天给大家分享虾皮的十个选品渠道&#xff0c;让选品不是难题&#xff01;话不多都说&#xff0c;往下看&#xff01; 1.搜索栏去搜索 拿台湾站来说&#xff0c;在shopee后台&#xff0c;我们搜索商品衬衫&#xff0c;在商品展示页面点击热销&#xff0c;除去第一排的广告商品…

元年方舟企业数字化PaaS平台入选《全国企业数字化转型十佳案例》|元年科技

7月4日&#xff0c;2023全球数字经济大会第二届全国企业数字化转型高峰论坛在京隆重举行。大会由全球数字经济大会组委会主办&#xff0c;中关村数字经济产业联盟承办&#xff0c;北京市科学技术协会鼎力支持。论坛期间元年科技凭借卓越案例《构建数字化转型引擎&#xff1a;元…

我的第一个创作纪念日

机缘 时间总是匆匆流逝&#xff0c;转眼间&#xff0c;我已经在前端领域迈入了第一个创作纪念日。回首往事&#xff0c;每一个创作的瞬间都如同一幅幅精彩的画面&#xff0c;在我心中留下深刻的印记。 日常 五年前&#xff0c;我踏入了前端职业的大门&#xff0c;初涉这片陌…

赛码网-01串的魔法(dp) 100%AC代码(C)

———————————————————————————————————— ⏩ 大家好哇&#xff01;我是小光&#xff0c;嵌入式爱好者&#xff0c;一个想要成为系统架构师的大三学生。 ⏩最近在准备秋招&#xff0c;一直在练习编程。 ⏩本篇文章对赛码网的01串的魔法 题目做…

开放式耳机对耳朵伤害大吗?开放式耳机哪个好?

一般来说&#xff0c;开放式耳机对耳朵的伤害是较小的&#xff0c;因为开放式耳机不会像入耳式耳机那样深入耳道&#xff0c;而是贴近外耳&#xff0c;所以它对耳朵的压力和负担更小。开放式耳机采用不入耳设计&#xff0c;让你在享受音乐的同时&#xff0c;保持对外界的感知&a…

弹簧滑块模型微分方程PLC数值求解(Euler和Runge-Kutta法SCL源代码)

龙格库塔法求解微分方程的PLC算法,还可以参看下面这篇文章博客: 微分方程数值解法(Runge-Kutta法PLC实现)_RXXW_Dor的博客-CSDN博客微分方程数值解法之欧拉法请参看下面的博客文章:微分方程数值解法(PID仿真用一阶被控对象库PLC算法实现)_数学微积分算法plc编程实例_RXXW_D…