Skip to content

Commit e742d07

Browse files
committed
Enable debugging.
Use the --debug command line flag to enable. It appears that d8 sucks. Luckily it can be rewritten rather easily with the repl and tcp client libraries. Node's CL option parsing is getting rather unwieldy - needs refactor.
1 parent 59b7a1b commit e742d07

5 files changed

Lines changed: 76 additions & 0 deletions

File tree

deps/v8/include/v8-debug.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ class EXPORT Debug {
188188
*/
189189
typedef void (*HostDispatchHandler)();
190190

191+
/**
192+
* Callback function for the host to ensure debug messages are processed.
193+
*/
194+
typedef void (*DebugMessageDispatchHandler)();
195+
191196
// Set a C debug event listener.
192197
static bool SetDebugEventListener(EventCallback that,
193198
Handle<Value> data = Handle<Value>());
@@ -211,6 +216,18 @@ class EXPORT Debug {
211216
static void SetHostDispatchHandler(HostDispatchHandler handler,
212217
int period = 100);
213218

219+
/**
220+
* Register a callback function to be called when a debug message has been
221+
* received and is ready to be precessed. For the debug messages to be
222+
* processed V8 needs to be entered, and in certain embedding scenarios this
223+
* callback can be used to make sure V8 is entered for the debug message to
224+
* be processed. Note that debug messages will only be processed if there is
225+
* a V8 break. This can happen automatically by using the option
226+
* --debugger-auto-break.
227+
*/
228+
static void SetDebugMessageDispatchHandler(
229+
DebugMessageDispatchHandler handler);
230+
214231
/**
215232
* Run a JavaScript function in the debugger.
216233
* \param fun the function to call

deps/v8/src/api.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,6 +3642,14 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
36423642
}
36433643

36443644

3645+
void Debug::SetDebugMessageDispatchHandler(
3646+
DebugMessageDispatchHandler handler) {
3647+
EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
3648+
ENTER_V8;
3649+
i::Debugger::SetDebugMessageDispatchHandler(handler);
3650+
}
3651+
3652+
36453653
Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
36463654
v8::Handle<v8::Value> data) {
36473655
if (!i::V8::IsRunning()) return Local<Value>();

deps/v8/src/debug.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,8 @@ bool Debugger::never_unload_debugger_ = false;
17581758
v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
17591759
bool Debugger::debugger_unload_pending_ = false;
17601760
v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
1761+
v8::Debug::DebugMessageDispatchHandler
1762+
Debugger::debug_message_dispatch_handler_ = NULL;
17611763
int Debugger::host_dispatch_micros_ = 100 * 1000;
17621764
DebuggerAgent* Debugger::agent_ = NULL;
17631765
LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
@@ -2389,6 +2391,12 @@ void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
23892391
}
23902392

23912393

2394+
void Debugger::SetDebugMessageDispatchHandler(
2395+
v8::Debug::DebugMessageDispatchHandler handler) {
2396+
debug_message_dispatch_handler_ = handler;
2397+
}
2398+
2399+
23922400
// Calls the registered debug message handler. This callback is part of the
23932401
// public API.
23942402
void Debugger::InvokeMessageHandler(MessageImpl message) {
@@ -2419,6 +2427,10 @@ void Debugger::ProcessCommand(Vector<const uint16_t> command,
24192427
if (!Debug::InDebugger()) {
24202428
StackGuard::DebugCommand();
24212429
}
2430+
2431+
if (Debugger::debug_message_dispatch_handler_ != NULL) {
2432+
Debugger::debug_message_dispatch_handler_();
2433+
}
24222434
}
24232435

24242436

deps/v8/src/debug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ class Debugger {
625625
static void SetMessageHandler(v8::Debug::MessageHandler2 handler);
626626
static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
627627
int period);
628+
static void SetDebugMessageDispatchHandler(
629+
v8::Debug::DebugMessageDispatchHandler handler);
628630

629631
// Invoke the message handler function.
630632
static void InvokeMessageHandler(MessageImpl message);
@@ -685,6 +687,7 @@ class Debugger {
685687
static v8::Debug::MessageHandler2 message_handler_;
686688
static bool debugger_unload_pending_; // Was message handler cleared?
687689
static v8::Debug::HostDispatchHandler host_dispatch_handler_;
690+
static v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_;
688691
static int host_dispatch_micros_;
689692

690693
static DebuggerAgent* agent_;

src/node.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern char **environ;
3030
namespace node {
3131

3232
static int dash_dash_index = 0;
33+
static bool use_debug_agent = false;
3334

3435
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
3536
HandleScope scope;
@@ -325,6 +326,21 @@ static void EIOWantPoll(void) {
325326
ev_async_send(EV_DEFAULT_UC_ &eio_watcher);
326327
}
327328

329+
static ev_async debug_watcher;
330+
331+
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) {
332+
HandleScope scope;
333+
assert(watcher == &debug_watcher);
334+
assert(revents == EV_ASYNC);
335+
ExecuteString(String::New("1+1;"),
336+
String::New("debug_poll"));
337+
}
338+
339+
static void DebugMessageDispatch(void) {
340+
ev_async_send(EV_DEFAULT_UC_ &debug_watcher);
341+
}
342+
343+
328344
static void ExecuteNativeJS(const char *filename, const char *data) {
329345
HandleScope scope;
330346
TryCatch try_catch;
@@ -434,18 +450,24 @@ static void CallExitHandler() {
434450
static void PrintHelp() {
435451
printf("Usage: node [options] [--] script.js [arguments] \n"
436452
" -v, --version print node's version\n"
453+
" --debug enable remote debugging\n" // TODO specify port
437454
" --cflags print pre-processor and compiler flags\n"
438455
" --v8-options print v8 command line options\n\n"
439456
"Documentation can be found at http://tinyclouds.org/node/api.html"
440457
" or with 'man node'\n");
441458
}
442459

443460
static void ParseArgs(int *argc, char **argv) {
461+
// TODO use parse opts
444462
for (int i = 1; i < *argc; i++) {
445463
const char *arg = argv[i];
446464
if (strcmp(arg, "--") == 0) {
447465
dash_dash_index = i;
448466
break;
467+
} else if (strcmp(arg, "--debug") == 0) {
468+
argv[i] = reinterpret_cast<const char*>("");
469+
use_debug_agent = true;
470+
dash_dash_index = i;
449471
} else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
450472
printf("%s\n", NODE_VERSION);
451473
exit(0);
@@ -488,6 +510,20 @@ int main(int argc, char *argv[]) {
488510

489511
HandleScope handle_scope;
490512

513+
#define AUTO_BREAK_FLAG "--debugger_auto_break"
514+
if (node::use_debug_agent) {
515+
V8::SetFlagsFromString(AUTO_BREAK_FLAG, sizeof(AUTO_BREAK_FLAG));
516+
ev_async_init(&node::debug_watcher, node::DebugMessageCallback);
517+
Debug::SetDebugMessageDispatchHandler(node::DebugMessageDispatch);
518+
ev_async_start(EV_DEFAULT_UC_ &node::debug_watcher);
519+
ev_unref(EV_DEFAULT_UC);
520+
521+
bool r = Debug::EnableAgent("node " NODE_VERSION, 5858);
522+
assert(r);
523+
printf("debugger listening on port 5858\n"
524+
"Use 'd8 --remote_debugger' to access it.\n");
525+
}
526+
491527
Local<FunctionTemplate> process_template = FunctionTemplate::New();
492528

493529
// The global object / "process" is an instance of EventEmitter. For

0 commit comments

Comments
 (0)