adb <-> adbserver <-> JDWP
简单理一下adb,adbserver,jdwp 之间的关系、角色与相关协议
| 上位机 | USB/TCP | 下位机 |
adb <-> adbserver <-JDWP-> Adbd <-JDWP-> VM
JDWP Server
当启动adbd时,它会创建UnixServerSocket ,命名为 @ vm-debug-control(@是“第一字节为0”的简写,用于以私有命名空间代替文件系统)
当一个新的JDWP守护线程(c层pthrerad,线程入口函数jdwpThreadStart())在新的虚拟机进程种启动时,他会创建一个链接到@ vm-debug-control来通知服务自己处于激活状态
JDWP thread @vm-debug-control (\0jdwp-control)//只是不被文件系统所现实出来的技巧?
| |
|-------------------------------> |
| hello I'm in process <pid> |
| |
| |
保持长连接。当JDWP进程结束时,会自动关闭(adbd也通过这种方式得知进程的死亡)
Adbd因此原理维护了一个“active”(活动的) JDWP 进程列表。他能发送内容信息通过“device:debug-prots”服务到客户端,
或者通过”device:track-debug-ports” 服务来更新。
当调试器想要链接时,会运行类似“adb forward tcp:<hostprot> jdwp:<pid>”的命令
(由host端的ADBServer和device端的ADBD通信后,)
“jdwp:<pid>” 是告诉设备需要转发目标JDWP进程到目的的新转发。当这样的请求到来时,adbd会做这样的操作流程
-首先,调用socketpair() 创建对等的socket对
-它将配对中的第一个套接字链接到本地套接字,而本地套接字又链接到远程套接字
-它发送第二个socket的文件描述符直接通过sendmsg()发送给JDWP进程
JDWP thread @vm-debug-control
| |
| <----------------------|
| OK, try this file descriptor |
| |
| |
然后,JDWP线程使用这个新的socket描述符做为它链接到调试器的通道(例如,并且通过它接受JDWP握手消息,并用它应答)
流程图:
____________________________________
88 | |
89 | ADB Server (host) |
90 | |
91 Debugger <---> LocalSocket <----> RemoteSocket |
92 | ^^ |
93 |___________________________||_______|
94 ||
95 Transport ||
96 (TCP for emulator - USB for device) ||
97 ||
98 ___________________________||_______
99 | || |
100 | ADBD (device) || |
101 | VV |
102 JDWP <======> LocalSocket <----> RemoteSocket |
103 | |
104 |____________________________________|
由于adb的工作方式,这并不需要特别的socket类型或者当socket终止时或者调试器或者JDWP进程关闭链接时要做什么复杂的处理。
自己:这就像个交换机
1.创建 UDS socket 并监听
name of the debug control Unix socket
JDWP_CONTROL_NAME = \0jdwp-control
/dev/socket/0jdwp-control
2.对握手后的socket fdevent_create()
并关闭serverSocket 0jdwp-control
初始化环节完成
对方是谁?
Dalvik 的 jdwp 线程(c层,在虚拟机启动时,启动的一个pthread,会先通过 /dev/socket/\0jdwp-control 和adbd 建立链接)
JDWPAdb
3.fdevent_loop() 处理socket 的命令
在一个循环里 用 select() 找出要处理的 socket fd,然后进行读写