Google breakpad编译过程

in #cn8 years ago

1、环境

为了能够获取android下C/C++的crash log, 采用google breakpad来生成dmp文件, breakpad的下载地址:

svn co http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad

操作系统使用的是Mac OS X, 将breakpad编译进cocos2d-x 3.3环境下的工程, 将在android手机设备中获取相应的dmp文件。

2、准备

因为cocos2d-x 3.3在编译android环境时需要的NDK版本必须是r9版本, 而breakpad最新版必须要求r10c, 所以方案有两种:

(1) 下载breakpad之前的版本, 不需要r10c的版本, 找到一个它svn的版本为r1216
(2) 将cocos2d-x 的NDK版本改成r10c, 解决cocos2d-x编译android的问题, 可参考: [1]

在这里选择第一个方案, 那么下载breakpad的代码:

svn co http://google-breakpad.googlecode.com/svn/trunk/ -r 1216 google-breakpad-1216

3、mac下配置linux环境

由于Google Breadpad处理Android崩溃日志时需要Linux环境, 而借助vagrant可以非常方便地在Mac使用Ubuntu环境

安装brew cask

brew install brew-cask

安装vagrant与virtualbox

brew cask install vagrant 
brew cask install virtualbox

下载ubuntu的box

mkdir ubuntu //创建ubuntu目录
cd ubuntu    //进入ubuntu 
wget http://files.vagrantup.com/precise32.box  //用wget下载box, 这里是下载的32的, 也可以下载64位的

创建与初始化ubuntu box

vagrant box add ubuntu ./precise32.box
vagrant init ubuntu

ssh登录

vagrant up   //启动ubuntu
vagrant ssh   //ssh

4、编译

在ubuntu中下载资源

svn co http://google-breakpad.googlecode.com/svn/trunk/ -r 1216 google-breakpad-1216

编译

cd google-breakpad-1216
./configure
make

执行完上面的命令后将会在

google-breakpad-1216/src/processor 目录下生成minidump_stackwalk 工具,用于导出crash log.
google-breakpad-1216/src/tools/linux/dump_syms 目录下生成 dump_syms工具,用于导出符号文件。
google-breakpad-1216/src/client/linux 目录下生成 libbreakpad_client.a 

5、集成

集成的方式有两种, 参考breakpad目录下README.ANDROID。

(1) 编译成成.a库文件, 直接用加入.a的方式来集成
(2) 使用import-module的方式, 让ndk来编译

这里采用第(2)种方式:

(1) mac下将下载下来的breakpad源码拷贝到cocos2d-x工程proj.android目录下

(2) 在jni/Android.mk中加入代码

LOCAL_STATIC_LIBRARIES += breakpad_client
$(call import-module, google-breakpad-1216/android/google_breakpad)

(3) 在main.cpp 中加入代码

#include "client/linux/handler/exception_handler.h"
#include "client/linux/handler/minidump_descriptor.h"


//breakpad
bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
                  void* context,
                  bool succeeded) {
  LOGD("Dump path: %s\n", descriptor.path());
  return succeeded;
}


void cocos_android_app_init (JNIEnv* env, jobject thiz) {
    LOGD("cocos_android_app_init");
    AppDelegate *pAppDelegate = new AppDelegate();

    // 这里是定义dump文件的保存位置,保存至sd卡根目录
    google_breakpad::MinidumpDescriptor descriptor("/mnt/sdcard/breakpadLog");
    google_breakpad::ExceptionHandler *handler = new google_breakpad::ExceptionHandler(descriptor, NULL, DumpCallback, NULL, true, -1);

    ...
}

此时, 就可以编译android cocos2d-x工程了, 生成的crash文件放在 /mnt/sdcard/breakpadLog下, 文件后缀为dmp

6、解析dmp文件

从android设备中取出dmp文件, 放到一个目录下, 假设此目录为Dump, 然后拷贝proj.android/obj/local/armeabi/libxxx.so到Dump下

切换到ubuntu下, 拷贝mac上的Dump目录到ubuntu下

scp -r  [email protected]:~/Dump ./   // user指mac的用户名, @后面的ip为mac的ip, :后面为mac下Dump的路径, ./指保存到ubuntu下的目录路径

scp的命令参考[3]

拷贝命令dump_syms和minidump_stackwalk到Dump目录下

cp google-breakpad-1216/src/tools/linux/dump_syms/dump_syms ./Dump
cp google-breakpad-1216/src/processor/minidump_stackwalk ./Dump

生成sym文件

cd Dump
./dump_syms libxxx.so > libxxx.so.sym

查看libxxx.so.sym文件内容, 头部会有, BB0351B14DDA42A6D36FA6EA358B49D50不一样

