1. breakpad简介

BreakPad是Google开发的一款软件崩溃信息记录工具,其大致原理是捕获系统底层发出的崩溃信号,将此刻软件的堆栈信息并进行分析生成报告,可以很方便的定位问题代码。

2. 安装

下载Breakpad,终端输入 git clone https://github.com/google/breakpad
下载载Breakpad依赖的库,git clone https://github.com/adelshokhy112/linux-syscall-support
linux-syscall-support/lss文件夹拷贝到breakpad/src/third_party目录下
编译 ./configure && make

编译完成后,
libbreakpad_client.abreakpad/src/client/linux/
dump_symsbreakpad/src/tools/linux/dump_syms/
minidump_stackwalkbreakpad/src/processor

3. 示例

下边是一个Google官方给出的例子:

#include "client/linux/handler/exception_handler.h"
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded) {
  printf("Dump path: %s\n", descriptor.path());
  return succeeded;
}

void crash() { volatile int* a = (int*)(NULL); *a = 1; }  //core dumped

int main() {
  google_breakpad::MinidumpDescriptor descriptor("./");
  google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
  crash();
  return 0;
}

为了统一路径,我把BreakPad拷贝到/usr/local

编译的时候,头文件包含src/目录,库文件要包含libbreakpad_client.alibpthread.so,程序运行完会在根目录下的/tmp文件夹生成一个.dmp文件

编译命令为:

g++ -g -I /usr/local/breakpad/src -o breakpad_test main.cpp /usr/local/breakpad/src/client/linux/libbreakpad_client.a -lpthread -std=c++11

其中的编译参数简单说一下:

  • -g:附带调试信息,必须要有,不然BreakPad无法定位问题具体在哪
  • -I: 头文件路径
  • -o:指定输出文件

对应的CMakeLists.txt为:

cmake_minimum_required(VERSION 3.0)
project(BreakPad_test)

# 支持C++11
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")

# 增加调试信息
add_definitions("-g")

#规定.h头文件路径
include_directories(/usr/local/breakpad/src)

#库路径
link_directories(/usr/local/breakpad/src/client/linux)

# 生成可执行文件
add_executable(${PROJECT_NAME} main.cpp )

target_link_libraries(${PROJECT_NAME} breakpad_client pthread)

运行结果为:

./breakpad_test 
Dump path: /tmp/4913fae1-f162-4147-8861a5a4-acf3fc2b.dmp
段错误 (核心已转储)

下面需要解析生成的.dmp文件,为了方便,我们把dump_symsminidump_stackwalk拷贝到可执行文件的同目录下

  1. 为了产生有用的堆栈信息,Breakpad要求将二进制文件中的调试符号(可执行文件里)转换为文本格式的符号文件,于是需要使用dump_syms工具生成文本格式的符号文件,命令为:
./dump_syms ./breakpad_test > breakpad_test.sym
  1. 为了将这些符号与minidump_stackwalk工具一起使用,还需要将它们放在特定的目录结构中。 符号文件的第一行包含生成此目录结构所需的信息,比如上述的breakpad_test.sym可使用如下命令:
head -n1 breakpad_test.sym 
				这一行是输出:MODULE Linux x86_64 076B1DEB1862487151B5C80B10E0DBC10 breakpad_test
#下边两行的路径名字要根据上一行的结果来
mkdir -p ./symbols/breakpad_test/076B1DEB1862487151B5C80B10E0DBC10
mv breakpad_test.sym ./symbols/breakpad_test/076B1DEB1862487151B5C80B10E0DBC10
  1. minidump_stackwalk工具可以提取一个minidump文件及其相应的文本格式符号,并生成可读的堆栈信息。在上述示例中可以使用如下命令生成最后的可读堆栈信息文件:
./minidump_stackwalk 800190a8-ca5c-4ce4-55bd12a2-3ca407ea.dmp ./symbols > dump_info.txt

此时会生成一个dump_info.txt文件,打开可以看到具体的报错信息,
在这里插入图片描述

4. 自动化脚本

前边解析.dmp文件的方法是基本方法,但是操作起来有些繁琐,下边是一个shell脚本,可以帮我们省去很多工作

#!/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 2> /dev/null 

    #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

脚本来源:https://blog.csdn.net/heroguo_jp/article/details/105387526

首先将dump_symsminidump_stackwalk拷贝到可执行文件的同目录下,再在同目录下新建一个dump_tools.sh脚本文件,将上面的脚本代码拷进去。

解析.dmp文件的时候,使用下边命令即可:

./dump_tools.sh ./BreakPad_test ./800190a8-ca5c-4ce4-55bd12a2-3ca407ea.dmp

5. 其他

如果使用breakpad的QT封装版本qbreakpad,可以参考跨平台的Qt程序崩溃生成Dump文件Breakpad

更多推荐