Android Native程序crash的一些定位方法简介

经常,避免不了,我们的代码会崩溃。如果crash在native代码上,Android会和其他Linux一样,生成一份core dump,将程序运行时的内存,寄存器状态,堆栈指针,内存管理信息以及各种函数调用堆栈信息等存到一个文件中,供调试者使用分析。

Core Dump的生成

Android的Core dump叫tombstone,墓碑文件。由专门的一个daemon服务debuggerd来搜集,保存到/data/tombstone/目录下[logcat中也会打印一份简要信息,基本够分析用]。一般生成过程为:

  1. 系统异常,内核丢出来signal信号
  2. 应用中,bionic中实现的默认signal处理过程,通过socket将pid/tid和异常退出信息,发给debuggerd进程
  3. debuggerd得到pid/tid信息,通过ptrace挂到异常进程,得到异常进程的各种信息,然后生成墓碑文件,保存起来。

debuggerd的具体实现和ptrace就不展开讲了,以前研究挂钩子和benchmark分析处理的时候,参考了这里不少代码。有兴趣同学可以好好学习一下这个,也可以玩出花来的。比如以前做老化测试,就是改了捕鱼达人的金钱,脚本一直放炮整周末自动老化,不过现在好多apk都防着ptrace了,你想调试它它就自杀,越来越没意思了…

Tombstone文件的基本信息:

Tombstone信息通常由如下几部分组成:
1. 系统信息
包括编译信息、版本号、进程信息等。
2. 异常信息
包括产生的异常的原因,如signal 11(即段错误,内存访问异常)、异常所在位置等。
3. 寄存器信息
Dump当前线程栈中的寄存器值,包括通用寄存器和浮点寄存器的值。
4. backtrace信息
Dump当前进程栈中的调用栈。这个信息对异常分析非常有用。Backtrace信息已经做过符号定位和demangle,PC地址已经减去基地址,基本可以直接和so文件中的偏移地址对应。
5. 栈帧数据
以ascii形式,dump当前线程栈的栈帧信息。
6. 通用寄存器周边数据信息
通用寄存器很可能存储的是指针等信息,Android的tombstone会将通用寄存器周边数据也dump出来供分析。
7. 进程的logcat信息
Tombstone中还会dump在发生异常前,该进程输出的logcat信息。

其中,3,4,5,6,7每个线程信息都有对应信息。也不展开详说了,基本玩Android的都见过,除了墓碑文件中保存,在dropbox下,以及logcat的DEBUG TAG打出来的log中也有。

错误大体定位

简单说一下tombstone文件的阅读方式,大体定位错误方法。
一般对tombstone文件,除了知道是哪个进程挂了外,我们首要要知道的,是下面画圈圈的几个信息:

第一个,是signum,一般debuggerd关注的是SIGILL,SIGBUS,SIGABRT,SIGFPE,SIGSEGV,SIGPIPE等。而这里,估计九成都是SIGSEGV (即signal 11),段错误,和非法内存访问等价。
第二个是sigcode。对于段错误来说,sigcode一般就两个:SEGV_MAPERR和SEGV_ACCERR,字面意思,一个是map错误,一个是访问错误。
第三个是错误地址。

简单定位

错误九成以上都是段错误,主要关注这个,其他像非法指令、浮点出错等,也可以分析一下,一般要么是代码越界改写,要么是系统硬件不稳定造成的
对于段错误,基本上大多是SEGV_MAPERR。先说一下段错误的两种类型:
SEGV_MAPERR:这个说明访问出错的地址,压根就没内map到进程地址空间来,这种情况,通常就是野指针,或者越界访问,当然访问空指针也是属于这类。
SEGV_ACCERR:这个说明访问出错地址,被map到地址空间来了,但是没访问权限。基本上是指针越界或野指针,比如写只读map的内存地址。
这里的tombstone中的错误地址,就是非法操作的地址。现在Adroid已经使用了ALSR(地址空间随机布局),错误地址也一般不容易猜出大约哪里出问题,不过有一类地址,还是比较容易猜出来的:即地址的值比较小,基本上都是空指针访问了。地址值是小于4K的地址,可以认为就是解引用空指针了。

根据错误地址,错误类型,再通过tombstone给出的backtrace信息,使用编译时带符号的那份库,用addr2line查PC,直接得到出错的行号,结合错误原因,基本上可以定位错误了,修复即可。

几个错误例子

SEGV_MAPERR,错误的虚拟地址。怀疑野指针或越界。可以通过addr2line定位到行号。
一般我们看backtrace,并不是死板的看栈帧最顶上的。一般最顶上的都是C库,C库通常是被调用的底层函数库,不会做太多容错处理,一般认为是调用它的code给出的参数等有问题,再回溯几个栈帧看一下。这里很明显可以看到,是栈帧号3的地方出问题了,调用的是realloc,可能是越界或野指针,错的代码在这:

