|
@ -1426,7 +1426,6 @@ void FatalException(TryCatch &try_catch) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ev_async debug_watcher; |
|
|
static ev_async debug_watcher; |
|
|
volatile static bool debugger_msg_pending = false; |
|
|
|
|
|
|
|
|
|
|
|
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) { |
|
|
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) { |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
@ -1441,48 +1440,13 @@ static void DebugMessageDispatch(void) { |
|
|
|
|
|
|
|
|
// Send a signal to our main thread saying that it should enter V8 to
|
|
|
// Send a signal to our main thread saying that it should enter V8 to
|
|
|
// handle the message.
|
|
|
// handle the message.
|
|
|
debugger_msg_pending = true; |
|
|
|
|
|
ev_async_send(EV_DEFAULT_UC_ &debug_watcher); |
|
|
ev_async_send(EV_DEFAULT_UC_ &debug_watcher); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static Handle<Value> CheckBreak(const Arguments& args) { |
|
|
static void DebugBreakMessageHandler(const Debug::Message& message) { |
|
|
HandleScope scope; |
|
|
// do nothing with debug messages.
|
|
|
assert(args.Length() == 0); |
|
|
// The message handler will get changed by DebuggerAgent::CreateSession in
|
|
|
|
|
|
// debug-agent.cc of v8/src when a new session is created
|
|
|
// 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(); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Persistent<Object> binding_cache; |
|
|
Persistent<Object> binding_cache; |
|
@ -1626,7 +1590,6 @@ static void Load(int argc, char *argv[]) { |
|
|
NODE_SET_METHOD(process, "dlopen", DLOpen); |
|
|
NODE_SET_METHOD(process, "dlopen", DLOpen); |
|
|
NODE_SET_METHOD(process, "kill", Kill); |
|
|
NODE_SET_METHOD(process, "kill", Kill); |
|
|
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage); |
|
|
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage); |
|
|
NODE_SET_METHOD(process, "checkBreak", CheckBreak); |
|
|
|
|
|
|
|
|
|
|
|
NODE_SET_METHOD(process, "binding", Binding); |
|
|
NODE_SET_METHOD(process, "binding", Binding); |
|
|
|
|
|
|
|
@ -1775,7 +1738,20 @@ int main(int argc, char *argv[]) { |
|
|
node::ParseArgs(&argc, argv); |
|
|
node::ParseArgs(&argc, argv); |
|
|
// Parse the rest of the args (up to the 'option_end_index' (where '--' was
|
|
|
// Parse the rest of the args (up to the 'option_end_index' (where '--' was
|
|
|
// in the command line))
|
|
|
// 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
|
|
|
// Ignore SIGPIPE
|
|
|
struct sigaction sa; |
|
|
struct sigaction sa; |
|
@ -1851,6 +1827,13 @@ int main(int argc, char *argv[]) { |
|
|
|
|
|
|
|
|
// Start the debug thread and it's associated TCP server on port 5858.
|
|
|
// Start the debug thread and it's associated TCP server on port 5858.
|
|
|
bool r = Debug::EnableAgent("node " NODE_VERSION, node::debug_port); |
|
|
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
|
|
|
// Crappy check that everything went well. FIXME
|
|
|
assert(r); |
|
|
assert(r); |
|
|