【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位

前言

实现在ubuntu/arm环境下 定位QT程序异常结束位置。

Google - Breakpad

Breakpad 是 Google 公司开发的开源 跨平台C++崩溃检测库。Breakpad可以捕获发布给用户的应用程序的崩溃,并记录软件崩溃的调试信息到 minidump 文件中。调试信息包括错误行号,报错详情,堆栈错误。

程序运行效果

异常代码位置【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第1张图片
异常退出位置【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第2张图片

ubuntu环境 Breakpad编译

1.下载breakpad源码

官网地址:https://github.com/google/breakpad.git
或码云地址:https://gitee.com/jiang_bin_yu/crashManager/blob/master/googlebreakpad%E7%BC%96%E8%AF%91%E6%89%80%E9%9C%80%E6%96%87%E4%BB%B6/%E6%96%B0%E7%89%88%E6%9C%AC/breakpad-main.zip

2.下载linux_syscall_support.h (源码中缺少此文件)

下载地址:https://gitee.com/jiang_bin_yu/crashManager/blob/master/googlebreakpad%E7%BC%96%E8%AF%91%E6%89%80%E9%9C%80%E6%96%87%E4%BB%B6/%E6%96%B0%E7%89%88%E6%9C%AC/linux_syscall_support.h

3.解压google breakpad
4.将linux_syscall_support.h放到breakpad/src/third_party/lss/中
要新建lss目录复制文件到该目录。
5.编译google breakpad
5.1 ubuntu环境下(如ubuntu虚拟机)编译方法

控制台cd breakpad 进入目录
运行指令 ./configure --prefix=$(pwd)/_install
PS --prefix=$(pwd)/_install 安装目录   指定安装目录  如果不指定是安装的在默认的目录下,/usr/local  pwd是当前用户目录。
运行指令 make -j4
运行指令 sudo make install

arm开发板环境 Breakpad编译

arm开发板编译方法
参考文章:google breakpad /qbreakpad 在 arm移植
注意:最新版的google breakpad需要支持C++ 11属性,对应比较老的交叉编译工具如arm-linux 4.4.3/arm-arago-linux-gnueabi,需要下载前几个版本的breakpad才能编译通过。
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第3张图片
在网址https://github.com/google/breakpad/branches/all中可以看到各个版本的更新时间
我用的arm交叉编译链是arm-linux-4.4.3版本 经过多个版本的尝试发现 chrome_32可以编译通过。

下面我以交叉编译链是arm-linux-4.4.3版本为例编译google breakpad
1.breakpad源码下载:
下载地址:https://github.com/google/breakpad/tree/chrome_23 (根据实际需求选择版本)
2.下载老版本的linux_syscall_support.h (源码中缺少此文件)
下载地址:https://gitee.com/jiang_bin_yu/crashManager/blob/master/googlebreakpad%E7%BC%96%E8%AF%91%E6%89%80%E9%9C%80%E6%96%87%E4%BB%B6/arm%E8%80%81%E7%89%88%E6%9C%AC/linux_syscall_support.h
3.解压google breakpad
4.将linux_syscall_support.h放到breakpad/src/third_party/lss/中
5.编译google breakpad
5.1 arm开发板环境下编译方法**

控制台cd breakpad 进入目录
运行指令 ./configure CC=arm-linux-gcc  CXX=arm-linux-g++ --host=arm-linux --prefix=$(pwd)/_install

PS --host=arm-linux 运行环境 (交叉编译成arm)
PS --prefix=$(pwd)/_install 安装目录   指定安装目录  如果不指定是安装的在默认的目录下,/usr/local  pwd是当前用户目录。

运行指令 make -j4
运行指令 sudo make install

5.2编译可能遇到的报错

5.2.1 Assembler message【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第4张图片
这个问题的原因是该arm-linux-gcc编译器的版本较老,使用最新版本的编译器。或编译更老版本的google breakpad。
5.2.2 error:‘sys_mmap2’
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第5张图片
修改src\common\memory.h ,将报错行的sys_mmap2 改成sys_mmap
5.2.3 redefinittion of ‘struct elf_siginfo’
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第6张图片
修改\src\tools\linux\md2core\minidump-2-core.cc #if 0 掉elf_siginfo结构体。

