JDWP(java debug wire protocol)是dalvik VM的一個線程,可以建立在adb或者tcp基礎上,與DDMS或debugger進行通信。
adb jdwp : list pids of processes hosting a JDWP transport
1.通過執行adb jdwp,可以看本設備上可以使用JDWP調試的進程。如下 :
通過設備上執行ps ,可知進程號1110是 com.android.launcher3 。我們將使用此進程進行測試。
2.用 adb forward tcp:port jdwp:<pid> 在PC上做端口映射, 然後在PC上通過端口連接手機,進行調試。命令如下:
adb forward tcp:8000 jdwp:1110
確認下命令執行的結果:
3.通過ipconfig獲取本機的ip是172.16.14.162,嘗試使用:
jdb -attach 172.16.14.162:8000
命令格式:
jdb -attach IP:PORT
遇到如下錯誤:
通過搜索錯誤信息:shmemBase_attach failed
https://community.oracle.com/thread/1177940
是因爲windows默認使用shared memory transport, 連接器是com.sun.jdi.SharedMemoryAttach,如果想通過socket連接,即通過網絡連接來調試,需要告訴jdb,使用socket attaching connector。
可以通過命令查看可用的連接器:
因此,接下來嘗試使用:
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000
結果遇到如下錯誤:
嗯,什麼原因會拒絕呢?權限不夠,還是端口已經被佔用。網上繼續搜索一翻,原來,我PC開着DDMS,估計端口衝突?先關於再說。再執行上面命令,結果如下:
不容易啊。
輸入thread命令:
其它更多命令呢,讓我們輸入萬能的help:
> help
** 命令列表 **
connectors -- 列出此 VM 中可用的連接器和傳輸
run [class [args]] -- 開始執行應用程序的主類
threads [threadgroup] -- 列出線程
thread <thread id> -- 設置默認線程
suspend [thread id(s)] -- 掛起線程 (默認值: all)
resume [thread id(s)] -- 恢復線程 (默認值: all)
where [<thread id> | all] -- 轉儲線程的堆棧
wherei [<thread id> | all]-- 轉儲線程的堆棧, 以及 pc 信息
up [n frames] -- 上移線程的堆棧
down [n frames] -- 下移線程的堆棧
kill <thread id> <expr> -- 終止具有給定的異常錯誤對象的線程
interrupt <thread id> -- 中斷線程
print <expr> -- 輸出表達式的值
dump <expr> -- 輸出所有對象信息
eval <expr> -- 對表達式求值 (與 print 相同)
set <lvalue> = <expr> -- 向字段/變量/數組元素分配新值
locals -- 輸出當前堆棧幀中的所有本地變量
classes -- 列出當前已知的類
class <class id> -- 顯示已命名類的詳細資料
methods <class id> -- 列出類的方法
fields <class id> -- 列出類的字段
threadgroups -- 列出線程組
threadgroup <name> -- 設置當前線程組
stop in <class id>.<method>[(argument_type,...)]
-- 在方法中設置斷點
stop at <class id>:<line> -- 在行中設置斷點
clear <class id>.<method>[(argument_type,...)]
-- 清除方法中的斷點
clear <class id>:<line> -- 清除行中的斷點
clear -- 列出斷點
catch [uncaught|caught|all] <class id>|<class pattern>
-- 出現指定的異常錯誤時中斷
ignore [uncaught|caught|all] <class id>|<class pattern>
-- 對於指定的異常錯誤, 取消 'catch'
watch [access|all] <class id>.<field name>
-- 監視對字段的訪問/修改
unwatch [access|all] <class id>.<field name>
-- 停止監視對字段的訪問/修改
trace [go] methods [thread]
-- 跟蹤方法進入和退出。
-- 除非指定 'go', 否則掛起所有線程
trace [go] method exit | exits [thread]
-- 跟蹤當前方法的退出, 或者所有方法的退出
-- 除非指定 'go', 否則掛起所有線程
untrace [methods] -- 停止跟蹤方法進入和/或退出
step -- 執行當前行
step up -- 一直執行, 直到當前方法返回到其調用方
stepi -- 執行當前指令
下一步 -- 步進一行 (步過調用)
cont -- 從斷點處繼續執行
list [line number|method] -- 輸出源代碼
use (或 sourcepath) [source file path]
-- 顯示或更改源路徑
exclude [<class pattern>, ... | "none"]
-- 對於指定的類, 不報告步驟或方法事件
classpath -- 從目標 VM 輸出類路徑信息
monitor <command> -- 每次程序停止時執行命令
monitor -- 列出監視器
unmonitor <monitor#> -- 刪除監視器
read <filename> -- 讀取並執行命令文件
lock <expr> -- 輸出對象的鎖信息
threadlocks [thread id] -- 輸出線程的鎖信息
pop -- 通過當前幀出棧, 且包含當前幀
reenter -- 與 pop 相同, 但重新進入當前幀
redefine <class id> <class file name>
-- 重新定義類的代碼
disablegc <expr> -- 禁止對象的垃圾收集
enablegc <expr> -- 允許對象的垃圾收集
!! -- 重複執行最後一個命令
<n> <command> -- 將命令重複執行 n 次
# <command> -- 放棄 (無操作)
help (或 ?) -- 列出命令
version -- 輸出版本信息
exit (或 quit) -- 退出調試器
<class id>: 帶有程序包限定符的完整類名
<class pattern>: 帶有前導或尾隨通配符 ('*') 的類名
<thread id>: 'threads' 命令中報告的線程編號
<expr>: Java(TM) 編程語言表達式。
支持大多數常見語法。
可以將啓動命令置於 "jdb.ini" 或 ".jdbrc" 中
位於 user.home 或 user.dir 中
JDB的探索,先進行到這裏。
關於JDWP協議相關說明,可以參考: