在App調(diào)試或面試??的過程中欲诺,一個(gè)常見的問題是:如何獲取當(dāng)前的thread的狀態(tài)信息瓢喉。這一方法對(duì)于app 性能分析,或是解決運(yùn)行中的死鎖問題惊畏,往往顯得很有用處恶耽。
常見的場(chǎng)景是,線程A獲取了Lock A颜启, 線程B獲取了Lock B偷俭;隨后線程A進(jìn)一步想獲取Lock B,線程B進(jìn)一步想獲取Lock A缰盏,這樣就出現(xiàn)了死鎖涌萤。
thread A {
lockA.lock();
//...
lockB.lock();
}
thread B {
lockB.lock();
//...
lockA.lock();
}
這如果發(fā)生在主線程中,則會(huì)導(dǎo)致界面凍住口猜,跳出ANR的彈框负溪。
ANR
為了便于調(diào)試和分析,讓我們?cè)趃enymotion模擬器上調(diào)試運(yùn)行目標(biāo)app济炎,重現(xiàn)上述場(chǎng)景川抡。
隨后在命令行中執(zhí)行:
adb shell ps -ef | grep <pkg-name>
查找到當(dāng)前app的進(jìn)程id e.g. pid1adb shell run-as <pkg-name> kill -3 <pid1>
action | code | comments | note |
---|---|---|---|
SIGQUIT | 3 | /* Quit (POSIX). */ | 建立CORE文件終止進(jìn)程,并且生成core文件 |
向當(dāng)前app發(fā)送 QUIT
signal须尚,此時(shí) console
中會(huì)顯示 Wrote stack traces to tombstoned
崖堤,已將應(yīng)用的stack信息記錄下來了。
-
adb bugreport ./bugreport.zip
將出錯(cuò)信息導(dǎo)出到當(dāng)前目錄下的bugreport.zip
文件中恨闪,解壓以后就能看到詳細(xì)的狀態(tài)信息了
(更一般的倘感,如果出現(xiàn)app已經(jīng)出現(xiàn)了ANR,也可以直接從/data/anr/ 目錄下使用adb pull
把a(bǔ)nr log 導(dǎo)出來)咙咽。
e.g.
"main" prio=5 tid=1 Waiting
| group="main" sCount=1 dsCount=0 flags=1 obj=0x729291f0 self=0xe9c3ae00
| sysTid=2742 nice=-10 cgrp=default sched=0/0 handle=0xea48bdc8
| state=S schedstat=( 1000841099 167892657 575 ) utm=76 stm=23 core=1 HZ=100
| stack=0xff23e000-0xff240000 stackSize=8192KB
| held mutexes=
at sun.misc.Unsafe.park(Native method)
- waiting on an unknown object
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:190)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:868)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:902)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1227)
at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:950)
at com.example.locktest.MainActivity.test(MainActivity.kt:65)
at com.example.locktest.MainActivity.onCreate$lambda$2$lambda$1(MainActivity.kt:52)
at com.example.locktest.MainActivity.$r8$lambda$97V3BXrElnLtyrlpwFsDN9nFJMY(MainActivity.kt:-1)
at com.example.locktest.MainActivity$$ExternalSyntheticLambda1.onClick(D8$$SyntheticClass:-1)
at com.google.android.material.snackbar.Snackbar$1.onClick(Snackbar.java:351)
at android.view.View.performClick(View.java:7259)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1131)
at android.view.View.performClickInternal(View.java:7236)
at android.view.View.access$3600(View.java:801)
at android.view.View$PerformClick.run(View.java:27892)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Ref :