5.2.4 其他报错 参考文献

https://blog.csdn.net/u011018840/article/details/113242842
https://blog.csdn.net/u013794365/article/details/78501899

google breakpad的使用

1.编译准备 准备lib和include文件夹
因为我们已经通过 --prefix=$(pwd)/_install 指定了编译输出路径,因此我们只需要将_install文件夹中的 include文件夹和lib文件夹移植到我们的QT项目中就能正常使用了。
ps 在老版本的google breakpad编译完成后 不一定会在_install文件夹中生成include文件夹 需要我们自己在breakpad/src里面把需要的头文件文件夹复制过来。
2.Qt 调用google breakpad库
2.1 qBreakpad参考
为了在Qt中更加优雅的调用google breakpad库 我们可以参考一下qBreakpad 的Demo
qBreakpad 是 Qt 库,用于使用 google-breakpad 崩溃报告工具(并方便地使用它)。
qbreakpad源码下载 : https://github.com/buzzySmile/qBreakpad
2.2 程序源码
下面是我的调试程序,支持QT4/QT5版本,支持环境ubuntu64和arm-linux 4.4.3,可以下载参考下

调试源码:https://gitee.com/jiang_bin_yu/crashManager/tree/master/code/Qt-arm-ubuntu-googlebreakpad

【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第7张图片
crashDump.pro

QT       += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = crashDump
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS


CONFIG += c++11

SOURCES += \
        main.cpp \
    gooleCrash/handler/QBreakpadHandler.cpp \
    gooleCrash/handler/QBreakpadHttpUploader.cpp

HEADERS += \
    gooleCrash/handler/QBreakpadHttpUploader.h \
    gooleCrash/handler/QBreakpadHandler.h \
    gooleCrash/handler/singletone/singleton.h \
    gooleCrash/handler/singletone/call_once.h

FORMS += \
        mainwindow.ui

#link Breakpad library
#arm4.4.3
#unix:!macx: LIBS += -L$$PWD/gooleCrash/arm4.4.3/lib/ -lbreakpad_client
#INCLUDEPATH += $$PWD/gooleCrash/arm4.4.3/include/
#DEPENDPATH += $$PWD/gooleCrash/arm4.4.3/include/
#unix:!macx: PRE_TARGETDEPS += $$PWD/gooleCrash/arm4.4.3/lib/libbreakpad_client.a
#ubuntu64bit 虚拟机
unix:!macx: LIBS += -L$$PWD/gooleCrash/ubuntu64/lib/ -lbreakpad_client
INCLUDEPATH += $$PWD/gooleCrash/ubuntu64/include/
DEPENDPATH += $$PWD/gooleCrash/ubuntu64/include/
unix:!macx: PRE_TARGETDEPS += $$PWD/gooleCrash/ubuntu64/lib/libbreakpad_client.a

CONFIG -= app_bundle
CONFIG += debug_and_release warn_on
CONFIG += thread exceptions rtti stl

OBJECTS_DIR = _build/obj
MOC_DIR = _build

#加入调试信息
QMAKE_CFLAGS_RELEASE += -g
QMAKE_CXXFLAGS_RELEASE += -g
#禁止优化
QMAKE_CFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE -= -O2

#release在最后link时默认有"-s”参数,表示"Omit all symbol information from the output file",因此要去掉该参数
#QMAKE_LFLAGS_RELEASE = -mthreads -Wl   #此行经过测试可用可不用
#参考自:https://blog.csdn.net/dgj8300/article/details/78450638


main.cpp

#include 
#include 
#include "client/linux/handler/exception_handler.h"
#include "gooleCrash/handler/QBreakpadHandler.h"
/* 触发crash来测试 */
void crash11111()
{
    volatile int* a = (int*)(NULL);
    *a = 1;
}

