How remote debugging works in Chrome

Chrome for Android allows pages to be debugged remotely from the desktop. The wire protocol for debugging is specified here. This post gives an overview on how the bridge is setup between desktop chrome and android chrome.

10,000 foot view
When the Android phone is in Developer mode and USB debugging is enabled, Chrome for Android allows itself to be debugged through Unix domain sockets. One can connect to this socket and obtain a list of open pages. Each page has a corresponding websocket debug URL which can be used to debug the page.

Finding the unix domain socket
/proc/net/unix contains the list of unix domain sockets. Chrome creates sockets with _devtools_remote somewhere in the name of the socket (see devtools_adb_bridge.cc).

You can view it by using the following command on the host:

adb shell cat /proc/shell/unix | grep _devtools_remote

The output should be something like this:

00000000: 00000002 00000000 00010000 0001 01 107909 @chrome_devtools_remote_8985
00000000: 00000002 00000000 00010000 0001 01 87977 @chrome_devtools_remote

There are two sockets listed because I have Chrome Beta and Chrome running at the same time. The ‘@’ in front of the socket name implies an abstract socket.

Setup adb forwarding
Next step is to connect to the abstract socket and find out the list of open pages. We setup forwarding through adb.

adb forward tcp:4000 localabstract:chrome_devtools_remote_8985

The port 4000 was chosen at random. The above line makes adb forward any connections to localhost TCP port 4000 to the abstract socket named chrome_devtools_remote_8985 over USB.

Getting list of pages
We can now connect to port 4000 to get the list of pages.

curl localhost:4000/json

You should see output like so:

[ {
   "description": "",
   "devtoolsFrontendUrl": "http://chrome-devtools-frontend.appspot.com/serve_rev/@165554/devtools.html?ws=localhost:4000/devtools/page/0",
   "id": "0",
   "title": "https://www.google.com/url?sa=t&source=web&rct=j&ei=aEPpUq3iIMrFoATNqYDwDQ&url=http://m.youtube.com/watch%3Fv%3DoHg5SJYRHA0&cd=3&ved=0CC8QtwIwAg&usg=AFQjCNE6GowB7mL72VHPMCbZco5bTpnXbA&sig2=GBopoUdf_D-kofy7N2c80w",
   "type": "page",
   "url": "https://www.google.com/url?sa=t&source=web&rct=j&ei=aEPpUq3iIMrFoATNqYDwDQ&url=http://m.youtube.com/watch%3Fv%3DoHg5SJYRHA0&cd=3&ved=0CC8QtwIwAg&usg=AFQjCNE6GowB7mL72VHPMCbZco5bTpnXbA&sig2=GBopoUdf_D-kofy7N2c80w",
   "webSocketDebuggerUrl": "ws://localhost:4000/devtools/page/0"
} ]

The webSocketDebuggerUrl above gives you the URL you can talk the remote debug protocol!

Connecting to the page

wscat allows you to talk to web sockets.

wscat -c ws://localhost:4000/devtools/page/0

You can now type away json commands. The remote debugging protocol is best understood with some source code. Which leads us to devtools ui.

Installing devtools
The DevTools UI that is part of chrome is just plain ol’ HTML/CSS/JS. You can just download it and ask it to connect to the websocket above!.

Download Devtools from here (The code is part of Blink). Extract and serve up the contents using a web server (I use serve).

In your browser, http://localhost:3000/front_end/inspector.html?ws=localhost:4000/devtools/page/0. Here, localhost:3000 is the port of your local webserver. localhost:4000 is our bridge to Chrome Android. That’s it!

 

twitter