最近又温习了一遍《Android开发高手课》(https://time.geekbang.org/column/article/70602),崩溃优化中提到了一个强大的native crash监控方案,就是Google开发的breakpad,本文目标是编译一个静态库出来方便以后项目复用
1.breakpad概述
官方描述
Breakpad provides an Autotools build system that will build both the Linux client libraries and the processor libraries. Running ./configure && make
in the Breakpad source directory will produce src/client/linux/libbreakpad_client.a, which contains all the code necessary to produce minidumps from an application.
github地址https://github.com/google/breakpad,由于breakpad工程量不小,并且提供的Linux平台编译脚本还是mk,如今AndroidStudio已经推荐使用Cmake了,所以本文主要是记录用cmake来编译breakpad。
2 下载源码
在https://github.com/google/breakpad download zip后解压后目录如下
breakpad按照官方说明分为两部分,一个是client源码,也就是客户端需要使用的native 链接库源码,另一个是生成的crash文件查看工具源码,因为breakpad的crash文件进行过优化,需要借助相关工具才能解析。client源码目录在src目录下,所以我们拷贝一份,准备新建工程。
3 工程引入并编译
其实本文的重点也就是去引入代码并且写CmakeLists文件编译了,新建一个native工程,并将刚才的src目录拷贝到cpp目录下,src/client下有些其他平台的文件夹可以删除,只保留linux就可以了。
编写Cmake
查看官方文档里的Android.mk,如下
LOCAL_SRC_FILES := \
src/client/linux/crash_generation/crash_generation_client.cc \
src/client/linux/dump_writer_common/thread_info.cc \
src/client/linux/dump_writer_common/ucontext_reader.cc \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/log/log.cc \
src/client/linux/microdump_writer/microdump_writer.cc \
src/client/linux/minidump_writer/linux_dumper.cc \
src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
src/client/linux/minidump_writer/minidump_writer.cc \
src/client/minidump_file_writer.cc \
src/common/convert_UTF.cc \
src/common/md5.cc \
src/common/string_conversion.cc \
src/common/linux/breakpad_getcontext.S \
src/common/linux/elfutils.cc \
src/common/linux/file_id.cc \
src/common/linux/guid_creator.cc \
src/common/linux/linux_libc_support.cc \
src/common/linux/memory_mapped_file.cc \
src/common/linux/safe_readlink.cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/common/android/include \
$(LOCAL_PATH)/src \
$(LSS_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
LOCAL_SRC_FILES 就是需要编译的文件,相当于cmake add_library()的源文件路径,最终我们的cmakeList文件内容如下,
cmake_minimum_required(VERSION 3.4.1)
set(BREAKPAD_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${BREAKPAD_ROOT}/src ${BREAKPAD_ROOT}/src/common/android/include)
file(GLOB BREAKPAD_SOURCES_COMMON
${BREAKPAD_ROOT}/src/client/linux/crash_generation/crash_generation_client.cc
${BREAKPAD_ROOT}/src/client/linux/dump_writer_common/thread_info.cc
${BREAKPAD_ROOT}/src/client/linux/dump_writer_common/ucontext_reader.cc
${BREAKPAD_ROOT}/src/client/linux/handler/exception_handler.cc
${BREAKPAD_ROOT}/src/client/linux/handler/minidump_descriptor.cc
${BREAKPAD_ROOT}/src/client/linux/log/log.cc
${BREAKPAD_ROOT}/src/client/linux/microdump_writer/microdump_writer.cc
${BREAKPAD_ROOT}/src/client/linux/minidump_writer/linux_dumper.cc
${BREAKPAD_ROOT}/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
${BREAKPAD_ROOT}/src/client/linux/minidump_writer/minidump_writer.cc
${BREAKPAD_ROOT}/src/client/minidump_file_writer.cc
${BREAKPAD_ROOT}/src/common/convert_UTF.c
${BREAKPAD_ROOT}/src/common/md5.cc
${BREAKPAD_ROOT}/src/common/string_conversion.cc
${BREAKPAD_ROOT}/src/common/linux/elfutils.cc
${BREAKPAD_ROOT}/src/common/linux/file_id.cc
${BREAKPAD_ROOT}/src/common/linux/guid_creator.cc
${BREAKPAD_ROOT}/src/common/linux/linux_libc_support.cc
${BREAKPAD_ROOT}/src/common/linux/memory_mapped_file.cc
${BREAKPAD_ROOT}/src/common/linux/safe_readlink.cc
)
file(GLOB BREAKPAD_ASM_SOURCE ${BREAKPAD_ROOT}/src/common/android/breakpad_getcontext.S)
set_source_files_properties(${BREAKPAD_ASM_SOURCE} PROPERTIES LANGUAGE C)
add_library(breakpad STATIC ${BREAKPAD_SOURCES_COMMON} ${BREAKPAD_ASM_SOURCE})
target_link_libraries(breakpad log)
跑起来会发现报错误提示说D:\workspace\breakpad_compile\app\src\main\cpp\src\client\linux\crash_generation\crash_generation_client.cc:40:10: fatal error: 'third_party/lss/linux_syscall_support.h' file not found,解决方案是去下载相应的文件
https://github.com/adelshokhy112/linux-syscall-support,好的,下载完后放入到对应的目录下,重新编译,编译没报错,但是到build目录下并没有生成对应的.a文件,发现是如果是想生成静态库文件,module下的build.gradle,配置需要加上一句
externalNativeBuild {
cmake {
cppFlags ""
targets 'breakpad' //注意和cmake里的lib名字一致
}
}
最后成功生成
后续基于此库封装jni层做一个简单的sdk
https://github.com/gsa798780633/breakpad_android
参考链接:
1.https://time.geekbang.org/column/article/70602 https://github.com/AndroidAdvanceWithGeektime/Chapter01 《Android开发高手课-崩溃优化》张绍文