Linux下Qt breakpad编译使用

news2024/12/24 10:40:40

一、下载安装包

  • 下载qbreakpad源码:
git clone https://github.com/buzzySmile/qBreakpad.git
  •  下载breakpad源码
git clone https://github.com/google/breakpad
  • 下载linux-syscall-support
    没有这个文件,编译报错
git clone https://github.com/adelshokhy112/linux-syscall-support.git

 二、编译

第一步:切换到breakpad目录

cd breakpad

第二步:

./configure

cxx@cxx-virtual-machine:~/Demo/breakpad$ ./configure  

 第三步:把linux-syscall-support目录下的lss文件拷贝到breakpad/src/third_party,如下图

 第四步:编译 

make -j12

注意:

如果make提示以下错误

 ./third_party/lss/linux_syscall_support.h: In member function ‘bool google_breakpad::ExceptionHandler::GenerateDump(google_breakpad::ExceptionHandler::CrashContext*)’:
./third_party/lss/linux_syscall_support.h:2146:75: error: listing the stack pointer register ‘rsp’ in a clobber list is deprecated [-Werror=deprecated]
 2146 |                              : "rsp", "memory", "r8", "r10", "r11", "rcx");
      |                                                                           ^

 则修改/lss/linux_syscall_support.h,如下图

如果提示“fatal error: zlib.h: 没有那个文件或目录”错误

src/common/linux/dump_symbols.cc' || echo './'`src/common/linux/dump_symbols.cc
src/common/linux/dump_symbols.cc:53:10: fatal error: zlib.h: 没有那个文件或目录
 #include <zlib.h>
          ^~~~~~~~
compilation terminated. 

解决方法:

在命令行中输入以下内容

sudo apt-get install zlib1g-dev

 重新编译

make -j12

出现以下信息,则编译成功

 第四步:

sudo make install

查看生成文件路径

which dump_syms

cxx@cxx-virtual-machine:~/Demo/breakpad$ which dump_syms
/usr/local/bin/dump_syms
cxx@cxx-virtual-machine:~/Demo/breakpad$ cd /usr/local/bin
cxx@cxx-virtual-machine:/usr/local/bin$ ls
core2md    dump_syms_mac        minidump-2-core  minidump_stackwalk  pid2md
dump_syms  microdump_stackwalk  minidump_dump    minidump_upload     sym_upload

 Qt中如何运用

在.pro文件中添加 

INCLUDEPATH +=/usr/local/include/breakpad
LIBS +=/usr/local/lib/libbreakpad_client.a
LIBS +=/usr/local/lib/libbreakpad.a

在main.cpp中添加头文件和

#include "client/linux/handler/exception_handler.h"
#include "client/linux/handler/minidump_descriptor.h"
#include "mainwindow.h"
#include <iostream>
#include <QApplication>
#include "client/linux/handler/exception_handler.h"
#include "client/linux/handler/minidump_descriptor.h"
using namespace std;

using namespace google_breakpad;

bool minidumpDB(const MinidumpDescriptor& descriptor,void* context,bool succeeded)
{
    if(succeeded){
        std::cout<<"Mini Dump file:"<<descriptor.path()<<std::endl;
    }
    return succeeded;
}
int crash(int a,int b){
    return a/b;
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //获取当前可执行文件的路径
    QString path = QCoreApplication::applicationDirPath();
    //这里设置生成.dmp文件的路径为当前可执行文件的路径
    google_breakpad::MinidumpDescriptor descriptor(path.toStdString());
    google_breakpad::ExceptionHandler eh(descriptor,NULL,minidumpDB,NULL,true,-1);
    MainWindow w;
    w.show();
    crash(5,0);
    return a.exec();
}

在生成的可执行文件目录下,创建一个breakpad.py文件:

 breakpad.py文件,内容如下

# -*- coding: utf-8 -*-
import os 
import sys
import subprocess
import shutil
import traceback

