Merge from v8 at revision 3723
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index cd0da1b..583a9c2 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -413,9 +413,7 @@
// Iterate the head and check that there are no debugger related objects left.
HeapIterator iterator;
- while (iterator.has_next()) {
- HeapObject* obj = iterator.next();
- CHECK(obj != NULL);
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
CHECK(!obj->IsDebugInfo());
CHECK(!obj->IsBreakPointInfo());
@@ -2197,13 +2195,25 @@
// We match parts of the message to get evaluate result int value.
bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
- const char* value = "\"value\":";
- char* pos = strstr(message, value);
- if (pos == NULL) {
+ if (strstr(message, "\"command\":\"evaluate\"") == NULL) {
+ return false;
+ }
+ const char* prefix = "\"text\":\"";
+ char* pos1 = strstr(message, prefix);
+ if (pos1 == NULL) {
+ return false;
+ }
+ pos1 += strlen(prefix);
+ char* pos2 = strchr(pos1, '"');
+ if (pos2 == NULL) {
return false;
}
Vector<char> buf(buffer, buffer_size);
- OS::StrNCpy(buf, pos, buffer_size);
+ int len = static_cast<int>(pos2 - pos1);
+ if (len > buffer_size - 1) {
+ len = buffer_size - 1;
+ }
+ OS::StrNCpy(buf, pos1, len);
buffer[buffer_size - 1] = '\0';
return true;
}
@@ -2303,9 +2313,10 @@
CHECK_EQ(3, process_debug_messages_data.counter);
- CHECK(strcmp("Pinguin", process_debug_messages_data.results[0].buffer));
- CHECK(strcmp("Captbara", process_debug_messages_data.results[1].buffer));
- CHECK(strcmp("805", process_debug_messages_data.results[2].buffer));
+ CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0);
+ CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer),
+ 0);
+ CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
v8::Debug::SetMessageHandler(NULL);
v8::Debug::SetDebugEventListener(NULL);
@@ -3872,6 +3883,23 @@
}
+// We match parts of the message to get total frames number.
+int GetTotalFramesInt(char *message) {
+ const char* prefix = "\"totalFrames\":";
+ char* pos = strstr(message, prefix);
+ if (pos == NULL) {
+ return -1;
+ }
+ pos += strlen(prefix);
+ char* pos_end = pos;
+ int res = static_cast<int>(strtol(pos, &pos_end, 10));
+ if (pos_end == pos) {
+ return -1;
+ }
+ return res;
+}
+
+
/* Test MessageQueues */
/* Tests the message queues that hold debugger commands and
* response messages to the debugger. Fills queues and makes
@@ -4235,7 +4263,12 @@
class BreakpointsDebuggerThread : public v8::internal::Thread {
public:
+ explicit BreakpointsDebuggerThread(bool global_evaluate)
+ : global_evaluate_(global_evaluate) {}
void Run();
+
+ private:
+ bool global_evaluate_;
};
@@ -4303,24 +4336,51 @@
"\"type\":\"request\","
"\"command\":\"setbreakpoint\","
"\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
- const char* command_3 = "{\"seq\":103,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
- const char* command_4 = "{\"seq\":104,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
+ const char* command_3;
+ if (this->global_evaluate_) {
+ command_3 = "{\"seq\":103,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
+ "\"global\":true}}";
+ } else {
+ command_3 = "{\"seq\":103,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
+ }
+ const char* command_4;
+ if (this->global_evaluate_) {
+ command_4 = "{\"seq\":104,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
+ "\"global\":true}}";
+ } else {
+ command_4 = "{\"seq\":104,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
+ }
const char* command_5 = "{\"seq\":105,"
"\"type\":\"request\","
"\"command\":\"continue\"}";
const char* command_6 = "{\"seq\":106,"
"\"type\":\"request\","
"\"command\":\"continue\"}";
- const char* command_7 = "{\"seq\":107,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
+ const char* command_7;
+ if (this->global_evaluate_) {
+ command_7 = "{\"seq\":107,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
+ "\"global\":true}}";
+ } else {
+ command_7 = "{\"seq\":107,"
+ "\"type\":\"request\","
+ "\"command\":\"evaluate\","
+ "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
+ }
const char* command_8 = "{\"seq\":108,"
"\"type\":\"request\","
"\"command\":\"continue\"}";
@@ -4377,12 +4437,12 @@
v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer));
}
-BreakpointsDebuggerThread breakpoints_debugger_thread;
-BreakpointsV8Thread breakpoints_v8_thread;
-
-TEST(RecursiveBreakpoints) {
+void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
i::FLAG_debugger_auto_break = true;
+ BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
+ BreakpointsV8Thread breakpoints_v8_thread;
+
// Create a V8 environment
Barriers stack_allocated_breakpoints_barriers;
stack_allocated_breakpoints_barriers.Initialize();
@@ -4395,6 +4455,14 @@
breakpoints_debugger_thread.Join();
}
+TEST(RecursiveBreakpoints) {
+ TestRecursiveBreakpointsGeneric(false);
+}
+
+TEST(RecursiveBreakpointsGlobal) {
+ TestRecursiveBreakpointsGeneric(true);
+}
+
static void DummyDebugEventListener(v8::DebugEvent event,
v8::Handle<v8::Object> exec_state,
@@ -5827,6 +5895,58 @@
}
+struct BracktraceData {
+ static int frame_counter;
+ static void MessageHandler(const v8::Debug::Message& message) {
+ char print_buffer[1000];
+ v8::String::Value json(message.GetJSON());
+ Utf16ToAscii(*json, json.length(), print_buffer, 1000);
+
+ if (strstr(print_buffer, "backtrace") == NULL) {
+ return;
+ }
+ frame_counter = GetTotalFramesInt(print_buffer);
+ }
+};
+
+int BracktraceData::frame_counter;
+
+
+// Test that debug messages get processed when ProcessDebugMessages is called.
+TEST(Backtrace) {
+ v8::HandleScope scope;
+ DebugLocalContext env;
+
+ v8::Debug::SetMessageHandler2(BracktraceData::MessageHandler);
+
+ const int kBufferSize = 1000;
+ uint16_t buffer[kBufferSize];
+ const char* scripts_command =
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"backtrace\"}";
+
+ // Check backtrace from ProcessDebugMessages.
+ BracktraceData::frame_counter = -10;
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
+ v8::Debug::ProcessDebugMessages();
+ CHECK_EQ(BracktraceData::frame_counter, 0);
+
+ v8::Handle<v8::String> void0 = v8::String::New("void(0)");
+ v8::Handle<v8::Script> script = v8::Script::Compile(void0, void0);
+
+ // Check backtrace from "void(0)" script.
+ BracktraceData::frame_counter = -10;
+ v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer));
+ script->Run();
+ CHECK_EQ(BracktraceData::frame_counter, 1);
+
+ // Get rid of the debug message handler.
+ v8::Debug::SetMessageHandler2(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
TEST(GetMirror) {
v8::HandleScope scope;
DebugLocalContext env;