为什么“15。。。”会导致微信ANR?

各位同学早上好,今天分享的文章是来自我的老熟人Wing神的投稿。最近两天想必你会遇到下面这个让微信应用卡死的bug,身为技术人员,在没有源码的情况下,我们可以从逆向分析的角度入手去探索一下造成微信卡死的原因。


首先,微信发生ANR以后,会生成traces.txt文件。通过adb 导出

adb pull /data/anr/traces.txt ~/

其中有这么一段:

native: #05 pc 0043a419  /data/dalvik-cache/arm/system@framework@boot.oat (Java_java_util_regex_Matcher_setInputImpl__JLjava_lang_String_2II+132)
  at java.util.regex.Matcher.setInputImpl(Native method)
  at java.util.regex.Matcher.resetForInput(Matcher.java:252)
  - locked <0x0ecefa84> (a java.util.regex.Matcher)
  at java.util.regex.Matcher.reset(Matcher.java:208)
  at java.util.regex.Matcher.reset(Matcher.java:177)
  at java.util.regex.Matcher.<init>(Matcher.java:90)
  at java.util.regex.Pattern.matcher(Pattern.java:297)
  at com.tencent.mm.ui.widget.celltextview.g.a.o(SourceFile:95)
  at com.tencent.mm.ui.widget.celltextview.g.a.dc(SourceFile:55)
  at com.tencent.mm.ui.widget.celltextview.f.b.a(SourceFile:76)
  at com.tencent.mm.ui.widget.celltextview.d.a.Cw(SourceFile:466)
  at com.tencent.mm.ui.widget.celltextview.d.a.Cp(SourceFile:92)
  at com.tencent.mm.ui.widget.celltextview.CellTextView.onMeasure(SourceFile:102)
  at android.view.View.measure(View.java:18794)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
  at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
  at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
  at android.view.View.measure(View.java:18794)

发现是cellTextView锁在了celltextView正则的时候。

于是乎debug celltextview包的a类的o方法,

发现一段超级复杂的正则(部分位置打码),所以初步断定为可能是正则时间太长导致。于是写了一个单元测试,来测试该正则是否有问题。

实验发现,这个正则根本不会导致耗时过长,平均耗时0-1ms。

那也就是说明,其实不是这里的原因。

于是将断点打靠上层,到 com.tencent.mm.ui.widget.celltextview.f.b.a() 方法上

点击放过按钮发现程序无限次落到这个断点上,由此可知,是造成了死循环,无限调用a()方法导致的。

继续深究,为什么会导致死循环。

线索1

发现a()方法上面有一个判断,会导致跳到cond_6最终会继续跳到goto_4调用a()方法。

这里有个

add-int/lit8 v4, v4, -0x1

其实他相当于

i-1

线索2

观察a()方法后面,有wwk,width等属性调用。

结合线索

接下来,打开jadx,将class文件反编译为java文件,利用线索快速定位代码。发现这些逻辑代码片段如下:

有了java代码,一下子就和蔼可亲了,来屡一下这段的逻辑。

可以看到有两个while循环,这里不关心外部while,因为可以看出真正卡死的是在内部while循环。

内部while循环首先判断了dVar2 是否为空,以及dVar2的text是否为空。

debug发现,dVar2是一个TextPaint类,用于绘制文本信息(包括字号,大小,颜色,超链接样式之类的)。

也就是说,只要dVar2不为空,这个循环就不会退出,根据代码可以看出,只有在i4>0的时候才可能把dVar2置为空:

那么i4是什么呢,在红框上面可以看到,i4是a的wwk属性。这个值暂时不知道是什么。

不过通过debug发现,这个wwk是始终等于0的,也就是不满足while内部的dVar2的置空条件,也就造成了while死循环。

于是乎,造成anr的最根本原因就是在这个while里了。

文章到此结束,觉得不错的朋友欢迎点赞,转发哟!这个bug容易造成微信卡死重启,为了避免你被被群主踢出群去,建议在自己建立的小群里面尝鲜玩玩就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值