ENVPATH = "/usr/local/bin"
def track_error():
    error_message=""
    (type,value,trace)=sys.exc_info()
    print("**************************************************************")
    print("Error_Type:\t%s\n"%type)
    print("Error_Value:\t%s\n"%value)
    print("%-40s %-20s %-20s %-20s\n"%("Filename", "Function","Linenum", "Source"))
    for filename, linenum, funcname, source in traceback.extract_tb(trace):
        print("%-40s %-20s %-20s%-20s" % (os.path.basename(filename),funcname,linenum, source))
    print("**************************************************************")

class RunDump(object):
    def __init__(self,m_app):
        self.current = os.path.abspath(os.path.dirname(m_app))
        self.appname = os.path.basename(m_app)
        self.app = os.path.abspath(m_app)
        self.symbols = os.path.join(self.current,"symbols")
        self.dump = None
        self.symfile = "%s.sym"%(self.app)
        self.mkdirpath = None
       

        self.Run()

    def __del__(self):
        if  os.path.exists(self.symbols):
            shutil.rmtree(self.symbols)
        if self.dump:
            os.remove(self.dump)
    def Get_Dump(self):
        dmp = list(filter(lambda file:  os.path.splitext(file)[-1] == ".dmp",os.listdir(self.current)))
        if dmp == list():
            print("dmp file not exist...")
            exit(1)
        self.dump = os.path.join(self.current,dmp[-1])
        
      
    def RunCmd(self,cmd):
        new_env = os.environ.copy()
        new_env["PATH"] = ENVPATH
        pid = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True,env = new_env)
        for i in pid.communicate():
            if len(i)>0:
                print(i)
        return pid.wait()
    
    def readlline(self):
        line = ""
        with open(self.symfile) as fd:
            for line in fd:
                break
        linemd5 = line.split()[-2]
        self.mkdirpath = os.path.join(self.symbols,self.appname,linemd5)
        os.makedirs(self.mkdirpath,exist_ok = True)   
        shutil.move(self.symfile,self.mkdirpath)
        print("symbols目录生成:%s"%self.mkdirpath )

    def Run(self):
        self.Get_Dump()
        self.CreatSym()
        self.readlline()
        self.CreatDump()

    def CreatSym(self):
        cmd = "dump_syms %s>%s"%(self.app,self.symfile)
        if self.RunCmd(cmd):
            print("%s 运行出错"%cmd)
            exit(1)
        else:
            print("生成sym文件:%s"%self.symfile)
         
    def CreatDump(self):
        sysmbols = os.path.join(os.path.join(self.current,"symbols"))
        creashlog = os.path.join(os.path.join(self.current,"crash.log"))
        errorlog = os.path.join(os.path.join(self.current,"error.log"))
        cmd = "minidump_stackwalk %s %s >%s 2>%s"%(self.dump,sysmbols,creashlog,errorlog)
        if self.RunCmd(cmd):
            print("%s 运行出错"%cmd)
        else:
            print("crash.log生成成功:%s"%creashlog)
    

if __name__ == "__main__":
    if len(sys.argv[:])<2:
        print("""输入命令:./Breakpad.py  AppPath 
            AppPath:程序app 所在路径
        """)
        exit(1)
    try:
        app = sys.argv[1]
        RunDump(app)
    except BaseException:
            track_error()

 执行程序,即可在可执行目录下生成一个dmp文件

 执行dmp解析

python3 breakpad.py ./breakTest

cxx@cxx-virtual-machine:~/Demo/build-breakTest-Desktop_Qt_5_14_2_GCC_64bit-Debug$ python3 breakpad.py ./breakTest 
生成sym文件:/home/cxx/Demo/build-breakTest-Desktop_Qt_5_14_2_GCC_64bit-Debug/breakTest.sym
symbols目录生成:/home/cxx/Demo/build-breakTest-Desktop_Qt_5_14_2_GCC_64bit-Debug/symbols/breakTest/EC33EEC8E77904C93D41C11D6FAE6E180
crash.log生成成功:/home/cxx/Demo/build-breakTest-Desktop_Qt_5_14_2_GCC_64bit-Debug/crash.log 

 生成crash.log 和error.log文件

 打开crash.log,即可看到记录到的详细错误信息。