MODULE Linux arm EB0351B143DA42A6D55FA6EA358B49D50 libxxx.so

继续执行命令

mkdir -p symbols/libxxx.so/BB0351B14DDA42A6D36FA6EA358B49D50/  
mv libxxx.so.sym symbols/libxxx.so/BB0351B14DDA42A6D36FA6EA358B49D50/  

这样就导出了符号文件,接下来导出崩溃堆栈

$ ./minidump_stackwalk xxxx-xxxx-xxxxx-xxxx.dmp symbols > crashed.log  

确保dmp文件和symbols目录是同级的。

查看crashed.log, 类似下面这段

Thread 12 (crashed)  
 0  libcocos2dcpp.so!AppDelegate::applicationDidFinishLaunching() [AppDelegate.cpp : 44 + 0x4]  
     r0 = 0x00000000    r1 = 0x00000001    r2 = 0x5a18a8e8    r3 = 0x5a18a6b8  
     r4 = 0x56ea70f0    r5 = 0x5c5c47b8    r6 = 0x00000000    r7 = 0x59f59f24  
     r8 = 0x5e5b6c58    r9 = 0x59f59f1c   r10 = 0x5c5c47c8   r12 = 0x00000000  
     fp = 0x5e5b6b60    sp = 0x5e5b6b18    lr = 0x5dc2d3e4    pc = 0x5db3e37c  

定位到是 AppDelegate.cpp的44行崩溃。

如果没有符号文件,比如这样导出crash log

$ ./minidump_stackwalk xxxx-xxxx-xxxxx-xxxx.dmp > crashed.log  

crashed.log 中的信息就是这样了

Thread 12 (crashed)  
 0  libcocos2dcpp.so + 0x2ee37c  
     r0 = 0x00000000    r1 = 0x00000001    r2 = 0x5a18a8e8    r3 = 0x5a18a6b8  
     r4 = 0x56ea70f0    r5 = 0x5c5c47b8    r6 = 0x00000000    r7 = 0x59f59f24  
     r8 = 0x5e5b6c58    r9 = 0x59f59f1c   r10 = 0x5c5c47c8   r12 = 0x00000000  
     fp = 0x5e5b6b60    sp = 0x5e5b6b18    lr = 0x5dc2d3e4    pc = 0x5db3e37c  

这个时候我们就要使用NDK中的arm-linux-androideabi-addr2line 工具定位崩溃了
arm-linux-androideabi-addr2line 路径为

$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86/bin/arm-linux-androideabi-addr2line
usage: arm-linux-androideabi-addr2line -C -f -e <库路径> <内存地址>
arm-linux-androideabi-addr2line -C -f -e project/test/obj/local/armeabi/aa.so 0003deb4

这时候就可以在终端中看到是 aa.so中的哪个文件的那一行发生异常了,接下来可以使用日志追踪有问题的代码了。

7、待解决的问题

(1) 无法在mac下查看和解析crash log
(2) breakpad使用的版本不是最新的, 需解决cocos2d-x在NDK r10c下编译出错的问题
(3) breakpad直接编译成.a的方式未成功, 虽然用ndk编译后也是生成.a, 但是clean后又需重新编译
(4) crash log上传到服务器的问题
(5) breakpad在iOS下也可以使用, 没有兼容

参考

[1] 使用NDK r10构建Cocosd-x v3.2时编译和链接错误的解决办法
[2] 在Mac下安装使用Vagrant
[3] scp命令
[4] Google Breakpad Android
[5] Android使用Google Breakpad进行崩溃日志管理
[6] use addr2line in android

Sort:  

欢迎您加入steemit社区。设置个人头像,有助于让大家更记住您,并且也比较美观,也显得正式。
如您还不知道如何设置,可点击此链接
https://steemit.com/cn/@kkkk/3sqepx

兄弟你很熱心,是好事。但是一直貼這條回覆,有點多了,已經開始有spam的疑慮的。建議你別再貼了。遇到新用戶,寫兩句就好了。

谢谢,已更换

谢谢分享。

Congratulations @wudb! You have received a personal award!

1 Year on Steemit
Click on the badge to view your own Board of Honor on SteemitBoard.

Upvote this notificationto to help all Steemit users. Learn why here!

Congratulations @wudb! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

Click here to view your Board

Vote for @Steemitboard as a witness and get one more award and increased upvotes!

Congratulations @wudb! You received a personal award!

Happy Steem Birthday! - You are on the Steem blockchain for 3 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Downvote challenge - Add up to 3 funny badges to your board
Use your witness votes and get the Community Badge
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.21
TRX 0.20
JST 0.035
BTC 91413.32
ETH 3152.41
USDT 1.00
SBD 3.07