使用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文件好像都没有和符号文件关联起来,不能得到下面的信息:

  1. 12-14 14:24:18.369 3281 3281 F DEBUG : backtrace:
  2.  
  3. 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)
  4.  
  5. 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)
  6.  
  7. 12-14 14:24:18.369 3281 3281 F DEBUG : #02 pc 000ec389 /system/lib/libart.so (art_quick_generic_jni_trampoline+40)

得到的文件内容如下:

  1. Operating system: Android
  2. 0.0.0 Linux 3.10.86-g8b38b32 #1 SMP PREEMPT Thu Apr 14 14:24:52 CST 2016 armv7l
  3. CPU: arm
  4. ARMv1 ARM part(0x4100d080) features: half,thumb,fastmult,vfpv2,edsp,neon,vfpv3,vfpv4,idiva,idivt
  5. 8 CPUs
  6.  
  7. GPU: UNKNOWN
  8.  
  9. Crash reason: SIGSEGV
  10. Crash address: 0x0
  11. Process uptime: not available
  12.  
  13. Thread 0 (crashed)
  14. 0 libweiyuan.so + 0xc98
  15. r0 = 0xf43d6cc0 r1 = 0xffcf371c r2 = 0x00000001 r3 = 0x00000000
  16. r4 = 0xf43d6cc0 r5 = 0xffcf3cb0 r6 = 0x0000004c r7 = 0xffcf37d0
  17. r8 = 0xef5251c8 r9 = 0xf43f6500 r10 = 0xffcf3720 r12 = 0xef50bc9d
  18. fp = 0xf43f6500 sp = 0xffcf36f8 lr = 0xef50bca5 pc = 0xef50bc98
  19. Found by: given as instruction pointer in context
  20. 1 dalvik-LinearAlloc (deleted) + 0x151c6
  21. sp = 0xffcf36fc pc = 0xef5251c8
  22. Found by: stack scanning
  23. 2 libart.so + 0xec389
  24. sp = 0xffcf3700 pc = 0xf3fb638b
  25. Found by: stack scanning
  26. 3 dalvik-main space 1 (deleted) + 0x1e40e
  27. sp = 0xffcf3704 pc = 0x32c1e410
  28. Found by: stack scanning
  29. 4 dalvik-main space 1 (deleted) + 0x1e3fe
  30. sp = 0xffcf3708 pc = 0x32c1e400
  31. Found by: stack scannin
  1.  

只能得到一个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文件的代码:

  1. //
  2. // Created by wei.yuan on 2017/11/13.
  3. //
  4. #include<jni.h>
  5. #include<logback_ecmapplication_cetcs_com_testbreakpad_MainActivity.h>
  6. #include <jni.h>
  7. #include <string.h>
  8. #include <pthread.h>
  9.  
  10. void sb_crash(){
  11. int *a = (int *) (NULL);
  12. *a = ;
  13. }
  14. JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_testbreakpad_MainActivity_getStringFromC
  15. (JNIEnv * env, jobject obj){
  16. sb_crash();
  17. return (*env)->NewStringUTF(env,"I'm comes from 444444to Native Function!");
  18. }

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

特别需要注意的地方:

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

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

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

4、对应android 6.0以上的操作系统,存储奔溃文件需要动态申请,一定要保存app的存储权限已经开启,否则在对应的目录下没有对应的奔溃文件

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

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

相当的经典

集成:

在ecms集成breakPad模块的时候报错:

 
  1. 上面ecmcommon这个模块依赖breakpad模块
    需要注意几点:
    第一:breakpad模块中在gradle配置文件中
  1. defaultConfig {
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
  2.  
  3. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  4.  
  5. }
    必须和ecmcommon模块中对应
  1. minSdkVersion 16
    targetSdkVersion 23
    一一对应
  2.  
  3. 第二:要在ecmmmon对应的minifimest清单文件中添加
  1. tools:replace="android:allowBackup"
    这句话
  1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.cetcs.ecmcommon">
  2.  
  3. <application android:allowBackup="false"
    android:label="@string/app_name"
    android:supportsRtl="true"
    tools:replace="android:allowBackup"
    >
  4.  
  5. </application>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.READ_LOGS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    </manifest>
  1. 不清楚的参看博客:https://www.jianshu.com/p/a3c3532f4d30
  2.  
  3. 集成方式二:

集成到App

  1. 拷贝.so文件到你项目的app/libs/
  2. 拷贝sample/breakpad/src/main/java/cn/onlinecache/breakpad/NativeBreakpad.java到你的工程目录下,注意:包名不能改哦!!
  3. 在你的Application类初始化:NativeBreakpad.init(Environment.getExternalStorageDirectory().getAbsolutePath()); 注意:这个方法所传的参数你可以直接定义

你也可以无需编译,直接使用sample的breakpad module

  1. 如果集成好了有打印:

