Created
February 22, 2010 03:24
-
-
Save zoka/310745 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/node.cc b/src/node.cc | |
index 648c4d1..8efdf01 100644 | |
--- a/src/node.cc | |
+++ b/src/node.cc | |
@@ -62,6 +62,8 @@ static Persistent<String> emit_symbol; | |
static int option_end_index = 0; | |
static bool use_debug_agent = false; | |
+static bool debug_wait_connect = false; | |
+static int debug_port=5858; | |
static ev_async eio_want_poll_notifier; | |
@@ -909,6 +911,7 @@ void FatalException(TryCatch &try_catch) { | |
static ev_async debug_watcher; | |
+volatile static bool debugger_msg_pending = false; | |
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) { | |
HandleScope scope; | |
@@ -923,9 +926,44 @@ static void DebugMessageDispatch(void) { | |
// 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; | |
+ | |
+ 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 Load(int argc, char *argv[]) { | |
HandleScope scope; | |
@@ -995,6 +1033,7 @@ static void Load(int argc, char *argv[]) { | |
NODE_SET_METHOD(process, "dlopen", DLOpen); | |
NODE_SET_METHOD(process, "kill", Kill); | |
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage); | |
+ NODE_SET_METHOD(process, "checkBreak", CheckBreak); | |
// Assign the EventEmitter. It was created in main(). | |
process->Set(String::NewSymbol("EventEmitter"), | |
@@ -1067,6 +1106,7 @@ static void Load(int argc, char *argv[]) { | |
// Node's I/O bindings may want to replace 'f' with their own function. | |
Local<Value> args[1] = { Local<Value>::New(process) }; | |
+ | |
f->Call(global, 1, args); | |
#ifndef NDEBUG | |
@@ -1077,12 +1117,43 @@ static void Load(int argc, char *argv[]) { | |
#endif | |
} | |
+static void PrintHelp(); | |
+ | |
+static void ParseDebugOpt(const char* arg) { | |
+ const char *p = 0; | |
+ | |
+ use_debug_agent = true; | |
+ if (!strcmp (arg, "--debug-brk")) { | |
+ debug_wait_connect = true; | |
+ return; | |
+ } else if (!strcmp(arg, "--debug")) { | |
+ return; | |
+ } else if (strstr(arg, "--debug-brk=") == arg) { | |
+ debug_wait_connect = true; | |
+ p = 1 + strchr(arg, '='); | |
+ debug_port = atoi(p); | |
+ } else if (strstr(arg, "--debug=") == arg) { | |
+ p = 1 + strchr(arg, '='); | |
+ debug_port = atoi(p); | |
+ } | |
+ if (p && debug_port > 1024 && debug_port < 65536) | |
+ return; | |
+ | |
+ fprintf(stderr, "Bad debug option.\n"); | |
+ if (p) fprintf(stderr, "Debug port must be in range 1025 to 65535.\n"); | |
+ | |
+ PrintHelp(); | |
+ exit(1); | |
+} | |
+ | |
static void PrintHelp() { | |
printf("Usage: node [options] script.js [arguments] \n" | |
- " -v, --version print node's version\n" | |
- " --debug enable remote debugging\n" // TODO specify port | |
- " --cflags print pre-processor and compiler flags\n" | |
- " --v8-options print v8 command line options\n\n" | |
+ " -v, --version print node's version\n" | |
+ " --debug[=port] enable remote debugging via given TCP port\n" | |
+ " --debug-brk[=port] as above, but break in node.js and\n" | |
+ " wait for remote debugger to connect\n" | |
+ " --cflags print pre-processor and compiler flags\n" | |
+ " --v8-options print v8 command line options\n\n" | |
"Documentation can be found at http://nodejs.org/api.html" | |
" or with 'man node'\n"); | |
} | |
@@ -1092,9 +1163,9 @@ static void ParseArgs(int *argc, char **argv) { | |
// TODO use parse opts | |
for (int i = 1; i < *argc; i++) { | |
const char *arg = argv[i]; | |
- if (strcmp(arg, "--debug") == 0) { | |
+ if (strstr(arg, "--debug") == arg) { | |
+ ParseDebugOpt(arg); | |
argv[i] = reinterpret_cast<const char*>(""); | |
- use_debug_agent = true; | |
option_end_index = i; | |
} else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) { | |
printf("%s\n", NODE_VERSION); | |
@@ -1191,12 +1262,12 @@ int main(int argc, char *argv[]) { | |
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, 5858); | |
+ bool r = Debug::EnableAgent("node " NODE_VERSION, node::debug_port); | |
+ | |
// Crappy check that everything went well. FIXME | |
assert(r); | |
- // Print out some information. REMOVEME | |
- printf("debugger listening on port 5858\n" | |
- "Use 'd8 --remote_debugger' to access it.\n"); | |
+ // Print out some information. | |
+ printf("debugger listening on port %d\n", node::debug_port); | |
} | |
// Create the one and only Context. | |
diff --git a/src/node.js b/src/node.js | |
index 66b9fe6..7ad28f2 100644 | |
--- a/src/node.js | |
+++ b/src/node.js | |
@@ -926,7 +926,10 @@ Module.prototype._loadContent = function (content, filename) { | |
try { | |
var compiledWrapper = process.compile(wrapper, filename); | |
- compiledWrapper.apply(self.exports, [self.exports, require, self, filename, path.dirname(filename)]); | |
+ var dirName = path.dirname(filename); | |
+ if (filename === process.argv[1]) | |
+ process.checkBreak(); | |
+ compiledWrapper.apply(self.exports, [self.exports, require, self, filename, dirName]); | |
} catch (e) { | |
return e; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment