android 抓取native层奔溃

kebibuluan · · 428 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

使用android的breakpad工具

使用这个工具需要下载Breakpad的源码,然后进行编译,编译之后会生成两个工具

我们使用这两个工具来解析奔溃的位置。这里我们可以下载已经编译好的工具

下载地址是:链接:http://pan.baidu.com/s/1jIiU5cq 密码:wy6f

你把对应的工具下载完成后需要上传到对应的linux环境下才能使用

二、生成转换工具
1、下载BreakPad源代码
命令行输入:svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only

2、编译工具
①进入代码路径
cd google-breakpad-read-only/


②配置环境
./configure


③编译工具
make


3、看看以下工具是否存在:
google-breakpad-read-only/src/tools/linux/dump_syms/dump_syms
google-breakpad-read-only/src/processor/minidump_stackwalk

 这两个工具可以直接到csdn中去下载编译成功的

这个过程你需要编译出几个工具:minidump_stackwalk dump_syms等等

就是上面这两个工具

但是这里要注意不同的版本不一样,这里可以直接到csdn上去下载

集成到App中

使用开源的:https://github.com/yinyinnie/breakpad-for-android,它已经将对应的抓取奔溃的so库已经生成好了你只需要将对应的breakpad moudle引入到你的工程中就可以了

我们的工程依赖breakpad 这个模块

 

 

 接下来我们来看看工程的代码:

调用的时候你只需要调用:  NativeBreakpad.init("/sdcard/Android/data/com.cetcs.ecmapplication/");

就可以,其中init中的参数就是奔溃日志存储的路径

当产生奔溃的时候会在该路径下面产生一个dmp的文件。有了dmp文件我们需要将dmp文件使用上面产生的两个工具来进行解析

得到奔溃的日志信息

我们新建了一个Dump文件夹

将上面的两个工具上传上去,必须保证上面的两个工具具有可以执行的权限

把奔溃的日志上传上去,保证奔溃的dmp文件具有可执行权限

把运行的si库文件上传上去,这里上传的so库必须需要具有调试信息:

对应android studio而言,这里需要上传的so库不是src/libs目录下的so库,而是必须具有调试信息的so库

具有调试信息的so 库在/local/目录下

使用ndk-build编译出来的so 库需要具有调试信息,so库存在的目录如下所示:

libs是正式提供给第三方使用的,obj目录下的so库才是具有调试信息的,所以具有调试信息的so库在发布版本的时候,我们需要进行备份

具体的操作步骤看博客:http://blog.csdn.net/brook0344/article/details/20126351

  

这里我实验了好多天:解析出来的dmp文件好像都没有和符号文件关联起来,不能得到下面的信息:

12-14 14:24:18.369  3281  3281 F DEBUG   : backtrace:

12-14 14:24:18.369  3281  3281 F DEBUG   :     #00 pc 00000c98  /data/app/logback.ecmapplication.cetcs.com.testbreakpad-2/lib/arm/libweiyuan.so (sb_crash+3)

12-14 14:24:18.369  3281  3281 F DEBUG   :     #01 pc 00000ca1  /data/app/logback.ecmapplication.cetcs.com.testbreakpad-2/lib/arm/libweiyuan.so (Java_logback_ecmapplication_cetcs_com_testbreakpad_MainActivity_getStringFromC+4)

12-14 14:24:18.369  3281  3281 F DEBUG   :     #02 pc 000ec389  /system/lib/libart.so (art_quick_generic_jni_trampoline+40)

 

得到的文件内容如下:

Operating system: Android
                  0.0.0 Linux 3.10.86-g8b38b32 #1 SMP PREEMPT Thu Apr 14 14:24:52 CST 2016 armv7l
CPU: arm
     ARMv1 ARM part(0x4100d080) features: half,thumb,fastmult,vfpv2,edsp,neon,vfpv3,vfpv4,idiva,idivt
     8 CPUs

