Revision: 4399
Author: peter.rybin
Date: Tue Apr 13 08:43:36 2010
Log: Edited wiki page through web user interface.
http://code.google.com/p/v8/source/detail?r=4399
Modified:
/wiki/AddDebuggerSupport.wiki
=======================================
--- /wiki/AddDebuggerSupport.wiki Fri Apr 9 06:29:38 2010
+++ /wiki/AddDebuggerSupport.wiki Tue Apr 13 08:43:36 2010
@@ -14,37 +14,37 @@
==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.
+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.
+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.
+*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.
+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_:
+(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();
@@ -58,10 +58,10 @@
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.
+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.