Implement issue 554 Add "ProcessDebuggerRequests" call to Debug Agent API
Review URL: http://codereview.chromium.org/549057 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3623 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
23fe22e7c8
commit
ec86bea132
@ -263,6 +263,43 @@ class EXPORT Debug {
|
||||
*/
|
||||
static bool EnableAgent(const char* name, int port,
|
||||
bool wait_for_connection = false);
|
||||
|
||||
/**
|
||||
* Makes V8 process all pending debug messages.
|
||||
*
|
||||
* From V8 point of view all debug messages come asynchronously (e.g. from
|
||||
* remote debugger) but they all must be handled synchronously: V8 cannot
|
||||
* do 2 things at one time so normal script execution must be interrupted
|
||||
* for a while.
|
||||
*
|
||||
* Generally when message arrives V8 may be in one of 3 states:
|
||||
* 1. V8 is running script; V8 will automatically interrupt and process all
|
||||
* pending messages (however auto_break flag should be enabled);
|
||||
* 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated
|
||||
* to reading and processing debug messages;
|
||||
* 3. V8 is not running at all or has called some long-working C++ function;
|
||||
* by default it means that processing of all debug message will be deferred
|
||||
* until V8 gets control again; however, embedding application may improve
|
||||
* this by manually calling this method.
|
||||
*
|
||||
* It makes sense to call this method whenever a new debug message arrived and
|
||||
* V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler
|
||||
* should help with the former condition.
|
||||
*
|
||||
* Technically this method in many senses is equivalent to executing empty
|
||||
* script:
|
||||
* 1. It does nothing except for processing all pending debug messages.
|
||||
* 2. It should be invoked with the same precautions and from the same context
|
||||
* as V8 script would be invoked from, because:
|
||||
* a. with "evaluate" command it can do whatever normal script can do,
|
||||
* including all native calls;
|
||||
* b. no other thread should call V8 while this method is running
|
||||
* (v8::Locker may be used here).
|
||||
*
|
||||
* "Evaluate" debug command behavior currently is not specified in scope
|
||||
* of this method.
|
||||
*/
|
||||
static void ProcessDebugMessages();
|
||||
};
|
||||
|
||||
|
||||
|
@ -3744,6 +3744,11 @@ Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
|
||||
bool Debug::EnableAgent(const char* name, int port, bool wait_for_connection) {
|
||||
return i::Debugger::StartAgent(name, port, wait_for_connection);
|
||||
}
|
||||
|
||||
void Debug::ProcessDebugMessages() {
|
||||
i::Execution::ProcessDebugMesssages(true);
|
||||
}
|
||||
|
||||
#endif // ENABLE_DEBUGGER_SUPPORT
|
||||
|
||||
namespace internal {
|
||||
|
@ -638,24 +638,32 @@ Object* Execution::DebugBreakHelper() {
|
||||
bool debug_command_only =
|
||||
StackGuard::IsDebugCommand() && !StackGuard::IsDebugBreak();
|
||||
|
||||
// Clear the debug request flags.
|
||||
// Clear the debug break request flag.
|
||||
StackGuard::Continue(DEBUGBREAK);
|
||||
|
||||
ProcessDebugMesssages(debug_command_only);
|
||||
|
||||
// Return to continue execution.
|
||||
return Heap::undefined_value();
|
||||
}
|
||||
|
||||
void Execution::ProcessDebugMesssages(bool debug_command_only) {
|
||||
// Clear the debug command request flag.
|
||||
StackGuard::Continue(DEBUGCOMMAND);
|
||||
|
||||
HandleScope scope;
|
||||
// Enter the debugger. Just continue if we fail to enter the debugger.
|
||||
EnterDebugger debugger;
|
||||
if (debugger.FailedToEnter()) {
|
||||
return Heap::undefined_value();
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify the debug event listeners. Indicate auto continue if the break was
|
||||
// a debug command break.
|
||||
Debugger::OnDebugBreak(Factory::undefined_value(), debug_command_only);
|
||||
|
||||
// Return to continue execution.
|
||||
return Heap::undefined_value();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Object* Execution::HandleStackGuardInterrupt() {
|
||||
|
@ -122,6 +122,7 @@ class Execution : public AllStatic {
|
||||
Handle<Object> is_global);
|
||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||
static Object* DebugBreakHelper();
|
||||
static void ProcessDebugMesssages(bool debug_command_only);
|
||||
#endif
|
||||
|
||||
// If the stack guard is triggered, but it is not an actual
|
||||
|
@ -5655,6 +5655,51 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
|
||||
}
|
||||
|
||||
|
||||
static int counting_message_handler_counter;
|
||||
|
||||
static void CountingMessageHandler(const v8::Debug::Message& message) {
|
||||
counting_message_handler_counter++;
|
||||
}
|
||||
|
||||
// Test that debug messages get processed when ProcessDebugMessages is called.
|
||||
TEST(ProcessDebugMessages) {
|
||||
v8::HandleScope scope;
|
||||
DebugLocalContext env;
|
||||
|
||||
counting_message_handler_counter = 0;
|
||||
|
||||
v8::Debug::SetMessageHandler2(CountingMessageHandler);
|
||||
|
||||
const int kBufferSize = 1000;
|
||||
uint16_t buffer[kBufferSize];
|
||||
const char* scripts_command =
|
||||
"{\"seq\":0,"
|
||||
"\"type\":\"request\","
|
||||
"\"command\":\"scripts\"}";
|
||||
|
||||
// Send scripts command.
|
||||
v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
|
||||
|
||||
CHECK_EQ(0, counting_message_handler_counter);
|
||||
v8::Debug::ProcessDebugMessages();
|
||||
// At least one message should come
|
||||
CHECK_GE(counting_message_handler_counter, 1);
|
||||
|
||||
counting_message_handler_counter = 0;
|
||||
|
||||
v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
|
||||
v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
|
||||
CHECK_EQ(0, counting_message_handler_counter);
|
||||
v8::Debug::ProcessDebugMessages();
|
||||
// At least two messages should come
|
||||
CHECK_GE(counting_message_handler_counter, 2);
|
||||
|
||||
// Get rid of the debug message handler.
|
||||
v8::Debug::SetMessageHandler2(NULL);
|
||||
CheckDebuggerUnloaded();
|
||||
}
|
||||
|
||||
|
||||
TEST(GetMirror) {
|
||||
v8::HandleScope scope;
|
||||
DebugLocalContext env;
|
||||
|
Loading…
Reference in New Issue
Block a user