GPU: UNKNOWN

Crash reason:  SIGSEGV
Crash address: 0x0
Process uptime: not available

Thread 0 (crashed)
 0  libweiyuan.so + 0xc98
     r0 = 0xf43d6cc0    r1 = 0xffcf371c    r2 = 0x00000001    r3 = 0x00000000
     r4 = 0xf43d6cc0    r5 = 0xffcf3cb0    r6 = 0x0000004c    r7 = 0xffcf37d0
     r8 = 0xef5251c8    r9 = 0xf43f6500   r10 = 0xffcf3720   r12 = 0xef50bc9d
     fp = 0xf43f6500    sp = 0xffcf36f8    lr = 0xef50bca5    pc = 0xef50bc98
    Found by: given as instruction pointer in context
 1  dalvik-LinearAlloc (deleted) + 0x151c6
     sp = 0xffcf36fc    pc = 0xef5251c8
    Found by: stack scanning
 2  libart.so + 0xec389
     sp = 0xffcf3700    pc = 0xf3fb638b
    Found by: stack scanning
 3  dalvik-main space 1 (deleted) + 0x1e40e
     sp = 0xffcf3704    pc = 0x32c1e410
    Found by: stack scanning
 4  dalvik-main space 1 (deleted) + 0x1e3fe
     sp = 0xffcf3708    pc = 0x32c1e400
    Found by: stack scannin

只能得到一个c98,这个时候有啥办法可以直接定位出来没

这个时候可以使用arm-linux-androideabi-addr2line.exe这个工具来进行定位,具体不清楚的看博客http://blog.csdn.net/xyang81/article/details/42319789

我们首先进入到工程中具有调试信息so 库所在的目录:目录的路径如下所示:

C:\TestGoogleBreakPad\app\build\intermediates\ndk\debug\obj\local\armeabi-v7a

我们使用下面的命令:

D:\android_sdk_ndk\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-addr2line.exe  -C -f -e ./libweiyuan.so 00000c98

其中:D:\android_sdk_ndk\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-addr2line.exe 是对应的arm-linux-androideabi-addr2line工具的路径

00000c98就是对应的so 库奔溃对应的堆栈位置

我们来看一下

 

 我们可以看出对应的奔溃信息是在:Java_logback_ecmapplication_cetcs_com_testbreakpad_MainActivity_getStringFromC这个c文件的第12行发生了奔溃

第12行就是*a =1,*a是一个无效的野指针,给野指针赋值就会导致内存奔溃

我们来看看这个c文件的代码:

//
// Created by wei.yuan on 2017/11/13.
//
#include<jni.h>
#include<logback_ecmapplication_cetcs_com_testbreakpad_MainActivity.h>
#include <jni.h>
#include <string.h>
#include <pthread.h>

void sb_crash(){
    int *a = (int *) (NULL);
    *a = 1;
}
JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_testbreakpad_MainActivity_getStringFromC
        (JNIEnv * env, jobject obj){
    sb_crash();
    return (*env)->NewStringUTF(env,"I'm comes from 444444to Native Function!");
}

 

 

 我们来看看整个工程的目录架构如下所示:

 

特别需要注意的地方:

1、不同的breakpad版本的源码编译出来的上面的两个工具可能不一样,这样对dmp文件进行解析,解析出来的结果可能存在问题;

2、使用功能进行解析的时候,需要使用具有调试信息的so库文件,所以每次发版本的时候,需要将具有调试信息的so库文件进行备份;

3、如果解析dmp文件得不到具有的那个函数奔溃,没有和符号文件关联起来,可以使用\arm-linux-androideabi-addr2line.exe对具体调试信息的so库文件进行定位,这样也可以得到具体的行数

 整个android studio工程的代码如下:

http://pan.baidu.com/s/1ge9iKQf

相当的经典

 

 



本文来自:博客园

感谢作者:kebibuluan

查看原文:android 抓取native层奔溃

428 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet