static ev_async debug_watcher;
-volatile static bool debugger_msg_pending = false;
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) {
HandleScope scope;
// Send a signal to our main thread saying that it should enter V8 to
// handle the message.
- debugger_msg_pending = true;
ev_async_send(EV_DEFAULT_UC_ &debug_watcher);
}
-static Handle<Value> CheckBreak(const Arguments& args) {
- HandleScope scope;
- assert(args.Length() == 0);
-
- // TODO FIXME This function is a hack to wait until V8 is ready to accept
- // commands. There seems to be a bug in EnableAgent( _ , _ , true) which
- // makes it unusable here. Ideally we'd be able to bind EnableAgent and
- // get it to halt until Eclipse connects.
-
- if (!debug_wait_connect)
- return Undefined();
-
- printf("Waiting for remote debugger connection...\n");
-
- const int halfSecond = 50;
- const int tenMs=10000;
- debugger_msg_pending = false;
- for (;;) {
- if (debugger_msg_pending) {
- Debug::DebugBreak();
- Debug::ProcessDebugMessages();
- debugger_msg_pending = false;
-
- // wait for 500 msec of silence from remote debugger
- int cnt = halfSecond;
- while (cnt --) {
- debugger_msg_pending = false;
- usleep(tenMs);
- if (debugger_msg_pending) {
- debugger_msg_pending = false;
- cnt = halfSecond;
- }
- }
- break;
- }
- usleep(tenMs);
- }
- return Undefined();
+static void DebugBreakMessageHandler(const Debug::Message& message) {
+ // do nothing with debug messages.
+ // The message handler will get changed by DebuggerAgent::CreateSession in
+ // debug-agent.cc of v8/src when a new session is created
}
Persistent<Object> binding_cache;
NODE_SET_METHOD(process, "dlopen", DLOpen);
NODE_SET_METHOD(process, "kill", Kill);
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
- NODE_SET_METHOD(process, "checkBreak", CheckBreak);
NODE_SET_METHOD(process, "binding", Binding);
node::ParseArgs(&argc, argv);
// Parse the rest of the args (up to the 'option_end_index' (where '--' was
// in the command line))
- V8::SetFlagsFromCommandLine(&node::option_end_index, argv, false);
+ int v8argc = node::option_end_index;
+ char **v8argv = argv;
+
+ if (node::debug_wait_connect) {
+ // v8argv is a copy of argv up to the script file argument +2 if --debug-brk
+ // to expose the v8 debugger js object so that module.js can set
+ // a breakpoint on the first line of the startup script
+ v8argc += 2;
+ v8argv = new char*[v8argc];
+ memcpy(v8argv, argv, sizeof(argv) * node::option_end_index);
+ v8argv[node::option_end_index] = const_cast<char*>("--expose_debug_as");
+ v8argv[node::option_end_index + 1] = const_cast<char*>("v8debug");
+ }
+ V8::SetFlagsFromCommandLine(&v8argc, v8argv, false);
// Ignore SIGPIPE
struct sigaction sa;
// Start the debug thread and it's associated TCP server on port 5858.
bool r = Debug::EnableAgent("node " NODE_VERSION, node::debug_port);
+ if (node::debug_wait_connect) {
+ // Set up an empty handler so v8 will not continue until a debugger
+ // attaches. This is the same behavior as Debug::EnableAgent(_,_,true)
+ // except we don't break at the beginning of the script.
+ // see Debugger::StartAgent in debug.cc of v8/src
+ Debug::SetMessageHandler2(node::DebugBreakMessageHandler);
+ }
// Crappy check that everything went well. FIXME
assert(r);