asvd / jailed

execute untrusted code with custom permissions
MIT License
1k stars 69 forks source link

Debugging child process #5

Open gfduszynski opened 9 years ago

gfduszynski commented 9 years ago

I've encountered a problem while debugging app using jailed in WebStorm. If i run the app in debug mode I get EADDRINUSE.

However I found that adding '--debug' to execArgv on line 205 of jailed.js not only prevents the issue from occurring but also allows for debugging of plugin code.

It would be great if this argument could be added only while the app is debugged.

asvd commented 9 years ago

That would be a nice feature, I will certainly work on it soon.

Two questions:

  1. Could you please show the exact code about the line 205, which makes it work for you?
  2. Which version of Node.js do you use? On my 0.10.25 if I simply add --debug argument for the subprocess, it tries to debug it on the same port. So I think the subprocess should start debugger on a different port (it works for node-inspector, but I'm not sure how WebStorm would treat that).
gfduszynski commented 9 years ago

Sorry for late response. I've changed:

__jailed__path__+'_pluginNode.js'

to:

__jailed__path__+'_pluginNode.js' ,[],{execArgv: ['--debug']} 

I'm using node 0.12.0 As for the argument '--debug' I've also tried --debug-brk=''

I have problem reproducing the situation it was working in. I don't have the error but the execution doesn't stop on break points. Probably I've broken something :)

I'll post an update when I get it working again.

asvd commented 9 years ago

no hurries :-)

I don't have the error but the execution doesn't stop on break points.

The same issue for me, I did not manage to get into the plugin code (honestly I never did that before).

gfduszynski commented 9 years ago

Ok I think I've got the debugging of child process right. That does not include vm at the moment.

Basically what's happening is that WebStorm runs main script with --debug-brk=. All exec args by default are inherited by child process and therefore it inherits --debug-brk=.

So that's the actual issue, now the solution. We need to copy execArgs and look for --debug-brk= and replace it with --debug-brk=<number + 1>. So that evvery child gets a free port. Then WebStorm magically connects to those processes and opens new tabs for them. (Well actually it's not magic, it reads console log :D)

My 'hack' implementation looks like this (note that 'i' is defined elsewhere and it has value of 47000 at start):

this._process = childProcess.fork(
    __jailed__path__+'_pluginNode.js'
    ,[],{execArgv: ['--debug-brk='+(i++)]} //HOT-FIX
);

This enables me to debug child processes but not the plugin itself (yet). There are two known problems with that:

  1. I have no idea if that port is free (no collision so far)
  2. It always runs child processes in debug mode.

As for the vm/plugin im looking into http://stackoverflow.com/questions/21183403/debugging-code-that-is-run-in-node-jss-vm

Maybe I'll find something ;)

asvd commented 9 years ago

Great, thanks for the info!

I'm currently finishing another project, and after two weeks or so I will be able to swithc to this issue (or maybe randomly on the weekend, but not sure yet). Please contribute with any additional info which you investigate on, that is valuable.

What I was thinking of for this case is something like following:

  1. determine if we are in debug mode and find out the port the main process runs debugger on;
  2. find out the next available port and debug the child process on it.

The problem with debuggin the plugin code (not only process) may be related to the fact, that after the child process is started, it waits for the message from the main process, and only then loads the plugin code. Maybe this disables the debugger somehow...

gfduszynski commented 9 years ago

No problem ;) --debug-brk stops the script until the debugger is connected. So there is a natural delay.

asvd commented 9 years ago

Some additional thoughts:

This is how it worked for me:

The last point is the issue. Currently I guess that this happens because in case of Node.js, the message is sent right after the connection is initialized:

https://github.com/asvd/jailed/blob/master/lib/jailed.js#L620 (function provided to whenInit() is executed immediately in Node.js)

Which means the message might be send before I manually continue the execution, and therefore the message might not be handled.