01-18 13:00:39.085 24480-24480/com.cetcs.ecmapplication D/cn.onlinecache.breakpad: nativeInit ===> breakpad initialized succeeded, dump file will be saved at /sdcard/Android/data/com.cetcs.ecmapplication/
01-18 13:00:39.628 24510-24510/? D/cn.onlinecache.breakpad: nativeInit ===> breakpad initialized succeeded, dump file will be saved at /sdcard/Android/data/com.cetcs.ecmapplication/

  1. 如何抓取到奔溃日志有打印:

-18 13:03:35.127 25292-25292/com.cetcs.ecmapplication E/cn.onlinecache.breakpad: native crash capture begin
01-18 13:03:35.246 25292-25292/com.cetcs.ecmapplication E/cn.onlinecache.breakpad: DumpCallback ===> succeeded 1

如果日志上出现

DumpCallback ===> succeeded 0

0表示native奔溃日志没有抓取成功

  1.  

android 抓取native层奔溃的更多相关文章

  1. Android平台抓取native crash log

    Android开发中,在Java层可以方便的捕获crashlog,但对于 Native 层的 crashlog 通常无法直接获取,只能通过系统的logcat来分析crash日志. 做过 Linux 和 ...

  2. Android 如何避免运行时奔溃

    奔溃问题 android运行的时候难免会有一些空指针(NullPointerException)或者下标越界(IndexOutOfBoundsException),用户使用的过程操作某一个按钮的时候, ...

  3. android抓取各种log的方法

    1.logcat (四类log buffer是main,radio.system.events) adb wait-for-device logcat adb logcat -v time > ...

  4. Charles + Android 抓取Https数据包 (适用于Android 6.0及以下)

    通过Charles代理,我们能很轻易的抓取手机的Http请求,因为Http属于明文传输,所以我们能直接获取到我们要抓取的内容.但是Https内容本身就是加密的,这时我们会发现内容是加密的了.本文我们来 ...

  5. Android 抓取LOG的几种命令【转】

    通常调试时候需要抓取log信息,下面几种通过ADB命令来抓取log的方法: USB连接上手机,手机需要其他操作:然后运行ADB工具:输入不同的命令即可抓取对应的LOG信息. 抓取radio LOG信息 ...

  6. android抓取logcat日志的方法

    这几天帮忙测试一个APP,报告结果需要提交日志文件,于是百度了下安卓的获取日志方法,其实很简单,7个步骤搞定,下面把我的总结分享给大家. 1.下载adb工具包 https://pan.baidu.co ...

  7. Android抓取log日志过滤

    前提:Android SDK已安装并配置环境变量 1.手机USB调试模式打开,连接PC 2.cmd窗口,执行adb logcat >log.log   // 输出日志到一个log文件 或者执行a ...

  8. Android使用ndk-stack获取so奔溃堆栈

    利用NDK做开发,因为各种原因的不小心,导致了闪退问题,没有stack的话,很难查到问题的所在.这时候ndk-stack出场了. 先看看如下DUMP信息: ********** Crash dump: ...

  9. Android Framework 分析---2消息机制Native层

    在Android的消息机制中.不仅提供了供Application 开发使用的java的消息循环.事实上java的机制终于还是靠native来实现的.在native不仅提供一套消息传递和处理的机制,还提 ...

随机推荐

  1. 附019.Rancher搭建及使用

    一 Rancher概述 1.1 什么是Rancher Rancher 是为使用容器的公司打造的容器管理平台.Rancher 简化了使用 Kubernetes 的流程,方便开发者可以随处运行 Kuber ...

  2. Alpha冲刺——总结随笔

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 Alpha冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.项目预期计划: ...

  3. jchdl - RTL实例 - Mux

    https://mp.weixin.qq.com/s/OmQRQU2mU2I5d-qtV4PAwg   二选一输出.   参考链接 https://github.com/wjcdx/jchdl/blo ...

  4. ffmpeg转码步骤源码实现的一点点浅析

    ffmpeg转码实现的一点点浅析 ffmpeg转码过程对解码的处理封装在process_input()中(process_input()->decode_video()->decode() ...

  5. 我终于看懂了HBase,太不容易了...

    前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 在我还不了解分布式和大数据的时候已经听说过HBa ...

  6. (Java实现) 洛谷 P1223 排队接水

    题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共两行,第一行为n:第二行分别 ...

  7. Java实现 LeetCode 525 连续数组

    525. 连续数组 给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组(的长度). 示例 1: 输入: [0,1] 输出: 2 说明: [0, 1] 是具有相同数量0和1的最长连续 ...

  8. Java实现 LeetCode 310 最小高度树

    310. 最小高度树 对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树 ...

  9. Java实现LeetCode_0035_SearchInsertPosition

    package javaLeetCode.primary; public class SearchInsertPosition_35 { public static void main(String[ ...

  10. Java动态规划实现最短路径问题

    问题描述 给定一个加权连通图(无向的或有向的),要求找出从每个定点到其他所有定点之间的最短路径以及最短路径的长度. 2.1 动态规划法原理简介 动态规划算法通常用于求解具有某种最优性质的问题.在这类问 ...