Breakpad是一个用于捕获和报告应用程序崩溃的开源库。它由Google开发并被广泛用于许多知名的开源项目,如Chrome浏览器、Firefox浏览器和Android操作系统等。Breakpad可以被集成到应用程序的代码中,它会在程序发生崩溃时收集相关的崩溃信息,并生成一个minidump文件。
通过分析minidump文件,开发人员可以了解到程序崩溃时的调用堆栈、寄存器值、线程信息等关键信息,这对于排查和解决崩溃问题非常有帮助。Breakpad还提供了一套工具,如dump_syms和minidump_stackwalk,用于解析minidump文件和符号表,以便更好地理解和分析崩溃信息。
使用Breakpad可以帮助开发人员快速定位和修复应用程序中的崩溃问题,提高软件的稳定性和可靠性。在开源社区中,Breakpad被广泛看作是一种高效的崩溃报告机制,能够帮助开发者及时发现和修复软件中的问题。
1. 安装
git clone https://gitee.com/ybmcode/breakpad.git
./configure && make -j 12
sudo make install
2. 库的链接
2.1 CMake
find_package(PkgConfig REQUIRED)
pkg_check_modules(BREAKPAD REQUIRED breakpad-client)
include_directories(${BREAKPAD_INCLUDE_DIRS})
# 添加到add_executable之后
target_link_libraries(${PROJECT_NAME}
${BREAKPAD_LIBRARIES}
pthread # 必须添加
)
2.2 Qt-Pro
CONFIG += link_pkgconfig
PKGCONFIG += breakpad-client
3. 测试示例
#include "client/linux/handler/exception_handler.h"
#include "iostream"
bool carsh_callback(const google_breakpad::MinidumpDescriptor &descriptor, void *context, bool succeeded)
{
(void)context;
printf("[error]:state %d path: %s\n", succeeded, descriptor.path());
fflush(stdout);
return succeeded;
}
int main(int argc, char **argv)
{
google_breakpad::ExceptionHandler *eh{nullptr};
google_breakpad::MinidumpDescriptor descriptor(".");
eh = new google_breakpad::ExceptionHandler(descriptor, nullptr,carsh_callback,nullptr, true, -1);
int *p = nullptr;
std::cout << *p << std::endl;
return 0;
}
4. 崩溃日志导出
官方导出崩溃信息的步骤比较麻烦,这里整理好了一键导出的脚本(dumptool.sh),在文章的最后。
使用方法
# ./dumptool.sh 可执行程序路径 崩溃文件路径
./dumptool.sh breakpad_test e2c0fa44-fe48-48cc-6b4da19a-192cf85b.dmp
运行后会在output文件夹中输出result.txt文件,内容即为崩溃日志,可定位到对应文件和函数的具体行。
一键导出脚本
#!/bin/bash
# fileName: dumptool.sh
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
mkdir output
minidump_stackwalk $dmp_file_name ./symbols > output/result.txt 2> output/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