爲何「15。。。」會致使微信ANR?

本文目的在於學習研究Android技術,如有侵犯,聯繫做者將及時刪除。php

本文同步自wing的地方酒館java

首先,微信發生ANR之後,會生成traces.txt文件。經過adb 導出android

adb pull /data/anr/traces.txt ~/複製代碼

其中有這麼一段:bash

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。測試

那也就是說明,其實不是這裏的緣由。ui

因而將斷點打靠上層,到 com.tencent.mm.ui.widget.celltextview.f.b.a() 方法上spa

點擊放過按鈕發現程序無限次落到這個斷點上,由此可知,是形成了死循環,無限調用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裏了。

歡迎加入qq羣討論Android技術:425983695

相關文章
相關標籤/搜索