dmp 解析脚本:

GitHub - heisai/breakpad: breakpad 解析生成log

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

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

相关文章

Stable Diffusion WebUI Ubuntu 22.04 LTS RTX2060 6G 极限显存出图

模型 默认选中 chilloutmix_Ni.safetensors&#xff0c;重启webui.sh进程 正向词 best quality, ultra high res, (photorealistic:1.4), 1girl, <lora:koreanDollLikeness_v15:1> ,<lora:yaeMikoRealistic_yaemikoMixed:1>, 反向词 paintings, sketches, (…

数字万用表的四种妙用方法

数字万用表&#xff08;Digital Multimeter&#xff0c;简称DMM&#xff09;是一种在电子电路测试和维修中常用的仪器。它可以测量电压、电流、电阻等各种电信号参数&#xff0c;同时还可以测试二极管、晶体管等元器件。数字万用表使用数字显示&#xff0c;具有高精度、易读性好…

SQL高级教程第三章

SQL CREATE DATABASE 语句 CREATE DATABASE 语句 CREATE DATABASE 用于创建数据库。 SQL CREATE DATABASE 语法 CREATE DATABASE database_name SQL CREATE DATABASE 实例 现在我们希望创建一个名为 "my_db" 的数据库。 我们使用下面的 CREATE DATABASE 语句&…

SQL19 分组过滤练习题

selectuniversity,round(avg(question_cnt), 3) as avg_question_cnt,round(avg(answer_cnt), 3) as avg_answer_cnt fromuser_profile group byuniversity havingavg_question_cnt < 5or avg_answer_cnt < 20;

抖音矩阵系统源码部署技术分享--基于抖音开放平台

开发概述 开放平台基于开发者诉求和相关平台规则&#xff0c;提供了两种开放模式&#xff1a;能力开放、行业开放。 自研开发者介绍 自研开发者是指有自己的自营业务&#xff0c;或是有多种加盟方的角色&#xff0c;可以基于用户需求&#xff0c;提供完整的技术解决方案。 …

【Redis】高可用之二:哨兵(sentinel)

本文是Redis系列第5篇&#xff0c;前4篇欢迎移步 【Redis】不卡壳的 Redis 学习之路&#xff1a;从十大数据类型开始入手_AQin1012的博客-CSDN博客关于Redis的数据类型&#xff0c;各个文章总有些小不同&#xff0c;我们这里讨论的是Redis 7.0&#xff0c;为确保准确&#xff…

dockerfile常用指令

Dockerfile常用指令 视频学习资料来源这里&#xff0c;点击本行文字即可跳转&#xff0c;讲的比较详细&#xff0c;不过比较老&#xff0c;跟最新的肯定是有一些差异的 Dockerfile官网文档的话点击这里 中文文档可以看看这个&#xff0c;不过没有详细的代码demo 或者是看这个 或…

3. 日志模块(下)

在日志模块的上篇中&#xff0c;我们详细拆解了 MyBatis 是如何整合第三方日志框架&#xff0c;实现了完善的日志功能的。那么在本节中&#xff0c;我们再来具体分析下&#xff1a;为了实现“将日志功能优雅地嵌入到核心流程中&#xff0c;实现无侵入式地日志打印”这一目标&am…

菜谱APP项目实战,可以魔改任意APP——前后端齐全

菜谱APP开发实战&#xff08;可改任意APP&#xff09; 1. 优点 多平台性 由于此APP开发的时候采用的是 uni-app 来开发的&#xff0c;所以说它可以打包成多种形态&#xff0c;在各种平台上进行使用。比如&#xff1a;微信、支付宝等各种小程序。当然也是可以打包成安卓APP&am…

如何学习 Midjourney 绘画,AI绘图

Midjourney 是至今为止最好的 AI 绘图工具&#xff0c;SD还是差了很多。 要用当然用最好的&#xff0c;为了绘制出更符合心意的图&#xff0c;我开始 Midjourney 的学习。 从各种渠道寻找相关的资料&#xff0c;国内国外&#xff0c;或者星球&#xff0c;或者群聊&#xff0c…

