[android]使用jdb除錯android應用程式
覺得eclipse太過臃腫,或者機器資源有限,不妨試試用jdb命令列中除錯java程式。先要確保adb工作正常,用adb jdwp列出支援JDPW的程式ID。
用adb shell ps檢視程式的資訊。
確定要除錯的程式ID之後,建立網路資料轉發關係。
假設這裡要除錯程式873。
設定jdb原始碼路徑,這裡設定了android系統內的JAVA路徑,如果除錯自己的應用程式 ,可以加在後面。
啟動jdb
這裡的埠號9000,是由前面的tcp:9000決定。然後就可以使用jdb的各種除錯命令了。方便起見可以使用jdbshell。
附:
jdb/jdbshell基本除錯技巧:
jdbshell相容所有jdb命令,只是另外加了些命令縮寫、記錄歷史、命令自動補全和命令列編輯等功能。
1.用threads查詢所有執行緒:
命令:
結果顯示示例:
2.選擇你感興趣的執行緒。
命令:
結果顯示示例:
和gdb不同的是,這裡使用執行緒的ID,而不是執行緒的序號。這個問題讓我折騰了好久,問了好幾個做JAVA的朋友,原來他們都不用jdb。
3.暫停執行緒。
命令:
4.顯示呼叫堆疊。
命令:
結果顯示示例:
5.切換呼叫堆疊的frame:
命令:
up [n 幀] – 向上移動執行緒的堆疊
down [n 幀] – 向下移動執行緒的堆疊
和gdb不同的時,這裡指定的是要切換的frame與當前frame的偏移,而不是frame的索引。
結果顯示示例:
6.設定斷點
命令:
結果顯示示例:
7.顯示某個類的資訊。有時要在巢狀類裡設定斷點,這個命令可能有幫助。
命令:
class <類 ID> – 顯示已命名的類的詳細資訊
結果顯示示例:
8.繼續執行
命令:
9.清除斷點
命令:
10.檢視原始碼
命令:
list [line number|method] – 輸出原始碼
11.jdbshell命令縮寫
835
$ adb jdwp:
876
873
879
926
956
989
999
1010
1022
用adb shell ps檢視程式的資訊。
system 835 793 208564 29768 ffffffff afe0c57c S system_server
radio 873 793 112816 21252 ffffffff afe0d674 S com.android.phone
app_8 876 793 98044 17336 ffffffff afe0d674 S android.process.media
app_7 879 793 123780 28452 ffffffff afe0d674 S android.process.acore
app_0 926 793 104916 18372 ffffffff afe0d674 S com.google.process.gapps
app_11 956 793 96008 16392 ffffffff afe0d674 S com.android.alarmclock
app_16 989 793 105304 16772 ffffffff afe0d674 S com.android.mms
app_23 999 793 96324 15552 ffffffff afe0d674 S org.broncho.powermonitor
app_19 1010 793 98492 16044 ffffffff afe0d674 S com.android.setupwizard
app_7 1022 793 106708 19204 ffffffff afe0d674 S com.android.inputmethod.pinyin
確定要除錯的程式ID之後,建立網路資料轉發關係。
假設這裡要除錯程式873。
adb forward tcp:9000 jdwp:873
設定jdb原始碼路徑,這裡設定了android系統內的JAVA路徑,如果除錯自己的應用程式 ,可以加在後面。
export ANDROID_SRC=/broncho/cupcake/dev
export ANDROID_SRC_PATH=$ANDROID_SRC/frameworks/base/opengl/java:$ANDROID_SRC/frameworks/base/awt/java:$ANDROID_SRC/frameworks/base/core/java:$ANDROID_SRC/frameworks/base/location/java:$ANDROID_SRC/frameworks/base/sax/java:$ANDROID_SRC/frameworks/base/graphics/java:$ANDROID_SRC/frameworks/base/telephony/java:$ANDROID_SRC/frameworks/base/services/java:$ANDROID_SRC/frameworks/base/media/java:$ANDROID_SRC/frameworks/base/wifi/java:$ANDROID_SRC/frameworks/base/im/java:$ANDROID_SRC/dalvik/libcore/suncompat/src/main/java:$ANDROID_SRC/dalvik/libcore/nio_char/src/main/java:$ANDROID_SRC/dalvik/libcore/nio_char/src/main/java/java:$ANDROID_SRC/dalvik/libcore/security-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/security-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/security/src/main/java:$ANDROID_SRC/dalvik/libcore/security/src/main/java/java:$ANDROID_SRC/dalvik/libcore/archive/src/main/java:$ANDROID_SRC/dalvik/libcore/archive/src/main/java/java:$ANDROID_SRC/dalvik/libcore/awt-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/awt-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/luni/src/main/java:$ANDROID_SRC/dalvik/libcore/luni/src/main/java/java:$ANDROID_SRC/dalvik/libcore/math/src/main/java:$ANDROID_SRC/dalvik/libcore/math/src/main/java/java:$ANDROID_SRC/dalvik/libcore/x-net/src/main/java:$ANDROID_SRC/dalvik/libcore/openssl/src/main/java:$ANDROID_SRC/dalvik/libcore/dalvik/src/main/java:$ANDROID_SRC/dalvik/libcore/auth/src/main/java:$ANDROID_SRC/dalvik/libcore/concurrent/src/main/java:$ANDROID_SRC/dalvik/libcore/concurrent/src/main/java/java:$ANDROID_SRC/dalvik/libcore/sql/src/main/java:$ANDROID_SRC/dalvik/libcore/sql/src/main/java/java:$ANDROID_SRC/dalvik/libcore/prefs/src/main/java:$ANDROID_SRC/dalvik/libcore/prefs/src/main/java/java:$ANDROID_SRC/dalvik/libcore/xml/src/main/java:$ANDROID_SRC/dalvik/libcore/text/src/main/java:$ANDROID_SRC/dalvik/libcore/text/src/main/java/java:$ANDROID_SRC/dalvik/libcore/luni-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/luni-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/regex/src/main/java:$ANDROID_SRC/dalvik/libcore/regex/src/main/java/java:$ANDROID_SRC/dalvik/libcore/nio/src/main/java:$ANDROID_SRC/dalvik/libcore/nio/src/main/java/java:$ANDROID_SRC/dalvik/libcore/json/src/main/java:$ANDROID_SRC/dalvik/libcore/crypto/src/main/java:$ANDROID_SRC/dalvik/libcore/icu/src/main/java:$ANDROID_SRC/dalvik/libcore/annotation/src/main/java:$ANDROID_SRC/dalvik/libcore/annotation/src/main/java/java:$ANDROID_SRC/dalvik/libcore/junit/src/main/java:$ANDROID_SRC/dalvik/libcore/logging/src/main/java:$ANDROID_SRC/dalvik/libcore/logging/src/main/java/java:$ANDROID_SRC/dalvik/libcore-disabled/instrument/src/main/java:$ANDROID_SRC/dalvik/libcore-disabled/instrument/src/main/java/java:$ANDROID_SRC/dalvik/libcore-disabled/sound/src/main/java
啟動jdb
jdb -sourcepath $ANDROID_SRC_PATH -attach localhost:9000
這裡的埠號9000,是由前面的tcp:9000決定。然後就可以使用jdb的各種除錯命令了。方便起見可以使用jdbshell。
附:
jdb/jdbshell基本除錯技巧:
jdbshell相容所有jdb命令,只是另外加了些命令縮寫、記錄歷史、命令自動補全和命令列編輯等功能。
1.用threads查詢所有執行緒:
命令:
threads
結果顯示示例:
組 system:
(java.lang.Thread)0xc14360d1e8 <7> Signal Catcher 條件正在等待
(java.lang.Thread)0xc142850040 <5> HeapWorker 條件正在等待
組 main:
(java.lang.Thread)0xc140018e50 <3> main 條件正在等待
(java.lang.Thread)0xc143767c78 <59> Binder Thread #16 正在執行
(java.lang.Thread)0xc143744d48 <57> Binder Thread #15 正在執行
(java.lang.Thread)0xc143757458 <51> Binder Thread #14 正在執行
(java.lang.Thread)0xc14374ab88 <55> Binder Thread #13 正在執行
(java.lang.Thread)0xc14376d698 <53> Binder Thread #12 正在執行
(java.lang.Thread)0xc143615478 <45> Binder Thread #11 正在執行
(java.lang.Thread)0xc1437317b0 <49> Binder Thread #10 正在執行
(java.lang.Thread)0xc1436e8c38 <47> Binder Thread #9 正在執行
(java.lang.Thread)0xc14374eb50 <43> Binder Thread #8 正在執行
(java.lang.Thread)0xc1437000e0 <41> Binder Thread #7 正在執行
(android.os.HandlerThread)0xc1436dd9d0 <37> ContactsAsyncWorker 條件正在等待
(java.lang.Thread)0xc143681fb8 <35> Binder Thread #6 正在執行
(java.lang.Thread)0xc143681ef8 <33> Binder Thread #5 正在執行
(java.lang.Thread)0xc143659170 <31> Stk App Service 條件正在等待
(java.lang.Thread)0xc14368bc88 <29> Binder Thread #4 正在執行
(java.lang.Thread)0xc14368ad00 <27> Binder Thread #3 正在執行
(android.os.HandlerThread)0xc1436597a0 <25> AsyncQueryWorker 條件正在等待
(android.os.HandlerThread)0xc143656c00 <23> Stk Icon Loader 條件正在等待
(android.os.HandlerThread)0xc143656580 <21> RilMessageDecoder 條件正在等待
(android.os.HandlerThread)0xc1436560a0 <19> Stk Telephony service 條件正在等待
(java.lang.Thread)0xc143643c70 <17> RILReceiver 正在執行
(android.os.HandlerThread)0xc143641858 <15> RILSender 條件正在等待
(java.lang.Thread)0xc14360ee08 <13> Binder Thread #2 正在執行
(java.lang.Thread)0xc14360df90 <11> Binder Thread #1 正在執行
2.選擇你感興趣的執行緒。
命令:
thread 0xc1436dd9d0
結果顯示示例:
<37> ContactsAsyncWorker[1]
和gdb不同的是,這裡使用執行緒的ID,而不是執行緒的序號。這個問題讓我折騰了好久,問了好幾個做JAVA的朋友,原來他們都不用jdb。
3.暫停執行緒。
命令:
suspend 0xc1436dd9d0
4.顯示呼叫堆疊。
命令:
wherei
結果顯示示例:
[1] java.lang.Object.wait (本機方法)
[2] java.lang.Object.wait (Object.java:288), pc = 3
[3] android.os.MessageQueue.next (MessageQueue.java:148), pc = 153
[4] android.os.Looper.loop (Looper.java:110), pc = 8
[5] android.os.HandlerThread.run (HandlerThread.java:60), pc = 28
5.切換呼叫堆疊的frame:
命令:
up [n 幀] – 向上移動執行緒的堆疊
down [n 幀] – 向下移動執行緒的堆疊
和gdb不同的時,這裡指定的是要切換的frame與當前frame的偏移,而不是frame的索引。
結果顯示示例:
<37> ContactsAsyncWorker[1] up
<37> ContactsAsyncWorker[2]
6.設定斷點
命令:
stop at <類>:<行號> 或
stop in <類>.<方法名>[(引數型別,...)]
結果顯示示例:
> stop at com.android.phone.SimContacts$ImportAllThread:124
設定 斷點 com.android.phone.SimContacts$ImportAllThread:124
7.顯示某個類的資訊。有時要在巢狀類裡設定斷點,這個命令可能有幫助。
命令:
class <類 ID> – 顯示已命名的類的詳細資訊
結果顯示示例:
>class com.android.phone.SimContacts
類:com.android.phone.SimContacts
擴充套件: com.android.phone.ADNList
巢狀: com.android.phone.SimContacts$ImportAllThread
8.繼續執行
命令:
step – 執行當前行
step up – 執行到當前方法返回到其呼叫程式
stepi – 執行當前指令
next – 跳過一行(跨過呼叫)
cont – 從斷點處繼續執行
9.清除斷點
命令:
clear <類 ID>.<方法>[(引數型別,...)] – 清除方法中的斷點
clear <類 ID>:<行> – 清除行中的斷點
clear – 列出斷點
10.檢視原始碼
命令:
list [line number|method] – 輸出原始碼
11.jdbshell命令縮寫
command alias:
c — cont
l — list
n — next
r — run
s — step
si — stepi
f — step up
bt — wherei
相關文章
- 使用GDB除錯Android Native 層程式碼除錯Android
- 做一個可除錯的Android應用除錯Android
- Android除錯工具Genymotion的使用Android除錯
- android studio 除錯 framework 層程式碼Android除錯Framework
- Android Studio程式碼除錯技巧篇Android除錯
- Ubuntu 下使用 ADB 除錯 Android 應用時的裝置識別問題Ubuntu除錯Android
- android 無線除錯Android除錯
- android studio中使用adb wifi外掛無線除錯程式AndroidWiFi除錯
- Android應用方法隱藏及反除錯技術淺析Android除錯
- Flutter 應用程式除錯Flutter除錯
- Android Apk反編譯系列教程(三)Android Studio除錯smali程式碼AndroidAPK編譯除錯
- Android除錯神器stetho使用詳解和改造Android除錯
- Android除錯命令收錄Android除錯
- Android adb 網路除錯Android除錯
- 使用 Eclipse 遠端除錯 Java 應用程式(mark)Eclipse除錯Java
- 用PHP編寫Android應用程式PHPAndroid
- 逮蝦戶!Android程式除錯竟簡單如斯Android除錯
- 使用Eclipse除錯PHP應用Eclipse除錯PHP
- No debuggable processes(Android Studio沒有可除錯應用)問題解決方案Android除錯
- Android 應用程式元件介紹Android元件
- 開發Android應用程式,在Android10的系統上提示網路出錯?Android
- 使用 ABAP 控制 Android 原生應用Android
- Android 中 WebView 的除錯方法AndroidWebView除錯
- Android FrameWork學習(二)Android系統原始碼除錯AndroidFramework原始碼除錯
- Android除錯資料庫的福音:Android-Debug-DatabaseAndroid除錯資料庫Database
- 【譯】使用 ndb 除錯 node 應用除錯
- (學習)godot4.2 Android除錯GoAndroid除錯
- UE Puerts 在 Android 的除錯方法Android除錯
- 深入理解Android逆向除錯原理Android除錯
- 在IntelliJ idea中使用docker除錯Spring Boot應用程式IntelliJIdeaDocker除錯Spring Boot
- 使用 Kotlin 構建 MVVM 應用程式—提高篇:Dagger-AndroidKotlinMVVMAndroid
- 【Android開發入門教程】二.Android應用程式結構分析Android
- Android原始碼(二)應用程式啟動Android原始碼
- 我的第一個Android應用程式Android
- Android基礎及應用 Service的使用Android
- android nfc tag3 除錯日記Android除錯
- 遠端除錯 Android 裝置網頁除錯Android網頁
- Android 除錯實戰與原理詳解Android除錯
- Android Jetpack - Android TV 應用開發教程AndroidJetpack