前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线上bug修复之Path.addCircle崩溃

线上bug修复之Path.addCircle崩溃

作者头像
韦东锏
发布2021-09-29 15:15:12
9460
发布2021-09-29 15:15:12
举报
文章被收录于专栏:Android码农

本期专门介绍一个线上bug的排查跟修复过程,首先看下崩溃路径

代码语言:javascript
复制
1 #00 pc 00000000003ff65c /system/lib64/libhwui.so (SkPathRef::growForVerb(int, float)+336) [arm64-v8a]
2 #01 pc 00000000003fdb60 /system/lib64/libhwui.so (SkPath::conicTo(float, float, float, float, float)+144) [arm64-v8a]
3 #02 pc 000000000044c6d0 /system/lib64/libhwui.so (SkPath::addOval(SkRect const&, SkPath::Direction, unsigned int)+372) [arm64-v8a]
4 #03 pc 000000000019c05c /system/lib64/libhwui.so (SkPath::addCircle(float, float, float, SkPath::Direction)+76) [arm64-v8a]
5 #04 pc 00000000004220a8 /system/framework/arm64/boot-framework.oat [arm64-v8a]
6 java:
7 android.graphics.Path.addCircle(Path.java:593)
8 com.meitu.app.meitucamera.e.d.w(CameraAroundBlur.java:1172)
9 com.meitu.app.meitucamera.e.d.u(CameraAroundBlur.java:1049)
10 com.meitu.app.meitucamera.e.d.a(CameraAroundBlur.java:271)

接下来看下实际崩溃的代码(历史代码,有删减,实现这部分代码的人已离职)

代码语言:javascript
复制
private Path mPathFullRingBlurArea = new Path();
mPathFullRingBlurArea.reset();                                                   
mPathFullRingBlurArea.addRect(new RectF(mBlurRect), Path.Direction.CCW);         
mPathFullRingBlurArea.addCircle(mCenterPoint.x + left, mCenterPoint.y + top, mOuterRadius, Path.Direction.CW); 
mPathFullRingBlurArea.close();   

可以很明显的看到,就是addCircle方法发生的崩溃,崩溃的地方是系统类Path的方法

还有崩溃2,数量也比较高,崩溃log如下

代码语言:javascript
复制
# AppExecutors-mt(32487)SIGSEGV(SEGV_MAPERR)
 1 #00    pc 000000000025cf00    /system/lib64/libhwui.so (SkPathRef::growForVerb(int, float)+456) [arm64-v8a]
 2 #01    pc 00000000003483e4    /system/lib64/libhwui.so (SkPath::addOval(SkRect const&, SkPath::Direction, unsigned int)+472) [arm64-v8a]
 3 #02    pc 00000000003481e4    /system/lib64/libhwui.so (SkPath::addCircle(float, float, float, SkPath::Direction)+72) [arm64-v8a]
 4 #03    pc 00000000002e17e8    /system/framework/arm64/boot-framework.oat [arm64-v8a]
 5 java:
 6 [Failed to get Java stack]

只有native层的log,不过有显示SkPath::addCircle信息,怀疑是同个崩溃(后来也证实,确实是同个崩溃)

当然,看到这里,就可以直接大概猜到崩溃原因的大神,请收下打的膝盖,不过自己的资历不够,于是继续分析

接下来看下其他维度的信息,看下可否辅助定位

崩溃数量:也比较高,影响了上万个用户了

崩溃设备:主要是10的系统,华为的机型

还有其他几个维度的信息,也都没有直接有助于定位问题的

接下来,尝试自己复现,发现本地无法复现,也有让测试配合验证,也没有复现,经内部讨论,怀疑会不会path的参数有问题,于是增加了参数埋点上报,跟着下个版本上线,看下线上实际崩溃时候的参数

发版后,收集log,发现线上崩溃时候的参数,跟本地自测的参数一样,没有异常,这里,初步排除参数异常问题

接下来,继续本地排查,path其实很多地方都在用,其他地方都没有问题,排除是系统Path类的异常,对代码继续断点跟打log验证,发现一个可疑的现象 出问题的这个方法,存在多线程调用的现象

可以发现,有主线程跟异步线程在调用这个方法,时间间隔几十毫秒,path类是用于canvas绘制的,绘制必定是主线程,path本身也不是线程安全的类,由此分析,多线程去操作同一个path实例,本身是不合理的,应该统一放主线程操作,于是做下如下修复

代码语言:javascript
复制
private void updateDiscontinuousBlurAreaPaths() {                                                       
    if (Looper.getMainLooper() != Looper.myLooper()) {
        //path不是线程安全的类,如果不是主线程调用,统一改成主线程调用
        AppExecutors.executeMain(new Runnable() {     
            @Override                                 
            public void run() {                       
                updateDiscontinuousBlurAreaPaths();   
            }                                         
        });                                           
        return;                                       
    }   
    //省略该方法的其他代码
}

修改后,由于无法本地验证,所以等到了下个版本上线后,看了下崩溃情况

发版后发现,最新版本没有再出现了,随着新版本逐渐覆盖上去,整体崩溃持续下降,由此确定问题已修复。

行数:63

字数:846

主题:默认主题

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档