最全Android Native Crash问题的一点排查思路,2024年最新面试怎么学

尾声

开发是需要一定的基础的,我是08年开始进入Android这行的,在这期间经历了Android的鼎盛时期,和所谓的Android”凉了“。中间当然也有着,不可说的心酸,看着身边朋友,同事一个个转前端,换行业,其实当时我的心也有过犹豫,但是我还是坚持下来了,这次的疫情就是一个好的机会,大浪淘沙,优胜劣汰。再等等,说不定下一个黄金浪潮就被你等到了。

  • 330页 PDF Android核心笔记

  • 几十套阿里 、字节跳动、腾讯、华为、美团等公司2020年的面试题

  • PDF和思维脑图,包含知识脉络 + 诸多细节

  • Android进阶系统学习视频

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

对于每个tombstone,如果是native crash,打开后大概会看到如下日志:

image.png

最上面的这些日志是最重要的,它包含了发生crash的线程是哪个,发的日志调用帧是哪个,到这里基本能很大程度上帮助我们实现问题的定位了,也就是基于bugreport + tombstone。

问题分析


线上ARM64升级的Crash只发生在Android10的系统上,具体到我们这个BUG,最终归宿到

arm64/base.odex (BakerReadBarrierThunkAcquire_r15_r0_2)

Cause: null pointer dereference

但是上述的问题看起来跟如下帧似乎没有任何关系

arm64/base.odex (com.netease.mail.profiler.handler.BaseHandler.stopTrace+360)

Java层的代码,怎么忽然就跑到arm64/base.odex (BakerReadBarrierThunk中去了呢?不防分析一下完整的调用帧:

backtrace:

#00 pc 00000000008ee260 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (BakerReadBarrierThunkAcquire_r15_r0_2)

#01 pc 00000000009c9808 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (com.netease.mail.profiler.handler.BaseHandler.stopTrace+360)

#02 pc 00000000009b3cc4 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (com.netease.mail.profiler.handler.TailHandler$1.operationComplete+212)

#03 pc 00000000009b3b8c /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (com.netease.mail.android.wzp.util.Util$1.operationComplete [DEDUPED]+108)

#04 pc 0000000000b93180 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.util.concurrent.DefaultPromise.notifyListener0+80)

#05 pc 0000000000b9370c /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.util.concurrent.DefaultPromise.notifyListeners+988)

#06 pc 0000000000b94e3c /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.util.concurrent.DefaultPromise.trySuccess+92)

#07 pc 0000000000ba499c /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.DefaultChannelPromise.trySuccess+44)

#08 pc 0000000000b90ef4 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise+84)

#09 pc 0000000000b91850 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect+192)

#10 pc 0000000000bb390c /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.nio.NioEventLoop.processSelectedKey+444)

#11 pc 0000000000bb3bf8 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized+312)

#12 pc 0000000000bb55b8 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.channel.nio.NioEventLoop.run+824)

#13 pc 0000000000ae1580 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.util.concurrent.SingleThreadEventExecutor$2.run+128)

#14 pc 0000000000adf068 /data/app/com.netease.yanxuan-YLeR3gwwgd3DyIUBNJZ8cA==/oat/arm64/base.odex (io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run+72)

#15 pc 00000000004afbb8 /system/framework/arm64/boot.oat (java.lang.Thread.run+72) (BuildId: 65cd48ea51183eb3b4cdfeb64ca2b90a9de89ffe)

#16 pc 0000000000137334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: fc24b8afa1bd5f1872cc1a38bcfa1cdc)

#17 pc 0000000000145fec /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: fc24b8afa1bd5f1872cc1a38bcfa1cdc)

#18 pc 00000000004b0d98 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: fc24b8afa1bd5f1872cc1a38bcfa1cdc)

#19 pc 00000000004b1eac /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416) (BuildId: fc24b8afa1bd5f1872cc1a38bcfa1cdc)

#20 pc 00000000004f2868 /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176) (BuildId: fc24b8afa1bd5f1872cc1a38bcfa1cdc)

#21 pc 00000000000e69e0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36) (BuildId: 1eb18e444251dc07dff5ebd93fce105c)

#22 pc 0000000000084b6c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 1eb18e444251dc07dff5ebd93fce105c)

从#22帧开始看出这个是一个ART解释执行的过程,Android中基本所有线程栈都是这种形式,那么最终就可以认为是解释BaseHandler.stopTrace这句的时候,出现了null pointer dereference这样一个异常,为甚会这样呢?由于在系统上有共性:只有Android10系统的ARM64设备上出现,所以有理由怀疑Android10的源码在BakerReadBarrierThunkAcquire_r15_r0_2这里的处理上有什么不对劲,通过检索akerReadBarrierThunkAcquire_r15_r0_2字符串,发现code_generator_arm64.cc源码CompileBakerReadBarrierThunk函数最终输出了这段日志:

image.png

对比Android10与Android 11源码发现有一处很明确的不同,在Field Load使用之前,多加了一个空检查的Case:

image.png

解释执行代码实在是看不懂:摘录了下这条记录的log Fix null checks on volatile reference field loads on ARM64.如下:

Fix null checks on volatile reference field loads on ARM64.

ART’s compiler adds a null check HIR instruction before each field

load HIR instruction created in the instruction builder phase. When

implicit null checks are allowed, the compiler elides the null check

if it can be turned into an implicit one (i.e. if the offset is within

a system page range).

On ARM64, the Baker read barrier thunk built for field reference loads

needs to check the lock word of the holder of the field, and thus

includes an explicit null check if no null check has been done before.

However, this was not done for volatile loads (implemented with a

load-acquire instruction on ARM64). This change adds this missing null

文末

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

这里笔者分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【视频教程】

天道酬勤,只要你想,大厂offer并不是遥不可及!希望本篇文章能为你带来帮助,如果有问题,请在评论区留言。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值