Skip to content

Instantly share code, notes, and snippets.

@zoka
Created February 22, 2010 02:57
Show Gist options
  • Save zoka/310733 to your computer and use it in GitHub Desktop.
Save zoka/310733 to your computer and use it in GitHub Desktop.
diff --git a/src/node.cc b/src/node.cc
index 648c4d1..85d20f4 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,45 @@ 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");
+ printf("Execution will stop in node.js\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 +1034,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 +1107,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 +1118,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 +1164,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 +1263,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