JDB远程调试system_service/Framework及普通app

前提条件

如果要调试Android系统库, 先确认AOSP编译时lunch的是eng或userdebug模式, 这样才会有调试工具在

或查看进程中是否存在JDWP线程

基本步骤

# 连接(无线调试需要)
adb connect 172.xx.xx.xx

# 查看进程ID
adb shell
ps | grep system_service

# 确认进程可调试, 查看是否有JDWP线程, 比如上一步输入pid为467
ps -eT | grep 467

# 端口转发;
adb -s <device> forward tcp:<port> jdwp:<target pid>
# 多台设备时需要指定-s选项; port即为本地映射的端口号

# JDB连接
jdb -attach 127.0.0.1:<port>

示例:

查看进程ID
local-pc:Home$ adb shell
local-android:/ $ ps | grep com.xx.packagename
USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME
u0_a71 4684 221 1017048 99668 0 00000000 S com.example.android.xxx

# 查看进程是否存在JDWP线程
ps -eT | grep 4684
USER      PID   PPID  VSIZE    RSS  WCHAN            PC  NAME
u0_a71    4689  4684  1018072 100952          0 00000000 S Jit thread pool 
u0_a71    4690  4684  1018072 100952          0 00000000 S Signal Catcher
u0_a71    4691  4684  1018072 100952          0 00000000 S JDWP
u0_a71    4692  4684  1018072 100952          0 00000000 S ReferenceQueueD

端口转发

adb forward tcp:8005 jdwp:4684
# 查看是否成功
adb forward --list 

附加调试

$ jdb -attach 127.0.0.1:8005
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb... 
>
 

调试命令

# 设置断点
stop in android.app.ContextImpl.getSystemService   # 方法名断点
stop at com.xxx.app.MainActivity:42          # 代码行断点
# 下一句
next
# 查看调用栈
where
# 在栈间移动, up移到上一级调用
up
down
# 打印变量
print `基本类型`
dump `对象`
# 单步进入
step
# 继续运行
cont

更多命令: https://www.tutorialspoint.com/jdb/index.htm

常见报错

java.net.SocketException: Connection reset 
at java.net.SocketInputStream.read(SocketInputStream.java:210<span><span>)
at java.net.SocketInputStream.read(SocketInputStream.java:141<span>)
at com.sun.tools.jdi.SocketTransportService.handshake(SocketTransportService.java:130<span>)
at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:232<span>)
at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116<span>)
at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90<span>)
at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519<span>)
at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328<span>)
at com.sun.tools.example.debug.tty.Env.init(Env.java:63<span>)
at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1082)

java.io.IOException: handshake failed - connection prematurally closed
at jdk.jdi/com.sun.tools.jdi.SocketTransportService.handshake(SocketTransportService.java:142)
at jdk.jdi/com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:255)
at jdk.jdi/com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:119)
at jdk.jdi/com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:83)
at jdk.jdi/com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
at jdk.jdi/com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
at jdk.jdi/com.sun.tools.example.debug.tty.Env.init(Env.java:63)
at jdk.jdi/com.sun.tools.example.debug.tty.TTY.main(TTY.java:1095)

----解决办法: 可能是Android Studio占用了jdb, 关闭Android Studio 重试

 2.

java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.sun.tools.jdi.SocketTransportService.attach(SocketTransportService.java:222)
    at com.sun.tools.jdi.GenericAttachingConnector.attach(GenericAttachingConnector.java:116)
    at com.sun.tools.jdi.SocketAttachingConnector.attach(SocketAttachingConnector.java:90)
    at com.sun.tools.example.debug.tty.VMConnection.attachTarget(VMConnection.java:519)
    at com.sun.tools.example.debug.tty.VMConnection.open(VMConnection.java:328)
    at com.sun.tools.example.debug.tty.Env.init(Env.java:63)
    at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1082)

 ----解决办法: 查看 adb forward --list 是否成功

3.

Unable to open debugger port (localhost:8005): java.io.IOException "handshake failed - connection prematurally closed"

----在使用Android Studio时遇到过, 后来不用Studio了, 暂时不知道怎么解, 知道的小伙伴欢迎留言指导

4. 还是不行?

试试: adb shell setprop dalvik.vm.extra-opts -agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y

拓展阅读:  http://liuwangshu.cn/framework/aosp/5-debug-aosp.html

原文地址:https://www.cnblogs.com/ciml/p/13362610.html