Google breakpad编译过程

in cn •  8 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

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

欢迎您加入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!