SharedBuffer* SharedBuffer::editResize(size_t newSize) const
{if (onlyOwner()) {SharedBuffer* buf = const_cast<SharedBuffer*>(this);if (buf->mSize == newSize) return buf;buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize);  //错在这if (buf != NULL) {buf->mSize = newSize;return buf;}}SharedBuffer* sb = alloc(newSize);if (sb) {const size_t mySize = mSize;memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize);release();}return sb;
}

看一下代码逻辑,基本先怀疑传入的参数newSize有异常,加一些trace,复现看看。


Dalvik虚拟机中有空指针, addr2line看一下具体位置,再看上下文查逻辑


这种错误,已经报说heap有异常,corrupt了。一般是有人越界写,或者double free都有可能,这个要查。很多时候还不是必现的,主要查一下临界区的保护问题。


主动自杀abort的,这个查到代码调用的地方,看一下逻辑就好。其实tombstone上,这类问题,同时会打印abort的原因,解决就好。

Android Native程序crash的一些定位方法简介相关推荐

  1. App控件定位:Android 控件介绍及元素定位方法

    本文将分享Android相关基础知识和Android APP控件定位工具的使用方法. 目录 Android基础知识 Android布局 Android四大组件 1.activity 2.Service ...

  2. android系统应用程序设置时间,Android应用程序设置系统时间的方法

    Android应用程序获取系统时间的方法: System.currentTimeMillis(); Android SDK虽然提供了设置系统时间的方法SystemClock.setCurrentTim ...

  3. 定位程序Crash常用工具和方法

    一.引言 任何程序正确则只有一种结果,但是错误却有千万种,而众多的错误有些是可容忍,有些则是致命的,如除零错误.堆栈溢出.内存越界等导致程序Crash.由于很多错误并不是发生在开发工作者调试阶段,而是 ...

  4. android应用程序永久获取root权限方法,怎么使Android应用程序获得root权限

    一般来说, Android 下的应用程序可以逗直接地得到的最大的权限为 system ,但是如果我们需要在程序中执行某些需要 root 权限的命令,如 ifconfig 等,就需要 root 权限了. ...

  5. androidsettitle方法_在Android应用程序中,Toolbar.setTitle方法无效-应用程序名称显示为标题...

    MYYA 以上答案完全正确,但对我不起作用.我通过以下方法解决了我的问题.实际上我的XML是这样的:                                                我已 ...

  6. Android应用程序获取ROOT权限的方法

    android中如何通过代码检测是否有root权限? public class MainActivity extends Activity { @Override     protected void ...

  7. 国内android应用商城中程序隐私泄露分析,Android应用程序隐私数据泄露检测

    摘要: Android智能手机中存储着用户的隐私数据,这些隐私数据泄露,会使用户蒙受经济损失及人身伤害.然而,目前第三方应用软件市场中存在许多恶意软件或漏洞软件,但现有的对Android应用软件检测技 ...

  8. 如何取消Google Play商店和Android应用程序订阅

    BigTunaOnline/ShutterstockBigTunaOnline / Shutterstock The Google Play Store plays host to all in-ap ...

  9. UI自动化测试之元素定位方法

    Python语言Selenium库UI自动化测试(一)元素定位方法 简介 当我们日常搭建自动化测试框架时,用Python调用浏览器时,通常有Requests库.Selenium库 这两个库是进行爬虫或 ...

最新文章

  1. 服务器技术综述(二)
  2. 【大话设计模式】——浅谈设计模式基础
  3. Spring Boot 2.x基础教程:使用JdbcTemplate访问MySQL数据库
  4. 自动化监控--zabbix中的show value详解
  5. [POI2008] Poc (原名 Trians) Treap+Hash
  6. android setGravity()的使用
  7. 第九次psp例行报告
  8. concat函数_三、P57-61 MySQL中常用函数
  9. AI修复技术为何这么强?原来背后的技术是……
  10. cms核心功能_如何根据这些重要功能选择合适的CMS
  11. pytorch模型保存
  12. addressof表达式不能转换为long_2.3 C++赋值运算符与表达式 | 将有符号数据赋给无符号...
  13. C#中 构造函数的执行
  14. Modown v4.11+Erphpdown10.01资源付费下载插件
  15. 蓝牙打印机CPCL编程手册~汉印HM-A300
  16. 大学计算机培训策划书,大学计划书的范文
  17. Android Studio 微信登录
  18. 邮件群发平台是什么意思?如何选择邮件群发平台
  19. 二维dct变换例题_数字图像处理试题(带答案)
  20. Visionpro工具用途中文介绍

热门文章

  1. JSP入门教程:JSP简明教程
  2. 信号与系统、数字信号处理、滤波、傅里叶变换、数字信号模拟信号采样信号、滤波器零阶保持器
  3. 复数,通往真理的最短路径
  4. 计算机为什么能做翻译,为什么计算机能翻译
  5. ThumbnailUtils.extractThumbnail Android图片缩略图显示总结及比较
  6. 01.计算机基础与Java
  7. Linux调试私房菜(四)揭开链接器的面纱、汇编语言的内嵌编程
  8. c++课程设计总结报告
  9. 云呐|机房监控服务平台,机房监控服务平台有哪些
  10. 牛客小白月赛28 J.树上行走