简析住宅小区有序充电价格响应的电动汽车有充电策略

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;在住宅小区传统建设模式下&#xff0c;充电桩安装难、配套投资大&#xff0c;严重阻碍了充电桩在小区内进行普及使用。为解决该问题&#xff0c;本文首先调研了住宅小区内的电动汽车用户的出行习惯和充电特点&#xf…

SQL力扣练习(六)

目录 1. 部门工资前三高的所有员工(185) 题解一(dense_rank()窗口函数&#xff09; 题解二&#xff08;自定义函数&#xff09; 2.删除重复的电子邮箱(196) 题解一 题解二&#xff08;官方解析&#xff09; 3.上升的温度(197) 解法一&#xff08;DATEDIFF()&#xff09;…

java中地址问题

//第一个大mapMap<String, Object> map new HashMap<>();HashMap<String, String> map2 new HashMap<>();map2.put("358","999");//给小map赋值并将其添加到map中map.put("666",map2);//获取小map并且修改对应的键值对…

商城小程序有哪些优势?

伴随着移动互联网的高速发展&#xff0c;越来越多的实体商家开始转变营销思路&#xff0c;都纷纷开始布局线上市场&#xff0c;尤其是从小程序出现以后。今天新胜天下小编就来和大家聊一聊商城小程序有哪些优势。 1. 拥有众多流量入口 商城小程序本身就是小程序里的一种类型&a…

基于ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析能力与项目科研水平研修

【科研团队必选】老师赋予目的不仅仅是技术的掌握&#xff0c;更能从技术融合与科研经验的视角下&#xff0c;培养科研团队科研素质&#xff0c;挖掘-融合-创新 目的&#xff1a;以科研及项目角度解决您的数据分析问题及热点问题&#xff0c;为您的论文写作及项目推进挖掘更好…

技术服务企业缺成本票,所得税高怎么解决?可有良策?

技术服务企业缺成本票&#xff0c;所得税高怎么解决&#xff1f;可有良策&#xff1f; 《税筹顾问》专注于园区招商、企业税务筹划&#xff0c;合理合规助力企业节税&#xff01; 技术服务型企业最核心的价值就是为客户提供技术支撑&#xff0c;而这类型的企业在税务方面面临的…

Observability:Synthetic monitoring - 合成监测入门(二)

在之前的文章 “Observability&#xff1a;Synthetic monitoring - 合成监测入门&#xff08;一&#xff09;” 里&#xff0c;我详细描述了如何使用 Project monitors 来创建监控器。我们可以通过在 terminal 中打入命令&#xff0c;创建最为基本的测试框架文件。我们可以通过…

python scrapy爬取网站数据(二)

用法很简单&#xff0c;先安装Scrapy&#xff0c;我这里是win10环境&#xff0c;py3.10 安装scrapy pip install Scrapy显示如图安装完毕 创建项目 分三步创建 scrapy stratproject spiderdemo #创建spiderdemo 项目&#xff0c;项目名随意取 cd spiderdemo #进入项目目录下…

【多线程初阶】第一次认识线程

多线程初阶系列目录 持续更新中 1.第一次认识线程 … 文章目录 多线程初阶系列目录前言1. 线程概念1.1 线程是什么1.2 为什么需要线程1.3 进程和线程的区别1.4 Java线程和操作系统线程的关系 2. 第一个Java多线程程序3. 创建线程的方法3.1 继承 Thread 类3.2 实现 Runnable 接…

深兰科技发布《深兰数字智能产业系列报告(2023年):个人数字化》

近日&#xff0c;深兰科技发布《深兰数字智能产业系列报告(2023年)&#xff1a;个人数字化》&#xff0c;这是深兰科技在数字智能产业领域发布的首份研究报告&#xff0c;也是国内第一份个人数字化产业报告。此报告是在上海市经济和信息化委员会和上海市产业技术创新促进会的共…