int main(int argc, char* argv[])
{
    QCoreApplication app(argc, argv);

    QCoreApplication::setApplicationName("AppName");
    QCoreApplication::setApplicationVersion("1.0");
    QCoreApplication::setOrganizationName("OrgName");
    QCoreApplication::setOrganizationDomain("name.org");
	//开启异常退出监控
    QBreakpadInstance.setDumpPath("crashes");
    crash11111(); //异常报错位置

    return app.exec();
}

运行程序后,crashes文件夹中将生成dmp文件
在这里插入图片描述
3.使用dump_syms和minidump_stackwalk查看程序异常崩溃位置
dump_syms和minidump_stackwalk是breakpad编程生成的可执行文件,文件存在在_install/bin文件夹下
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第8张图片
3.1制作脚本一键输出记录异常退出位置的文本文件
3.1.1新建文件dump_tool.sh

#!/bin/bash

if [ $# != 2 ] ; then 
echo "USAGE: $0 EXE_NAME DMP_NAME" 
echo " e.g.: $0 test 3872B2CF-983B-4963-AFA9-C8534DFD4C44.dmp" 
exit 1; 
fi 

#get input param
exe_file_name=$1
dmp_file_name=$2

getSymbol() {
    echo "@getSymbol: start get symbol"
    dump_syms ./$exe_file_name > $exe_file_name'.sym'
}

getStackTrace() {
    echo "@getStackTrace: start get StackTrace"
    sym_file_name=$exe_file_name'.sym'

    #get first line of $sym_file_name
    line1=`head -n1 $sym_file_name`
    #echo $line1

    #get version number from string of first line
    OIFS=$IFS; IFS=" "; set -- $line1; aa=$1;bb=$2;cc=$3;dd=$4; IFS=$OIFS 
    #echo $dd
    version_number=$dd

    #make standard dir and move *.sym in it
    mkdir -p ./symbols/$exe_file_name/$version_number
    mv $sym_file_name ./symbols/$exe_file_name/$version_number

    #print stack trace at std output
    minidump_stackwalk $dmp_file_name ./symbols > result.txt 2> process.txt
    #print stack trace at a file
    #./minidump_stackwalk $dmp_file_name ./symbols 2>/dev/null >result.txt
}

main() {
    getSymbol 
    if [ $? == 0 ] 
    then 
        getStackTrace
    fi
}
# run main
main

3.1.2 设置环境变量
打开~/.bashrc
gedit ~/.bashrc
添加行:
在bashrc文本尾部加入下面的内容 注意BREADKPAD_ROOT为breakpad编译后的输出路径

#
export BREADKPAD_ROOT=/home/book/jbyyy/crash/breakpad-main/install
# 运行依赖
export LD_LIBRARY_PATH=$BREADKPAD_ROOT/lib:$LD_LIBRARY_PATH
# 开发依赖
export PATH=$BREADKPAD_ROOT/bin:$PATH
export CPATH=$BREADKPAD_ROOT/include/breakpad:$CPATH
export LIBRARY_PATH=$BREADKPAD_ROOT/lib:$LIBRARY_PATH

保存并使其生效
source ~/.bashrc
3.1.3 使用脚本
将dump_tool.sh脚本移动到 刚才生成.dmp的文件夹中
将Qt编译处理的Qt可执行程序crashDump移到 刚才生成.dmp的文件夹中
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第9张图片
执行语句

chmod 777 dump_tool.sh 
./dump_tool.sh crashDump 5f765e27-c115-4e06-3df13884-4806b565.dmp 

注意
这里的crashDump为你自己的可执行文件程序名
这里的5f765e27-c115-4e06-3df13884-4806b565.dmp为你自己刚才程序崩溃生成的dmp文件名

语句执行成功后 result.txt就是我们需要的记录了异常退出位置的文件
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第10张图片
【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位_第11张图片

源码下载

支持windows环境,MSVC、MINGW编译器源码
需要参考文献:【QT 定位程序异常结束位置】windows环境实现程序异常结束定位

支持ubuntu、arm环境源码
需要参考文献:【QT 定位程序异常结束位置】arm环境使用 breakpad 实现程序异常崩溃定位

支持windows、ubuntu环境源码

你可能感兴趣的:(android,C++,开发语言)