Browse Source

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.
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
e742d077e0
  1. 17
      deps/v8/include/v8-debug.h
  2. 8
      deps/v8/src/api.cc
  3. 12
      deps/v8/src/debug.cc
  4. 3
      deps/v8/src/debug.h
  5. 36
      src/node.cc

17
deps/v8/include/v8-debug.h

@ -188,6 +188,11 @@ class EXPORT Debug {
*/ */
typedef void (*HostDispatchHandler)(); typedef void (*HostDispatchHandler)();
/**
* Callback function for the host to ensure debug messages are processed.
*/
typedef void (*DebugMessageDispatchHandler)();
// Set a C debug event listener. // Set a C debug event listener.
static bool SetDebugEventListener(EventCallback that, static bool SetDebugEventListener(EventCallback that,
Handle<Value> data = Handle<Value>()); Handle<Value> data = Handle<Value>());
@ -211,6 +216,18 @@ class EXPORT Debug {
static void SetHostDispatchHandler(HostDispatchHandler handler, static void SetHostDispatchHandler(HostDispatchHandler handler,
int period = 100); int period = 100);
/**
* Register a callback function to be called when a debug message has been
* received and is ready to be precessed. For the debug messages to be
* processed V8 needs to be entered, and in certain embedding scenarios this
* callback can be used to make sure V8 is entered for the debug message to
* be processed. Note that debug messages will only be processed if there is
* a V8 break. This can happen automatically by using the option
* --debugger-auto-break.
*/
static void SetDebugMessageDispatchHandler(
DebugMessageDispatchHandler handler);
/** /**
* Run a JavaScript function in the debugger. * Run a JavaScript function in the debugger.
* \param fun the function to call * \param fun the function to call

8
deps/v8/src/api.cc

@ -3642,6 +3642,14 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
} }
void Debug::SetDebugMessageDispatchHandler(
DebugMessageDispatchHandler handler) {
EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
ENTER_V8;
i::Debugger::SetDebugMessageDispatchHandler(handler);
}
Local<Value> Debug::Call(v8::Handle<v8::Function> fun, Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
v8::Handle<v8::Value> data) { v8::Handle<v8::Value> data) {
if (!i::V8::IsRunning()) return Local<Value>(); if (!i::V8::IsRunning()) return Local<Value>();

12
deps/v8/src/debug.cc

@ -1758,6 +1758,8 @@ bool Debugger::never_unload_debugger_ = false;
v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL; v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
bool Debugger::debugger_unload_pending_ = false; bool Debugger::debugger_unload_pending_ = false;
v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
v8::Debug::DebugMessageDispatchHandler
Debugger::debug_message_dispatch_handler_ = NULL;
int Debugger::host_dispatch_micros_ = 100 * 1000; int Debugger::host_dispatch_micros_ = 100 * 1000;
DebuggerAgent* Debugger::agent_ = NULL; DebuggerAgent* Debugger::agent_ = NULL;
LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
@ -2389,6 +2391,12 @@ void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
} }
void Debugger::SetDebugMessageDispatchHandler(
v8::Debug::DebugMessageDispatchHandler handler) {
debug_message_dispatch_handler_ = handler;
}
// Calls the registered debug message handler. This callback is part of the // Calls the registered debug message handler. This callback is part of the
// public API. // public API.
void Debugger::InvokeMessageHandler(MessageImpl message) { void Debugger::InvokeMessageHandler(MessageImpl message) {
@ -2419,6 +2427,10 @@ void Debugger::ProcessCommand(Vector<const uint16_t> command,
if (!Debug::InDebugger()) { if (!Debug::InDebugger()) {
StackGuard::DebugCommand(); StackGuard::DebugCommand();
} }
if (Debugger::debug_message_dispatch_handler_ != NULL) {
Debugger::debug_message_dispatch_handler_();
}
} }

3
deps/v8/src/debug.h

@ -625,6 +625,8 @@ class Debugger {
static void SetMessageHandler(v8::Debug::MessageHandler2 handler); static void SetMessageHandler(v8::Debug::MessageHandler2 handler);
static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
int period); int period);
static void SetDebugMessageDispatchHandler(
v8::Debug::DebugMessageDispatchHandler handler);
// Invoke the message handler function. // Invoke the message handler function.
static void InvokeMessageHandler(MessageImpl message); static void InvokeMessageHandler(MessageImpl message);
@ -685,6 +687,7 @@ class Debugger {
static v8::Debug::MessageHandler2 message_handler_; static v8::Debug::MessageHandler2 message_handler_;
static bool debugger_unload_pending_; // Was message handler cleared? static bool debugger_unload_pending_; // Was message handler cleared?
static v8::Debug::HostDispatchHandler host_dispatch_handler_; static v8::Debug::HostDispatchHandler host_dispatch_handler_;
static v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_;
static int host_dispatch_micros_; static int host_dispatch_micros_;
static DebuggerAgent* agent_; static DebuggerAgent* agent_;

36
src/node.cc

@ -30,6 +30,7 @@ extern char **environ;
namespace node { namespace node {
static int dash_dash_index = 0; static int dash_dash_index = 0;
static bool use_debug_agent = false;
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) { enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
HandleScope scope; HandleScope scope;
@ -325,6 +326,21 @@ static void EIOWantPoll(void) {
ev_async_send(EV_DEFAULT_UC_ &eio_watcher); ev_async_send(EV_DEFAULT_UC_ &eio_watcher);
} }
static ev_async debug_watcher;
static void DebugMessageCallback(EV_P_ ev_async *watcher, int revents) {
HandleScope scope;
assert(watcher == &debug_watcher);
assert(revents == EV_ASYNC);
ExecuteString(String::New("1+1;"),
String::New("debug_poll"));
}
static void DebugMessageDispatch(void) {
ev_async_send(EV_DEFAULT_UC_ &debug_watcher);
}
static void ExecuteNativeJS(const char *filename, const char *data) { static void ExecuteNativeJS(const char *filename, const char *data) {
HandleScope scope; HandleScope scope;
TryCatch try_catch; TryCatch try_catch;
@ -434,6 +450,7 @@ static void CallExitHandler() {
static void PrintHelp() { static void PrintHelp() {
printf("Usage: node [options] [--] script.js [arguments] \n" printf("Usage: node [options] [--] script.js [arguments] \n"
" -v, --version print node's version\n" " -v, --version print node's version\n"
" --debug enable remote debugging\n" // TODO specify port
" --cflags print pre-processor and compiler flags\n" " --cflags print pre-processor and compiler flags\n"
" --v8-options print v8 command line options\n\n" " --v8-options print v8 command line options\n\n"
"Documentation can be found at http://tinyclouds.org/node/api.html" "Documentation can be found at http://tinyclouds.org/node/api.html"
@ -441,11 +458,16 @@ static void PrintHelp() {
} }
static void ParseArgs(int *argc, char **argv) { static void ParseArgs(int *argc, char **argv) {
// TODO use parse opts
for (int i = 1; i < *argc; i++) { for (int i = 1; i < *argc; i++) {
const char *arg = argv[i]; const char *arg = argv[i];
if (strcmp(arg, "--") == 0) { if (strcmp(arg, "--") == 0) {
dash_dash_index = i; dash_dash_index = i;
break; break;
} else if (strcmp(arg, "--debug") == 0) {
argv[i] = reinterpret_cast<const char*>("");
use_debug_agent = true;
dash_dash_index = i;
} else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) { } else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
printf("%s\n", NODE_VERSION); printf("%s\n", NODE_VERSION);
exit(0); exit(0);
@ -488,6 +510,20 @@ int main(int argc, char *argv[]) {
HandleScope handle_scope; HandleScope handle_scope;
#define AUTO_BREAK_FLAG "--debugger_auto_break"
if (node::use_debug_agent) {
V8::SetFlagsFromString(AUTO_BREAK_FLAG, sizeof(AUTO_BREAK_FLAG));
ev_async_init(&node::debug_watcher, node::DebugMessageCallback);
Debug::SetDebugMessageDispatchHandler(node::DebugMessageDispatch);
ev_async_start(EV_DEFAULT_UC_ &node::debug_watcher);
ev_unref(EV_DEFAULT_UC);
bool r = Debug::EnableAgent("node " NODE_VERSION, 5858);
assert(r);
printf("debugger listening on port 5858\n"
"Use 'd8 --remote_debugger' to access it.\n");
}
Local<FunctionTemplate> process_template = FunctionTemplate::New(); Local<FunctionTemplate> process_template = FunctionTemplate::New();
// The global object / "process" is an instance of EventEmitter. For // The global object / "process" is an instance of EventEmitter. For

Loading…
Cancel
Save