Revision: 4376
Author: peter.rybin
Date: Fri Apr 9 06:24:11 2010
Log: Created wiki page through web user interface.
http://code.google.com/p/v8/source/detail?r=4376
Added:
/wiki/AddDebuggerSupport.wiki
=======================================
--- /dev/null
+++ /wiki/AddDebuggerSupport.wiki Fri Apr 9 06:24:11 2010
@@ -0,0 +1,67 @@
+#summary Adding debugger support to application HOW-TO.
+
+=How to debug !JavaScript in your V8-based application=
+
+When your !JavaScript scripts grow complex enough you may want to debug
them. V8 is ready for running scripts under debugger, but a few things need
to be done in the host application. V8 debug API is implemented as
JSON-based network protocol. There are 2 UI debuggers currently available:
D8 and “Google Chrome Developer Tools”.
+
+V8 is written in C++ and therefore may be run under C++ debugger (like
gdb). Unfortunately, you won’t be able to see a single !JavaScript artifact
from C++ debugger.
+
+There is a standard sample program lineprocessor.cc that illustrates this
HOW-TO.
+
+==!JavaScript debuggers==
+There are 2 UI debuggers that support V8 debug protocol. D8 is a console
application that comes with V8 distribution. Google Chrome Developer Tools
is a GUI debugger written in Java that is deployed as a plugin to Eclipse
IDE. It is hosted at [http://code.google.com/p/chromedevtools]
+
+==Adding debug support step by step==
+V8 incorporates full debug support, which is compiled in optionally.
+
+1. *Make sure you compile V8 with enabled debug support.* It should be
enabled by default, and you may control this with the option
“_debuggersupport_”, e.g.
+{{{
+scons debuggersupport=on
+}}}
+
+V8 communicates with the debugger by means of JSON-encoded messages.
Message transport is handled by an additional unit called Debug Agent. It
opens a TCP port for listening, establishes the handshake with the remote
debugger and sends/receives messages.
+
+2. *On application initialization start Debug Agent.* Call
_v8::Debug::!EnableAgent(name, port, wait_for_connection)_ function.
+
+The last step is to set up the debugger message dispatching. When new
messages arrive, V8 needs to be called in order to process them. We assume
that normally an application calls V8 execution periodically, in some
pattern, possibly from different threads (and even in parallel, using V8
lockers). Within a debug session, an additional call to V8 is needed
whenever new messages arrive (in fact, this is not always the case, since
V8 may be executing, but you cannot rely on this in general). It is
important that all additional calls to V8 be properly synchronized with
other regular calls to V8. Since Debug Agent does not know how a particular
application coordinates V8 execution, it cannot make additional calls
itself.
+
+3. *Install a callback in _v8::Debug::!SetDebugMessageDispatchHandler_
method*. Make your callback invoke _v8::Debug::!ProcessDebugMessages()_
method directly or indirectly, according to your synchronization model.
+
+Based on your current synchronization model, you may choose one of the two
approaches.
+
+*A. Your application already deals with multi-threaded synchronization.*
Everything is straightforward: call _!SetDebugMessageDispatchHandler_ with
the second argument “_provider_locker_” set to false. From your callback,
do not call _!ProcessDebugMessages_ method directly; you must schedule this
call for another thread instead.
+
+*B. Your application does not have a proper synchronization tool smith*.
It would take a lot to implement scheduling from one thread to another
thread. Then simply take advantage of V8 lockers. Just wrap all of your
calls to V8 with _v8::Locker_ (and possibly unwrap nested calls with
_v8::Unlocker_); it should not be too expensive. Install a callback in the
_!SetDebugMessageDispatchHandler_ method with the second argument
“_provider_locker_” set to true. From your callback, you may directly call
the _!ProcessDebugMessages_ method, though you have to set up a
_v8::Context_ first.
+
+
+==Sample application lineprocessor.cc==
+
+A small program _lineprocessor.cc_ comes with V8. It is a simple V8-based
console application that processes its input line by line with a
custom !JavaScript code. The debugger support was intentionally set off by
preprocessor conditional sections to make this HOW-TO more illustrative.
+
+You can compile it with:
+{{{
+scons sample=lineprocessor
+}}}
+(Add “_mode=debug_” if you want lineprocessor to work under a C++
debugger).
+
+Put a small program in a .js file, e.g. _capitalizer.js_:
+{{{
+function ProcessLine(line) {
+ return line.toUpperCase();
+}
+}}}
+
+Try to run it:
+{{{
+./lineprocessor capitalizer.js -p 9222 --main-cycle-in-cpp --callback
+}}}
+
+It should start reading lines from console and print them out capitalized.
If it works, try to connect to it from Eclipse (using debugger plugin; see
[http://code.google.com/p/chromedevtools]).
+
+When you have connected, the application probably will not be
executing !JavaScript, but rather will be waiting for input line in C++
code. However you may press “suspend” in Eclipse UI and inspect
some !JavaScript global variables (e.g. try the watch expression
“_this.!ProcessLine(‘Hello’)_” ). Try to enter some more strings into the
console. Do not forget to press “resume” in debugger to unfreeze V8 first.
If you press “suspend” again, you are unlikely to catch V8 while it is
executing !ProcessLine, because V8 is very fast; instead, you can set a
breakpoint inside the function to suspend it the next time it executes.
+
+As an experiment, try to run lineprocessor without the “--callback”
parameter. You’ll notice that when V8 is idle, breakpoints more or less
work, but you can no longer inspect global variables.
+
+The lineprocessor example also illustrates 2 main types of V8-based
applications. With the “--main-cycle-in-cpp” parameter, it keeps all the
control in the C++ part and calls V8 only briefly for the actual string
transformation. With the “--main-cycle-in-js” parameter (see inline
documentation), it gives you full control of the !JavaScript script, while
the C++ part becomes a passive API (e.g. the _read_line_ function).
+
+As a small final experiment, try to run lineprocessor in the
“--main-cycle-in-js” mode (see inline documentation). The application
starts the script execution immediately and runs down to “read_line” in
almost no time, never giving you a chance to debug the first statements.
You may check how the “--wait-for-connection” parameter works here.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
To unsubscribe, reply using "remove me" as the subject.