Monday, December 29, 2014

Chrome Remote Operation--work in process

Now that I'm making a debugger abstraction it's time to think about eating my own dogfood by connecting my IDE to a Chrome debugger instance running an application--or even another instance of the debugger.

Even better, it looks like the the chrome-remote-debugger API will not only let me debug a remote instance of Chrome, it will let me control and monitor everything that happens.

The node module is here.

To run more than one debugger on an instance requires crmux, here.

And a partially implemented console that I might be able to read to understand what to do is here.

So far I've been able to do this:

1. Run my debugger with an external debug port:

google-chrome --remote-debugging-port=9222&
9222 is the standard debugging port.

2. Run crmux in a separate window

crmux

This multiplexes the debugger on 9222 to be available on 9223

3. Now I can use the chrome-remote-api REPL

./node_modules/chrome-remote-interface/bin/repl.js -p 9223
Proof that it works: if crmux is not running, it gives an error.

4. Now I can open a page at

     http://localhost:9223

This gives me a list of debuggable pages. If I choose the one that I want I get this URL:

http://localhost:9223/devtools/devtools.html?ws=localhost:9222/devtools/page/7F642E19-7F9A-40AB-BE87-B344B6307246

Note the ws=localhost:9222. This is the original port and can interfere with things. So I must manually change to ....?ws=localhost:9223...

Proof that this works: I can kill crmux and things no longer work.

5. If I now run

crconsole -p 9223

I get a prompt. (It fails if crmux is not running)

And if I type the command

.tabs

I get something like this:

localhost> .tabs
[0] http://localhost:9223/devtools/devtools.html?ws=localhost:9223/devtools/page/7F642E19-7F9A-40AB-BE87-B344B6307246
[1] http://localhost:3333/IDE
[2] chrome-extension://jnihajbhpnppcggbcgedagnkighmdlei/_generated_background_page.html
[3] chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/_generated_background_page.html
[4] chrome-extension://diebikgmpmeppiilkaijjbdgciafajmg/background.html
localhost> 

OK. Those are the right tabs.

But no matter what order I use, I haven't been able to get both the Chrome debugger and crconsole ot play nicely together.

But: I was able to run an instance of crdebug and an instance of the chrome-remote-interface REPL together, and evaluate the following this in the REPL

chrome> Runtime.evaluate({expression: 'foo = 20'}, console.log)
Output is:
chrome> false { result: { type: 'number', value: 20, description: '20' },  wasThrown: false }
And the result, 'foo=20' appears in the other console. So I have two different consoles talking to the same chrome instance.

The problem comes when I run one chrome debugger instance along with a crdebug instance. Depending on which one I start first, the other fails.

If I run devtools first, then crconsole fails:
TypeError: Parameter 'url' must be a string, not undefined    at Url.parse (url.js:107:11)    at Object.urlParse [as parse] (url.js:101:5)    at WebSocket.initAsClient (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/node_modules/chrome-remote-interface/node_modules/ws/lib/WebSocket.js:475:23)    at new WebSocket (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/node_modules/chrome-remote-interface/node_modules/ws/lib/WebSocket.js:59:18)    at Chrome.connectToWebSocket (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/node_modules/chrome-remote-interface/lib/chrome.js:112:15)    at Object.ChromeREPL.setTab (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/index.js:223:17)    at Object.<anonymous> (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/index.js:23:12)    at /home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/index.js:167:7    at IncomingMessage.<anonymous> (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crconsole/node_modules/chrome-remote-interface/lib/chrome.js:104:13)    at IncomingMessage.EventEmitter.emit (events.js:117:20)
The code c

Then crmux fails this way:
/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/crmux.js:103           msgObj.id = idMap.id;                            ^TypeError: Cannot read property 'id' of undefined    at WebSocket.<anonymous> (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/crmux.js:103:29)    at WebSocket.EventEmitter.emit (events.js:98:17)    at Receiver.self._receiver.ontext (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/node_modules/ws/lib/WebSocket.js:682:10)    at Receiver.opcodes.1.finish (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/node_modules/ws/lib/Receiver.js:391:14)    at Receiver.expectHandler (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/node_modules/ws/lib/Receiver.js:378:31)    at Receiver.add (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/node_modules/ws/lib/Receiver.js:87:24)    at Socket.firstHandler (/home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/node_modules/ws/lib/WebSocket.js:663:22)    at Socket.EventEmitter.emit (events.js:95:17)    at Socket.<anonymous> (_stream_readable.js:746:14)    at Socket.EventEmitter.emit (events.js:92:17)
The crmux code can be debugged with:

node-debug --preload 0 /home/awesome/tools/node-v0.10.26-linux-x86/lib/node_modules/crmux/crmux.js

The problem occurs when we can't map an upstream ID to a downstream one. That is going to take a bit before we can deal with it. It probably has to do with the DevTools debugger making sure that the IDs that it gets are correct ones, and that it does not see an ID that it does not understand.

I can probably solve this by opening a debugger on the debugger and debugging it.