|
@ -17,11 +17,6 @@ |
|
|
#include <pwd.h> /* getpwnam() */ |
|
|
#include <pwd.h> /* getpwnam() */ |
|
|
#include <grp.h> /* getgrnam() */ |
|
|
#include <grp.h> /* getgrnam() */ |
|
|
|
|
|
|
|
|
// waitpid
|
|
|
|
|
|
#include <sys/types.h> |
|
|
|
|
|
#include <sys/wait.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "platform.h" |
|
|
#include "platform.h" |
|
|
|
|
|
|
|
|
#include <node_buffer.h> |
|
|
#include <node_buffer.h> |
|
@ -92,7 +87,6 @@ static ev_idle tick_spinner; |
|
|
static bool need_tick_cb; |
|
|
static bool need_tick_cb; |
|
|
static Persistent<String> tick_callback_sym; |
|
|
static Persistent<String> tick_callback_sym; |
|
|
|
|
|
|
|
|
static ev_async enable_debug; |
|
|
|
|
|
static ev_async eio_want_poll_notifier; |
|
|
static ev_async eio_want_poll_notifier; |
|
|
static ev_async eio_done_poll_notifier; |
|
|
static ev_async eio_done_poll_notifier; |
|
|
static ev_idle eio_poller; |
|
|
static ev_idle eio_poller; |
|
@ -1868,41 +1862,6 @@ static void SignalExit(int signal) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void EnableDebugSignalHandler(int signal) { |
|
|
|
|
|
// can't do much here, marshal this back into the main thread where we'll
|
|
|
|
|
|
// enable the debugger.
|
|
|
|
|
|
ev_async_send(EV_DEFAULT_UC_ &enable_debug); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void EnableDebug(bool wait_connect) { |
|
|
|
|
|
// Start the debug thread and it's associated TCP server on port 5858.
|
|
|
|
|
|
bool r = Debug::EnableAgent("node " NODE_VERSION, debug_port); |
|
|
|
|
|
|
|
|
|
|
|
if (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); |
|
|
|
|
|
|
|
|
|
|
|
// Print out some information.
|
|
|
|
|
|
fprintf(stderr, "debugger listening on port %d\r\n", debug_port); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void EnableDebug2(EV_P_ ev_async *watcher, int revents) { |
|
|
|
|
|
assert(watcher == &enable_debug); |
|
|
|
|
|
assert(revents == EV_ASYNC); |
|
|
|
|
|
EnableDebug(false); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int RegisterSignalHandler(int signal, void (*handler)(int)) { |
|
|
static int RegisterSignalHandler(int signal, void (*handler)(int)) { |
|
|
struct sigaction sa; |
|
|
struct sigaction sa; |
|
|
|
|
|
|
|
@ -1913,57 +1872,6 @@ static int RegisterSignalHandler(int signal, void (*handler)(int)) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool debugger_slave_running = false; |
|
|
|
|
|
|
|
|
|
|
|
static void HandleDebugEvent(DebugEvent event, |
|
|
|
|
|
Handle<Object> exec_state, |
|
|
|
|
|
Handle<Object> event_data, |
|
|
|
|
|
Handle<Value> data) { |
|
|
|
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
|
|
|
if (debugger_slave_running) return; |
|
|
|
|
|
|
|
|
|
|
|
if (event != Break) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Then we take one of two actions
|
|
|
|
|
|
// 1. Inspect the environ variable NODE_DEBUG_PROG; if it is not empty //
|
|
|
|
|
|
// then start it. (TODO)
|
|
|
|
|
|
// 2. Start the built-in debugger.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t size = 2*PATH_MAX; |
|
|
|
|
|
char node_path[size]; |
|
|
|
|
|
OS::GetExecutablePath(node_path, &size); |
|
|
|
|
|
|
|
|
|
|
|
int pid = vfork(); |
|
|
|
|
|
|
|
|
|
|
|
if (pid == -1) { |
|
|
|
|
|
perror("vfork()"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (pid == 0) { |
|
|
|
|
|
// Child process
|
|
|
|
|
|
char *argv[] = { node_path, "debug", NULL }; |
|
|
|
|
|
execvp(node_path, argv); |
|
|
|
|
|
perror("execvp()"); |
|
|
|
|
|
_exit(127); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
debugger_slave_running = true; |
|
|
|
|
|
|
|
|
|
|
|
// We've hit some debugger event. First we will enable the debugger agent.
|
|
|
|
|
|
EnableDebug(true); |
|
|
|
|
|
|
|
|
|
|
|
// TODO probably need to waitpid here or something to avoid zombies.
|
|
|
|
|
|
// int status;
|
|
|
|
|
|
// waitpid(pid, &status, 0);
|
|
|
|
|
|
//Debug::DebugBreak();
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Start(int argc, char *argv[]) { |
|
|
int Start(int argc, char *argv[]) { |
|
|
// Hack aroung with the argv pointer. Used for process.title = "blah".
|
|
|
// Hack aroung with the argv pointer. Used for process.title = "blah".
|
|
|
argv = node::Platform::SetupArgs(argc, argv); |
|
|
argv = node::Platform::SetupArgs(argc, argv); |
|
@ -2059,7 +1967,8 @@ int Start(int argc, char *argv[]) { |
|
|
|
|
|
|
|
|
V8::SetFatalErrorHandler(node::OnFatalError); |
|
|
V8::SetFatalErrorHandler(node::OnFatalError); |
|
|
|
|
|
|
|
|
|
|
|
// If the --debug flag was specified then initialize the debug thread.
|
|
|
|
|
|
if (node::use_debug_agent) { |
|
|
// Initialize the async watcher for receiving messages from the debug
|
|
|
// Initialize the async watcher for receiving messages from the debug
|
|
|
// thread and marshal it into the main thread. DebugMessageCallback()
|
|
|
// thread and marshal it into the main thread. DebugMessageCallback()
|
|
|
// is called from the main thread to execute a random bit of javascript
|
|
|
// is called from the main thread to execute a random bit of javascript
|
|
@ -2075,16 +1984,20 @@ int Start(int argc, char *argv[]) { |
|
|
// unref it so that we exit the event loop despite it being active.
|
|
|
// unref it so that we exit the event loop despite it being active.
|
|
|
ev_unref(EV_DEFAULT_UC); |
|
|
ev_unref(EV_DEFAULT_UC); |
|
|
|
|
|
|
|
|
|
|
|
// 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); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// If the --debug flag was specified then initialize the debug thread.
|
|
|
// Crappy check that everything went well. FIXME
|
|
|
if (node::use_debug_agent) { |
|
|
assert(r); |
|
|
// XXX: only use if debug flag enabled?
|
|
|
// Print out some information.
|
|
|
Debug::SetDebugEventListener(HandleDebugEvent); |
|
|
printf("debugger listening on port %d\n", node::debug_port); |
|
|
} else { |
|
|
|
|
|
RegisterSignalHandler(SIGUSR1, EnableDebugSignalHandler); |
|
|
|
|
|
ev_async_init(&enable_debug, EnableDebug2); |
|
|
|
|
|
ev_async_start(EV_DEFAULT_UC_ &enable_debug); |
|
|
|
|
|
ev_unref(EV_DEFAULT_UC); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Create the one and only Context.
|
|
|
// Create the one and only Context.
|
|
|