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.

Reply via email to