28 #ifdef ENABLE_DEBUGGER_SUPPORT
44 using ::v8::internal::EmbeddedVector;
46 using ::v8::internal::OS;
47 using ::v8::internal::Handle;
48 using ::v8::internal::Heap;
49 using ::v8::internal::JSGlobalProxy;
50 using ::v8::internal::Code;
51 using ::v8::internal::Debug;
52 using ::v8::internal::Debugger;
53 using ::v8::internal::CommandMessage;
54 using ::v8::internal::CommandMessageQueue;
55 using ::v8::internal::StepAction;
56 using ::v8::internal::StepIn;
57 using ::v8::internal::StepNext;
58 using ::v8::internal::StepOut;
59 using ::v8::internal::Vector;
63 #define SMALL_STRING_BUFFER_SIZE 80
71 const char* expected_source,
73 const char* value_source,
75 if (expected != value) {
76 V8_Fatal(file, line,
"CHECK_EQ(%s, %s) failed\n# "
77 "Expected: %i\n# Found: %i",
78 expected_source, value_source, expected, value);
86 const char* unexpected_source,
88 const char* value_source,
90 if (unexpected == value) {
91 V8_Fatal(file, line,
"CHECK_NE(%s, %s) failed\n# Value: %i",
92 unexpected_source, value_source, value);
100 const char* expected_source,
101 const Code* expected,
102 const char* value_source,
104 if (expected != value) {
105 V8_Fatal(file, line,
"CHECK_EQ(%s, %s) failed\n# "
106 "Expected: %p\n# Found: %p",
107 expected_source, value_source, expected, value);
113 const char* expected_source,
114 const Code* expected,
115 const char* value_source,
117 if (expected == value) {
118 V8_Fatal(file, line,
"CHECK_NE(%s, %s) failed\n# Value: %p",
119 expected_source, value_source, value);
128 class DebugLocalContext {
130 inline DebugLocalContext(
135 : context_(v8::Context::New(extensions, global_template, global_object)) {
138 inline ~DebugLocalContext() {
142 inline v8::Context* operator->() {
return *context_; }
143 inline v8::Context* operator*() {
return *context_; }
144 inline bool IsReady() {
return !context_.IsEmpty(); }
146 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
149 debug->debug_context()->set_security_token(
150 v8::Utils::OpenHandle(*context_)->security_token());
152 Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
153 v8::Utils::OpenHandle(*context_->Global())));
154 Handle<v8::internal::String> debug_string =
155 FACTORY->LookupAsciiSymbol(
"debug");
157 Handle<Object>(debug->debug_context()->global_proxy()),
DONT_ENUM,
172 const char* function_name) {
181 const char* function_name) {
190 Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun);
191 Handle<v8::internal::SharedFunctionInfo> shared(f->shared());
192 return Debug::HasDebugInfo(shared);
198 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun,
int position) {
199 static int break_point = 0;
200 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
201 debug->SetBreakPoint(
212 return SetBreakPoint(v8::Utils::OpenHandle(*fun), position);
218 static int SetBreakPointFromJS(
const char* function_name,
219 int line,
int position) {
220 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
222 "debug.Debug.setBreakPoint(%s,%d,%d)",
223 function_name, line, position);
231 static int SetScriptBreakPointByIdFromJS(
int script_id,
int line,
int column) {
232 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
236 "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
237 script_id, line, column);
241 "debug.Debug.setScriptBreakPointById(%d,%d)",
250 return value->Int32Value();
257 static int SetScriptBreakPointByNameFromJS(
const char* script_name,
258 int line,
int column) {
259 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
263 "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
264 script_name, line, column);
268 "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
277 return value->Int32Value();
283 static void ClearBreakPoint(
int break_point) {
284 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
285 debug->ClearBreakPoint(
291 static void ClearBreakPointFromJS(
int break_point_number) {
292 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
294 "debug.Debug.clearBreakPoint(%d)",
301 static void EnableScriptBreakPointFromJS(
int break_point_number) {
302 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
304 "debug.Debug.enableScriptBreakPoint(%d)",
311 static void DisableScriptBreakPointFromJS(
int break_point_number) {
312 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
314 "debug.Debug.disableScriptBreakPoint(%d)",
321 static void ChangeScriptBreakPointConditionFromJS(
int break_point_number,
322 const char* condition) {
323 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
325 "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
326 break_point_number, condition);
332 static void ChangeScriptBreakPointIgnoreCountFromJS(
int break_point_number,
334 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
336 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
337 break_point_number, ignoreCount);
344 static void ChangeBreakOnException(
bool caught,
bool uncaught) {
345 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
346 debug->ChangeBreakOnException(v8::internal::BreakException, caught);
347 debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
352 static void ChangeBreakOnExceptionFromJS(
bool caught,
bool uncaught) {
365 v8::String::New(
"debug.Debug.clearBreakOnUncaughtException()"))->Run();
371 static void PrepareStep(StepAction step_action) {
372 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
373 debug->PrepareStep(step_action, 1);
383 Handle<FixedArray> GetDebuggedFunctions() {
384 Debug* debug = Isolate::Current()->debug();
386 v8::internal::DebugInfoListNode* node = debug->debug_info_list_;
396 Handle<FixedArray> debugged_functions =
402 debugged_functions->set(count++, *node->debug_info());
406 return debugged_functions;
410 static Handle<Code> ComputeCallDebugBreak(
int argc) {
411 return Isolate::Current()->stub_cache()->ComputeCallDebugBreak(argc,
417 void CheckDebuggerUnloaded(
bool check_functions) {
420 CHECK(Isolate::Current()->debug()->debug_context().is_null());
421 CHECK_EQ(
NULL, Isolate::Current()->debug()->debug_info_list_);
428 HeapIterator iterator;
429 for (HeapObject* obj = iterator.next(); obj !=
NULL; obj = iterator.next()) {
430 CHECK(!obj->IsDebugInfo());
431 CHECK(!obj->IsBreakPointInfo());
435 if (check_functions) {
436 if (obj->IsJSFunction()) {
438 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) {
439 RelocInfo::Mode rmode = it.rinfo()->rmode();
440 if (RelocInfo::IsCodeTarget(rmode)) {
441 CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address()));
442 }
else if (RelocInfo::IsJSReturn(rmode)) {
443 CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo()));
452 void ForceUnloadDebugger() {
453 Isolate::Current()->debugger()->never_unload_debugger_ =
false;
454 Isolate::Current()->debugger()->UnloadDebugger();
462 static void CheckDebuggerUnloaded(
bool check_functions =
false) {
466 v8::internal::CheckDebuggerUnloaded(check_functions);
472 class TestBreakLocationIterator:
public v8::internal::BreakLocationIterator {
474 explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info)
475 : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {}
478 return reloc_iterator_original_;
485 void CheckDebugBreakFunction(DebugLocalContext* env,
486 const char* source,
const char* name,
487 int position, v8::internal::RelocInfo::Mode mode,
489 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
492 Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle(
493 *CompileFunction(env, source, name));
494 int bp = SetBreakPoint(fun, position);
497 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
498 CHECK(Debug::HasDebugInfo(shared));
499 TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
500 it1.FindBreakLocationFromPosition(position);
501 v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode();
502 if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
503 actual_mode = v8::internal::RelocInfo::CODE_TARGET;
506 if (mode != v8::internal::RelocInfo::JS_RETURN) {
508 Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
510 CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo()));
516 CHECK(!debug->HasDebugInfo(shared));
517 CHECK(debug->EnsureDebugInfo(shared, fun));
518 TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
519 it2.FindBreakLocationFromPosition(position);
520 actual_mode = it2.it()->rinfo()->rmode();
521 if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
522 actual_mode = v8::internal::RelocInfo::CODE_TARGET;
525 if (mode == v8::internal::RelocInfo::JS_RETURN) {
526 CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
539 const char* frame_function_name_source =
540 "function frame_function_name(exec_state, frame_number) {"
541 " return exec_state.frame(frame_number).func().name();"
548 const char* frame_argument_name_source =
549 "function frame_argument_name(exec_state, frame_number) {"
550 " return exec_state.frame(frame_number).argumentName(0);"
557 const char* frame_argument_value_source =
558 "function frame_argument_value(exec_state, frame_number) {"
559 " return exec_state.frame(frame_number).argumentValue(0).value_;"
566 const char* frame_local_name_source =
567 "function frame_local_name(exec_state, frame_number) {"
568 " return exec_state.frame(frame_number).localName(0);"
575 const char* frame_local_value_source =
576 "function frame_local_value(exec_state, frame_number) {"
577 " return exec_state.frame(frame_number).localValue(0).value_;"
584 const char* frame_source_line_source =
585 "function frame_source_line(exec_state) {"
586 " return exec_state.frame(0).sourceLine();"
593 const char* frame_source_column_source =
594 "function frame_source_column(exec_state) {"
595 " return exec_state.frame(0).sourceColumn();"
602 const char* frame_script_name_source =
603 "function frame_script_name(exec_state) {"
604 " return exec_state.frame(0).func().script().name();"
611 const char* frame_script_data_source =
612 "function frame_script_data(exec_state) {"
613 " return exec_state.frame(0).func().script().data();"
620 const char* compiled_script_data_source =
621 "function compiled_script_data(event_data) {"
622 " return event_data.script().data();"
628 static const char* frame_count_source =
629 "function frame_count(exec_state) {"
630 " return exec_state.frameCount();"
636 char last_function_hit[80];
640 char last_script_name_hit[80];
641 char last_script_data_hit[80];
644 int last_source_line = -1;
645 int last_source_column = -1;
648 int break_point_hit_count = 0;
649 int break_point_hit_count_deoptimize = 0;
654 Debug* debug = v8::internal::Isolate::Current()->debug();
660 break_point_hit_count++;
661 if (!frame_function_name.
IsEmpty()) {
668 last_function_hit[0] =
'\0';
672 function_name->WriteAscii(last_function_hit);
676 if (!frame_source_line.
IsEmpty()) {
686 if (!frame_source_column.
IsEmpty()) {
696 if (!frame_script_name.
IsEmpty()) {
703 last_script_name_hit[0] =
'\0';
707 script_name->WriteAscii(last_script_name_hit);
711 if (!frame_script_data.
IsEmpty()) {
718 last_script_data_hit[0] =
'\0';
723 script_data->WriteAscii(last_script_data_hit);
729 if (break_point_hit_count == break_point_hit_count_deoptimize) {
738 last_script_data_hit[0] =
'\0';
743 script_data->WriteAscii(last_script_data_hit);
751 int exception_hit_count = 0;
752 int uncaught_exception_hit_count = 0;
753 int last_js_stack_height = -1;
755 static void DebugEventCounterClear() {
756 break_point_hit_count = 0;
757 exception_hit_count = 0;
758 uncaught_exception_hit_count = 0;
765 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
772 break_point_hit_count++;
774 exception_hit_count++;
781 if (result->IsTrue()) {
782 uncaught_exception_hit_count++;
789 static const int kArgc = 1;
806 struct EvaluateCheck {
811 struct EvaluateCheck* checks =
NULL;
814 const char* evaluate_check_source =
815 "function evaluate_check(exec_state, expr, expected) {"
816 " return exec_state.frame(0).evaluate(expr).value() === expected;"
825 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
830 for (
int i = 0; checks[i].expr !=
NULL; i++) {
834 checks[i].expected };
836 evaluate_check_function->
Call(exec_state, argc, argv);
839 V8_Fatal(__FILE__, __LINE__,
"%s != %s", checks[i].expr, *ascii);
847 int debug_event_remove_break_point = 0;
852 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
857 break_point_hit_count++;
859 ClearBreakPoint(debug_event_remove_break_point);
866 StepAction step_action = StepIn;
871 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
876 break_point_hit_count++;
877 PrepareStep(step_action);
891 const char* expected_step_sequence =
NULL;
898 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
904 CHECK(break_point_hit_count <
914 expected_step_sequence[break_point_hit_count]);
917 break_point_hit_count++;
918 PrepareStep(step_action);
924 static void DebugEventBreakPointCollectGarbage(
929 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
937 break_point_hit_count++;
938 if (break_point_hit_count % 2 == 0) {
943 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
955 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
961 break_point_hit_count++;
975 int max_break_point_hit_count = 0;
976 bool terminate_after_max_break_point_hit =
false;
981 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
986 if (break_point_hit_count < max_break_point_hit_count) {
988 break_point_hit_count++;
993 static const int kArgc = 1;
997 frame_count->
Call(exec_state, kArgc, argv);
1004 }
else if (terminate_after_max_break_point_hit) {
1011 if (break_point_hit_count == break_point_hit_count_deoptimize) {
1022 int message_callback_count = 0;
1024 static void MessageCallbackCountClear() {
1025 message_callback_count = 0;
1030 message_callback_count++;
1040 using ::v8::internal::Builtins;
1041 using ::v8::internal::Isolate;
1043 DebugLocalContext env;
1045 CheckDebugBreakFunction(&env,
1046 "function f1(){}",
"f1",
1048 v8::internal::RelocInfo::JS_RETURN,
1050 CheckDebugBreakFunction(&env,
1051 "function f2(){x=1;}",
"f2",
1053 v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
1054 Isolate::Current()->builtins()->builtin(
1055 Builtins::kStoreIC_DebugBreak));
1056 CheckDebugBreakFunction(&env,
1057 "function f3(){var a=x;}",
"f3",
1059 v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
1060 Isolate::Current()->builtins()->builtin(
1061 Builtins::kLoadIC_DebugBreak));
1067 #if !defined (__arm__) && !defined(__thumb__)
1068 CheckDebugBreakFunction(
1070 "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
1073 v8::internal::RelocInfo::CODE_TARGET,
1074 Isolate::Current()->builtins()->builtin(
1075 Builtins::kKeyedStoreIC_DebugBreak));
1076 CheckDebugBreakFunction(
1078 "function f5(){var index='propertyName'; var a={}; return a[index];}",
1081 v8::internal::RelocInfo::CODE_TARGET,
1082 Isolate::Current()->builtins()->builtin(
1083 Builtins::kKeyedLoadIC_DebugBreak));
1088 Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
1089 Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
1090 Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
1092 CheckDebugBreakFunction(&env,
1093 "function f4_0(){x();}",
"f4_0",
1095 v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
1098 CheckDebugBreakFunction(&env,
1099 "function f4_1(){x(1);}",
"f4_1",
1101 v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
1104 CheckDebugBreakFunction(&env,
1105 "function f4_4(){x(1,2,3,4);}",
"f4_4",
1107 v8::internal::RelocInfo::CODE_TARGET_CONTEXT,
1116 DebugLocalContext env;
1119 CompileFunction(&env,
"function foo(){}",
"foo");
1121 CompileFunction(&env,
"function bar(){}",
"bar");
1123 CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1124 CHECK(!HasDebugInfo(foo));
1125 CHECK(!HasDebugInfo(bar));
1127 int bp1 = SetBreakPoint(foo, 0);
1128 CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1129 CHECK(HasDebugInfo(foo));
1130 CHECK(!HasDebugInfo(bar));
1132 int bp2 = SetBreakPoint(bar, 0);
1133 CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length());
1134 CHECK(HasDebugInfo(foo));
1135 CHECK(HasDebugInfo(bar));
1137 ClearBreakPoint(bp1);
1138 CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1139 CHECK(!HasDebugInfo(foo));
1140 CHECK(HasDebugInfo(bar));
1142 ClearBreakPoint(bp2);
1143 CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1144 CHECK(!HasDebugInfo(foo));
1145 CHECK(!HasDebugInfo(bar));
1150 TEST(BreakPointICStore) {
1151 break_point_hit_count = 0;
1153 DebugLocalContext env;
1163 CHECK_EQ(0, break_point_hit_count);
1166 int bp = SetBreakPoint(foo, 0);
1168 CHECK_EQ(1, break_point_hit_count);
1170 CHECK_EQ(2, break_point_hit_count);
1173 ClearBreakPoint(bp);
1175 CHECK_EQ(2, break_point_hit_count);
1178 CheckDebuggerUnloaded();
1183 TEST(BreakPointICLoad) {
1184 break_point_hit_count = 0;
1186 DebugLocalContext env;
1196 CHECK_EQ(0, break_point_hit_count);
1199 int bp = SetBreakPoint(foo, 0);
1201 CHECK_EQ(1, break_point_hit_count);
1203 CHECK_EQ(2, break_point_hit_count);
1206 ClearBreakPoint(bp);
1208 CHECK_EQ(2, break_point_hit_count);
1211 CheckDebuggerUnloaded();
1216 TEST(BreakPointICCall) {
1217 break_point_hit_count = 0;
1219 DebugLocalContext env;
1229 CHECK_EQ(0, break_point_hit_count);
1232 int bp = SetBreakPoint(foo, 0);
1234 CHECK_EQ(1, break_point_hit_count);
1236 CHECK_EQ(2, break_point_hit_count);
1239 ClearBreakPoint(bp);
1241 CHECK_EQ(2, break_point_hit_count);
1244 CheckDebuggerUnloaded();
1249 TEST(BreakPointICCallWithGC) {
1250 break_point_hit_count = 0;
1252 DebugLocalContext env;
1262 CHECK_EQ(0, break_point_hit_count);
1265 int bp = SetBreakPoint(foo, 0);
1267 CHECK_EQ(1, break_point_hit_count);
1269 CHECK_EQ(2, break_point_hit_count);
1272 ClearBreakPoint(bp);
1274 CHECK_EQ(2, break_point_hit_count);
1277 CheckDebuggerUnloaded();
1282 TEST(BreakPointConstructCallWithGC) {
1283 break_point_hit_count = 0;
1285 DebugLocalContext env;
1290 "function foo(){return new bar(1).x;}"))->Run();
1296 CHECK_EQ(0, break_point_hit_count);
1299 int bp = SetBreakPoint(foo, 0);
1301 CHECK_EQ(1, break_point_hit_count);
1303 CHECK_EQ(2, break_point_hit_count);
1306 ClearBreakPoint(bp);
1308 CHECK_EQ(2, break_point_hit_count);
1311 CheckDebuggerUnloaded();
1316 TEST(BreakPointReturn) {
1317 break_point_hit_count = 0;
1319 DebugLocalContext env;
1323 frame_source_line = CompileFunction(&env,
1324 frame_source_line_source,
1325 "frame_source_line");
1326 frame_source_column = CompileFunction(&env,
1327 frame_source_column_source,
1328 "frame_source_column");
1339 CHECK_EQ(0, break_point_hit_count);
1342 int bp = SetBreakPoint(foo, 0);
1344 CHECK_EQ(1, break_point_hit_count);
1348 CHECK_EQ(2, break_point_hit_count);
1353 ClearBreakPoint(bp);
1355 CHECK_EQ(2, break_point_hit_count);
1358 CheckDebuggerUnloaded();
1364 int break_point_count,
1366 break_point_hit_count = 0;
1369 CHECK_EQ((i + 1) * break_point_count, break_point_hit_count);
1374 TEST(GCDuringBreakPointProcessing) {
1375 break_point_hit_count = 0;
1377 DebugLocalContext env;
1384 foo = CompileFunction(&env,
"function foo(){bar=0;}",
"foo");
1385 SetBreakPoint(foo, 0);
1386 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1389 foo = CompileFunction(&env,
"bar=1;function foo(){var x=bar;}",
"foo");
1390 SetBreakPoint(foo, 0);
1391 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1394 foo = CompileFunction(&env,
"function bar(){};function foo(){bar();}",
"foo");
1395 SetBreakPoint(foo, 0);
1396 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1399 foo = CompileFunction(&env,
"function foo(){}",
"foo");
1400 SetBreakPoint(foo, 0);
1401 CallWithBreakPoints(env->Global(),
foo, 1, 25);
1404 foo = CompileFunction(&env,
"function foo(){var a;}",
"foo");
1405 SetBreakPoint(foo, 0);
1406 CallWithBreakPoints(env->Global(),
foo, 1, 25);
1409 CheckDebuggerUnloaded();
1417 break_point_hit_count = 0;
1419 for (
int i = 0; i < 3; i++) {
1422 CHECK_EQ(1 + i * 3, break_point_hit_count);
1427 CHECK_EQ(2 + i * 3, break_point_hit_count);
1430 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
1432 CHECK_EQ(3 + i * 3, break_point_hit_count);
1438 TEST(BreakPointSurviveGC) {
1439 break_point_hit_count = 0;
1441 DebugLocalContext env;
1449 CompileFunction(&env,
"function foo(){}",
"foo");
1450 foo = CompileFunction(&env,
"function foo(){bar=0;}",
"foo");
1451 SetBreakPoint(foo, 0);
1453 CallAndGC(env->Global(),
foo);
1457 CompileFunction(&env,
"function foo(){}",
"foo");
1458 foo = CompileFunction(&env,
"bar=1;function foo(){var x=bar;}",
"foo");
1459 SetBreakPoint(foo, 0);
1461 CallAndGC(env->Global(),
foo);
1465 CompileFunction(&env,
"function foo(){}",
"foo");
1466 foo = CompileFunction(&env,
1467 "function bar(){};function foo(){bar();}",
1469 SetBreakPoint(foo, 0);
1471 CallAndGC(env->Global(),
foo);
1475 CompileFunction(&env,
"function foo(){}",
"foo");
1476 foo = CompileFunction(&env,
"function foo(){}",
"foo");
1477 SetBreakPoint(foo, 0);
1479 CallAndGC(env->Global(),
foo);
1483 CompileFunction(&env,
"function foo(){}",
"foo");
1484 foo = CompileFunction(&env,
"function foo(){var bar=0;}",
"foo");
1485 SetBreakPoint(foo, 0);
1487 CallAndGC(env->Global(),
foo);
1491 CheckDebuggerUnloaded();
1496 TEST(BreakPointThroughJavaScript) {
1497 break_point_hit_count = 0;
1499 DebugLocalContext env;
1513 CHECK_EQ(0, break_point_hit_count);
1516 int bp1 = SetBreakPointFromJS(
"foo", 0, 3);
1518 CHECK_EQ(1, break_point_hit_count);
1520 CHECK_EQ(2, break_point_hit_count);
1523 int bp2 = SetBreakPointFromJS(
"foo", 0, 9);
1525 CHECK_EQ(4, break_point_hit_count);
1527 CHECK_EQ(6, break_point_hit_count);
1530 ClearBreakPointFromJS(bp2);
1532 CHECK_EQ(7, break_point_hit_count);
1534 CHECK_EQ(8, break_point_hit_count);
1537 ClearBreakPointFromJS(bp1);
1539 CHECK_EQ(8, break_point_hit_count);
1542 CheckDebuggerUnloaded();
1552 TEST(ScriptBreakPointByNameThroughJavaScript) {
1553 break_point_hit_count = 0;
1555 DebugLocalContext env;
1564 " a = 0; // line 2\n"
1566 " b = 1; // line 4\n"
1574 " b = 2; // line 12\n"
1576 " b = 3; // line 14\n"
1577 " f(); // line 15\n"
1590 break_point_hit_count = 0;
1592 CHECK_EQ(0, break_point_hit_count);
1594 CHECK_EQ(0, break_point_hit_count);
1597 int sbp1 = SetScriptBreakPointByNameFromJS(
"test", 12, 0);
1598 break_point_hit_count = 0;
1600 CHECK_EQ(0, break_point_hit_count);
1602 CHECK_EQ(1, break_point_hit_count);
1605 break_point_hit_count = 0;
1606 ClearBreakPointFromJS(sbp1);
1608 CHECK_EQ(0, break_point_hit_count);
1610 CHECK_EQ(0, break_point_hit_count);
1613 int sbp2 = SetScriptBreakPointByNameFromJS(
"test", 2, 0);
1614 break_point_hit_count = 0;
1616 CHECK_EQ(1, break_point_hit_count);
1618 CHECK_EQ(2, break_point_hit_count);
1621 int sbp3 = SetScriptBreakPointByNameFromJS(
"test", 4, 0);
1622 int sbp4 = SetScriptBreakPointByNameFromJS(
"test", 12, 0);
1623 int sbp5 = SetScriptBreakPointByNameFromJS(
"test", 14, 0);
1624 int sbp6 = SetScriptBreakPointByNameFromJS(
"test", 15, 0);
1625 break_point_hit_count = 0;
1627 CHECK_EQ(2, break_point_hit_count);
1629 CHECK_EQ(7, break_point_hit_count);
1632 break_point_hit_count = 0;
1633 ClearBreakPointFromJS(sbp2);
1634 ClearBreakPointFromJS(sbp3);
1635 ClearBreakPointFromJS(sbp4);
1636 ClearBreakPointFromJS(sbp5);
1637 ClearBreakPointFromJS(sbp6);
1639 CHECK_EQ(0, break_point_hit_count);
1641 CHECK_EQ(0, break_point_hit_count);
1644 CheckDebuggerUnloaded();
1656 TEST(ScriptBreakPointByIdThroughJavaScript) {
1657 break_point_hit_count = 0;
1659 DebugLocalContext env;
1668 " a = 0; // line 2\n"
1670 " b = 1; // line 4\n"
1678 " b = 2; // line 12\n"
1680 " b = 3; // line 14\n"
1681 " f(); // line 15\n"
1695 uint32_t script_id = script->
Id()->Uint32Value();
1698 break_point_hit_count = 0;
1700 CHECK_EQ(0, break_point_hit_count);
1702 CHECK_EQ(0, break_point_hit_count);
1705 int sbp1 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
1706 break_point_hit_count = 0;
1708 CHECK_EQ(0, break_point_hit_count);
1710 CHECK_EQ(1, break_point_hit_count);
1713 break_point_hit_count = 0;
1714 ClearBreakPointFromJS(sbp1);
1716 CHECK_EQ(0, break_point_hit_count);
1718 CHECK_EQ(0, break_point_hit_count);
1721 int sbp2 = SetScriptBreakPointByIdFromJS(script_id, 2, 0);
1722 break_point_hit_count = 0;
1724 CHECK_EQ(1, break_point_hit_count);
1726 CHECK_EQ(2, break_point_hit_count);
1729 int sbp3 = SetScriptBreakPointByIdFromJS(script_id, 4, 0);
1730 int sbp4 = SetScriptBreakPointByIdFromJS(script_id, 12, 0);
1731 int sbp5 = SetScriptBreakPointByIdFromJS(script_id, 14, 0);
1732 int sbp6 = SetScriptBreakPointByIdFromJS(script_id, 15, 0);
1733 break_point_hit_count = 0;
1735 CHECK_EQ(2, break_point_hit_count);
1737 CHECK_EQ(7, break_point_hit_count);
1740 break_point_hit_count = 0;
1741 ClearBreakPointFromJS(sbp2);
1742 ClearBreakPointFromJS(sbp3);
1743 ClearBreakPointFromJS(sbp4);
1744 ClearBreakPointFromJS(sbp5);
1745 ClearBreakPointFromJS(sbp6);
1747 CHECK_EQ(0, break_point_hit_count);
1749 CHECK_EQ(0, break_point_hit_count);
1752 CheckDebuggerUnloaded();
1765 TEST(EnableDisableScriptBreakPoint) {
1766 break_point_hit_count = 0;
1768 DebugLocalContext env;
1776 " a = 0; // line 1\n"
1787 int sbp = SetScriptBreakPointByNameFromJS(
"test", 1, 0);
1790 break_point_hit_count = 0;
1792 CHECK_EQ(1, break_point_hit_count);
1794 DisableScriptBreakPointFromJS(sbp);
1796 CHECK_EQ(1, break_point_hit_count);
1798 EnableScriptBreakPointFromJS(sbp);
1800 CHECK_EQ(2, break_point_hit_count);
1802 DisableScriptBreakPointFromJS(sbp);
1804 CHECK_EQ(2, break_point_hit_count);
1810 CHECK_EQ(2, break_point_hit_count);
1812 EnableScriptBreakPointFromJS(sbp);
1814 CHECK_EQ(3, break_point_hit_count);
1817 CheckDebuggerUnloaded();
1822 TEST(ConditionalScriptBreakPoint) {
1823 break_point_hit_count = 0;
1825 DebugLocalContext env;
1834 " g(count++); // line 2\n"
1837 " var a=x; // line 5\n"
1848 int sbp1 = SetScriptBreakPointByNameFromJS(
"test", 5, 0);
1851 break_point_hit_count = 0;
1852 ChangeScriptBreakPointConditionFromJS(sbp1,
"false");
1854 CHECK_EQ(0, break_point_hit_count);
1856 ChangeScriptBreakPointConditionFromJS(sbp1,
"true");
1857 break_point_hit_count = 0;
1859 CHECK_EQ(1, break_point_hit_count);
1861 ChangeScriptBreakPointConditionFromJS(sbp1,
"x % 2 == 0");
1862 break_point_hit_count = 0;
1863 for (
int i = 0; i < 10; i++) {
1866 CHECK_EQ(5, break_point_hit_count);
1872 break_point_hit_count = 0;
1873 for (
int i = 0; i < 10; i++) {
1876 CHECK_EQ(5, break_point_hit_count);
1879 CheckDebuggerUnloaded();
1884 TEST(ScriptBreakPointIgnoreCount) {
1885 break_point_hit_count = 0;
1887 DebugLocalContext env;
1895 " a = 0; // line 1\n"
1906 int sbp = SetScriptBreakPointByNameFromJS(
"test", 1, 0);
1909 break_point_hit_count = 0;
1910 ChangeScriptBreakPointIgnoreCountFromJS(sbp, 1);
1912 CHECK_EQ(0, break_point_hit_count);
1914 CHECK_EQ(1, break_point_hit_count);
1916 ChangeScriptBreakPointIgnoreCountFromJS(sbp, 5);
1917 break_point_hit_count = 0;
1918 for (
int i = 0; i < 10; i++) {
1921 CHECK_EQ(5, break_point_hit_count);
1927 break_point_hit_count = 0;
1928 for (
int i = 0; i < 10; i++) {
1931 CHECK_EQ(5, break_point_hit_count);
1934 CheckDebuggerUnloaded();
1939 TEST(ScriptBreakPointReload) {
1940 break_point_hit_count = 0;
1942 DebugLocalContext env;
1952 " a = 0; // line 2\n"
1954 " b = 1; // line 4\n"
1962 SetScriptBreakPointByNameFromJS(
"1", 2, 0);
1969 break_point_hit_count = 0;
1971 CHECK_EQ(1, break_point_hit_count);
1979 break_point_hit_count = 0;
1981 CHECK_EQ(0, break_point_hit_count);
1988 break_point_hit_count = 0;
1990 CHECK_EQ(1, break_point_hit_count);
1993 CheckDebuggerUnloaded();
1998 TEST(ScriptBreakPointMultiple) {
1999 break_point_hit_count = 0;
2001 DebugLocalContext env;
2010 " a = 0; // line 1\n"
2016 " b = 0; // line 1\n"
2023 int sbp = SetScriptBreakPointByNameFromJS(
"test", 1, 0);
2032 break_point_hit_count = 0;
2034 CHECK_EQ(1, break_point_hit_count);
2036 CHECK_EQ(2, break_point_hit_count);
2039 ClearBreakPointFromJS(sbp);
2042 break_point_hit_count = 0;
2044 CHECK_EQ(0, break_point_hit_count);
2046 CHECK_EQ(0, break_point_hit_count);
2049 sbp = SetScriptBreakPointByNameFromJS(
"test", 1, 0);
2052 break_point_hit_count = 0;
2054 CHECK_EQ(1, break_point_hit_count);
2056 CHECK_EQ(2, break_point_hit_count);
2059 CheckDebuggerUnloaded();
2064 TEST(ScriptBreakPointLineOffset) {
2065 break_point_hit_count = 0;
2067 DebugLocalContext env;
2076 " a = 0; // line 8 as this script has line offset 7\n"
2077 " b = 0; // line 9 as this script has line offset 7\n"
2085 int sbp1 = SetScriptBreakPointByNameFromJS(
"test.html", 8, 0);
2086 int sbp2 = SetScriptBreakPointByNameFromJS(
"test.html", 9, 0);
2093 break_point_hit_count = 0;
2095 CHECK_EQ(2, break_point_hit_count);
2098 ClearBreakPointFromJS(sbp1);
2099 ClearBreakPointFromJS(sbp2);
2102 break_point_hit_count = 0;
2104 CHECK_EQ(0, break_point_hit_count);
2107 sbp1 = SetScriptBreakPointByNameFromJS(
"test.html", 9, 0);
2110 break_point_hit_count = 0;
2112 CHECK_EQ(1, break_point_hit_count);
2115 CheckDebuggerUnloaded();
2120 TEST(ScriptBreakPointLine) {
2122 DebugLocalContext env;
2126 frame_function_name = CompileFunction(&env,
2127 frame_function_name_source,
2128 "frame_function_name");
2138 " a = 1; // line 2\n"
2140 " a = 2; // line 4\n"
2141 " /* xx */ function g() { // line 5\n"
2142 " function h() { // line 6\n"
2143 " a = 3; // line 7\n"
2146 " a = 4; // line 10\n"
2148 " a=5; // line 12");
2151 int sbp1 = SetScriptBreakPointByNameFromJS(
"test.html", 0, -1);
2152 int sbp2 = SetScriptBreakPointByNameFromJS(
"test.html", 1, -1);
2153 int sbp3 = SetScriptBreakPointByNameFromJS(
"test.html", 5, -1);
2156 break_point_hit_count = 0;
2163 CHECK_EQ(1, break_point_hit_count);
2168 CHECK_EQ(2, break_point_hit_count);
2173 CHECK_EQ(3, break_point_hit_count);
2177 ClearBreakPointFromJS(sbp3);
2178 int sbp4 = SetScriptBreakPointByNameFromJS(
"test.html", 6, -1);
2182 CHECK_EQ(4, break_point_hit_count);
2188 ClearBreakPointFromJS(sbp2);
2189 ClearBreakPointFromJS(sbp4);
2190 int sbp5 = SetScriptBreakPointByNameFromJS(
"test.html", 4, -1);
2191 break_point_hit_count = 0;
2194 CHECK_EQ(0, break_point_hit_count);
2197 break_point_hit_count = 0;
2199 CHECK_EQ(2, break_point_hit_count);
2203 int sbp6 = SetScriptBreakPointByNameFromJS(
"test.html", 12, -1);
2206 break_point_hit_count = 0;
2208 CHECK_EQ(3, break_point_hit_count);
2213 ClearBreakPointFromJS(sbp1);
2214 ClearBreakPointFromJS(sbp5);
2215 ClearBreakPointFromJS(sbp6);
2216 break_point_hit_count = 0;
2218 CHECK_EQ(0, break_point_hit_count);
2221 CheckDebuggerUnloaded();
2226 TEST(ScriptBreakPointLineTopLevel) {
2228 DebugLocalContext env;
2236 " a = 1; // line 1\n"
2238 "a = 2; // line 3\n");
2246 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
2248 SetScriptBreakPointByNameFromJS(
"test.html", 3, -1);
2251 break_point_hit_count = 0;
2253 CHECK_EQ(0, break_point_hit_count);
2256 break_point_hit_count = 0;
2258 CHECK_EQ(1, break_point_hit_count);
2261 break_point_hit_count = 0;
2263 CHECK_EQ(0, break_point_hit_count);
2266 CheckDebuggerUnloaded();
2272 TEST(ScriptBreakPointTopLevelCrash) {
2274 DebugLocalContext env;
2286 int sbp1 = SetScriptBreakPointByNameFromJS(
"test.html", 3, -1);
2289 break_point_hit_count = 0;
2291 CHECK_EQ(1, break_point_hit_count);
2294 int sbp2 = SetScriptBreakPointByNameFromJS(
"test.html", 3, -1);
2295 ClearBreakPointFromJS(sbp1);
2296 ClearBreakPointFromJS(sbp2);
2299 CheckDebuggerUnloaded();
2305 TEST(RemoveBreakPointInBreak) {
2307 DebugLocalContext env;
2310 CompileFunction(&env,
"function foo(){a=1;}",
"foo");
2311 debug_event_remove_break_point = SetBreakPoint(foo, 0);
2316 break_point_hit_count = 0;
2318 CHECK_EQ(1, break_point_hit_count);
2320 break_point_hit_count = 0;
2322 CHECK_EQ(0, break_point_hit_count);
2325 CheckDebuggerUnloaded();
2330 TEST(DebuggerStatement) {
2331 break_point_hit_count = 0;
2333 DebugLocalContext env;
2338 "function foo(){debugger;debugger;}"))->Run();
2346 CHECK_EQ(1, break_point_hit_count);
2350 CHECK_EQ(3, break_point_hit_count);
2353 CheckDebuggerUnloaded();
2358 TEST(DebuggerStatementBreakpoint) {
2359 break_point_hit_count = 0;
2361 DebugLocalContext env;
2370 CHECK_EQ(1, break_point_hit_count);
2372 int bp = SetBreakPoint(foo, 0);
2376 CHECK_EQ(2, break_point_hit_count);
2378 ClearBreakPoint(bp);
2380 CheckDebuggerUnloaded();
2386 TEST(DebugEvaluate) {
2388 DebugLocalContext env;
2392 evaluate_check_function = CompileFunction(&env,
2393 evaluate_check_source,
2400 struct EvaluateCheck checks_uu[] = {
2405 struct EvaluateCheck checks_hu[] = {
2410 struct EvaluateCheck checks_hh[] = {
2428 const int foo_break_position_1 = 15;
2429 const int foo_break_position_2 = 29;
2435 int bp = SetBreakPoint(foo, foo_break_position_1);
2437 foo->Call(env->Global(), 0,
NULL);
2441 foo->Call(env->Global(), 1, argv_foo);
2444 ClearBreakPoint(bp);
2445 SetBreakPoint(foo, foo_break_position_2);
2447 foo->Call(env->Global(), 1, argv_foo);
2455 "x = 'Goodbye, world!';"
2456 "function bar(x, b) {"
2458 " function barbar() {"
2459 " y=0; /* To ensure break location.*/"
2462 " debug.Debug.clearAllBreakPoints();"
2467 const int barbar_break_position = 8;
2476 bar->
Call(env->Global(), 2, argv_bar_1);
2485 bar->
Call(env->Global(), 2, argv_bar_2);
2494 bar->
Call(env->Global(), 2, argv_bar_3);
2497 CheckDebuggerUnloaded();
2501 int debugEventCount = 0;
2508 TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
2510 DebugLocalContext env;
2516 "function foo(x) {\n"
2517 " var s = 'String value2';\n"
2523 CompileRun(
"debug.Debug.setBreakPoint(foo, 2, 0, 'true')");
2525 debugEventCount = 0;
2526 env->AllowCodeGenerationFromStrings(
false);
2531 CheckDebuggerUnloaded();
2535 bool checkedDebugEvals =
true;
2554 TEST(DebugEvaluateWithCodeGenerationDisallowed) {
2556 DebugLocalContext env;
2562 "var global = 'Global';\n"
2563 "function foo(x) {\n"
2564 " var local = 'Local';\n"
2566 " return local + x;\n"
2569 checkGlobalEvalFunction = CompileFunction(&env,
2570 "function checkGlobalEval(exec_state) {\n"
2571 " return exec_state.evaluateGlobal('global').value() === 'Global';\n"
2575 checkFrameEvalFunction = CompileFunction(&env,
2576 "function checkFrameEval(exec_state) {\n"
2577 " return exec_state.frame(0).evaluate('local').value() === 'Local';\n"
2580 debugEventCount = 0;
2581 env->AllowCodeGenerationFromStrings(
false);
2585 checkGlobalEvalFunction.
Clear();
2586 checkFrameEvalFunction.
Clear();
2588 CheckDebuggerUnloaded();
2595 int AsciiToUtf16(
const char* input_buffer,
uint16_t* output_buffer) {
2597 for (i = 0; input_buffer[i] !=
'\0'; ++i) {
2599 output_buffer[i] =
static_cast<unsigned char>(input_buffer[i]);
2601 output_buffer[i] = 0;
2608 int Utf16ToAscii(
const uint16_t* input_buffer,
int length,
2609 char* output_buffer,
int output_len = -1) {
2610 if (output_len >= 0) {
2611 if (length > output_len - 1) {
2612 length = output_len - 1;
2616 for (
int i = 0; i < length; ++i) {
2617 output_buffer[i] =
static_cast<char>(input_buffer[i]);
2619 output_buffer[length] =
'\0';
2625 bool GetEvaluateStringResult(
char *
message,
char* buffer,
int buffer_size) {
2626 if (strstr(message,
"\"command\":\"evaluate\"") ==
NULL) {
2629 const char* prefix =
"\"text\":\"";
2630 char* pos1 = strstr(message, prefix);
2634 pos1 += strlen(prefix);
2635 char* pos2 = strchr(pos1,
'"');
2639 Vector<char> buf(buffer, buffer_size);
2640 int len =
static_cast<int>(pos2 - pos1);
2641 if (len > buffer_size - 1) {
2642 len = buffer_size - 1;
2644 OS::StrNCpy(buf, pos1, len);
2645 buffer[buffer_size - 1] =
'\0';
2650 struct EvaluateResult {
2651 static const int kBufferSize = 20;
2652 char buffer[kBufferSize];
2655 struct DebugProcessDebugMessagesData {
2656 static const int kArraySize = 5;
2658 EvaluateResult results[kArraySize];
2663 EvaluateResult* current() {
2664 return &results[counter % kArraySize];
2671 DebugProcessDebugMessagesData process_debug_messages_data;
2673 static void DebugProcessDebugMessagesHandler(
2678 const int kBufferSize = 100000;
2679 char print_buffer[kBufferSize];
2680 Utf16ToAscii(message, length, print_buffer, kBufferSize);
2682 EvaluateResult* array_item = process_debug_messages_data.current();
2684 bool res = GetEvaluateStringResult(print_buffer,
2686 EvaluateResult::kBufferSize);
2688 process_debug_messages_data.next();
2694 TEST(DebugEvaluateWithoutStack) {
2698 DebugLocalContext env;
2700 const char* source =
2701 "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
2707 const int kBufferSize = 1000;
2710 const char* command_111 =
"{\"seq\":111,"
2711 "\"type\":\"request\","
2712 "\"command\":\"evaluate\","
2715 " \"expression\":\"v1\",\"disable_break\":true"
2720 const char* command_112 =
"{\"seq\":112,"
2721 "\"type\":\"request\","
2722 "\"command\":\"evaluate\","
2725 " \"expression\":\"getAnimal()\",\"disable_break\":true"
2730 const char* command_113 =
"{\"seq\":113,"
2731 "\"type\":\"request\","
2732 "\"command\":\"evaluate\","
2735 " \"expression\":\"239 + 566\",\"disable_break\":true"
2742 CHECK_EQ(3, process_debug_messages_data.counter);
2744 CHECK_EQ(strcmp(
"Pinguin", process_debug_messages_data.results[0].buffer), 0);
2745 CHECK_EQ(strcmp(
"Capybara", process_debug_messages_data.results[1].buffer),
2747 CHECK_EQ(strcmp(
"805", process_debug_messages_data.results[2].buffer), 0);
2751 CheckDebuggerUnloaded();
2756 TEST(DebugStepLinear) {
2758 DebugLocalContext env;
2762 "function foo(){a=1;b=1;c=1;}",
2766 CompileRun(
"a=0; b=0; c=0; foo();");
2768 SetBreakPoint(foo, 3);
2773 step_action = StepIn;
2774 break_point_hit_count = 0;
2778 CHECK_EQ(4, break_point_hit_count);
2781 CheckDebuggerUnloaded();
2786 SetBreakPoint(foo, 3);
2787 break_point_hit_count = 0;
2791 CHECK_EQ(1, break_point_hit_count);
2794 CheckDebuggerUnloaded();
2799 TEST(DebugStepKeyedLoadLoop) {
2801 DebugLocalContext env;
2810 "function foo(a) {\n"
2812 " var len = a.length;\n"
2813 " for (var i = 0; i < len; i++) {\n"
2823 for (
int i = 0; i < 10; i++) {
2828 const int kArgc = 1;
2830 foo->
Call(env->Global(), kArgc, args);
2833 SetBreakPoint(foo, 3);
2834 step_action = StepNext;
2835 break_point_hit_count = 0;
2836 foo->
Call(env->Global(), kArgc, args);
2839 CHECK_EQ(34, break_point_hit_count);
2842 CheckDebuggerUnloaded();
2847 TEST(DebugStepKeyedStoreLoop) {
2849 DebugLocalContext env;
2858 "function foo(a) {\n"
2859 " var len = a.length;\n"
2860 " for (var i = 0; i < len; i++) {\n"
2870 for (
int i = 0; i < 10; i++) {
2875 const int kArgc = 1;
2877 foo->
Call(env->Global(), kArgc, args);
2880 SetBreakPoint(foo, 3);
2881 step_action = StepNext;
2882 break_point_hit_count = 0;
2883 foo->
Call(env->Global(), kArgc, args);
2886 CHECK_EQ(33, break_point_hit_count);
2889 CheckDebuggerUnloaded();
2894 TEST(DebugStepNamedLoadLoop) {
2896 DebugLocalContext env;
2904 "function foo() {\n"
2907 " for (var i = 0; i < 10; i++) {\n"
2908 " var v = new V(i, i + 1);\n"
2914 "function V(x, y) {\n"
2924 SetBreakPoint(foo, 4);
2925 step_action = StepNext;
2926 break_point_hit_count = 0;
2930 CHECK_EQ(54, break_point_hit_count);
2933 CheckDebuggerUnloaded();
2937 static void DoDebugStepNamedStoreLoop(
int expected) {
2939 DebugLocalContext env;
2947 "function foo() {\n"
2949 " for (var i = 0; i < 10; i++) {\n"
2959 SetBreakPoint(foo, 3);
2960 step_action = StepNext;
2961 break_point_hit_count = 0;
2965 CHECK_EQ(expected, break_point_hit_count);
2968 CheckDebuggerUnloaded();
2973 TEST(DebugStepNamedStoreLoop) {
2974 DoDebugStepNamedStoreLoop(23);
2979 TEST(DebugStepLinearMixedICs) {
2981 DebugLocalContext env;
2988 "function bar() {};"
2991 " var index='name';"
2993 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}",
"foo");
2996 CompileRun(
"a=0; b=0; bar(); foo();");
2998 SetBreakPoint(foo, 0);
3000 step_action = StepIn;
3001 break_point_hit_count = 0;
3005 CHECK_EQ(11, break_point_hit_count);
3008 CheckDebuggerUnloaded();
3013 SetBreakPoint(foo, 0);
3014 break_point_hit_count = 0;
3018 CHECK_EQ(1, break_point_hit_count);
3021 CheckDebuggerUnloaded();
3025 TEST(DebugStepDeclarations) {
3027 DebugLocalContext env;
3034 const char* src =
"function foo() { "
3038 " var d = Math.floor;"
3039 " var e = b + d(1.2);"
3044 SetBreakPoint(foo, 0);
3047 step_action = StepIn;
3048 break_point_hit_count = 0;
3050 CHECK_EQ(6, break_point_hit_count);
3054 CheckDebuggerUnloaded();
3058 TEST(DebugStepLocals) {
3060 DebugLocalContext env;
3067 const char* src =
"function foo() { "
3072 " a = Math.floor(b);"
3077 SetBreakPoint(foo, 0);
3080 step_action = StepIn;
3081 break_point_hit_count = 0;
3083 CHECK_EQ(6, break_point_hit_count);
3087 CheckDebuggerUnloaded();
3093 DebugLocalContext env;
3101 const char* src =
"function foo(x) { "
3110 "a=0; b=0; c=0; d=0; foo()";
3112 SetBreakPoint(foo, 0);
3115 step_action = StepIn;
3116 break_point_hit_count = 0;
3118 foo->
Call(env->Global(), argc, argv_true);
3119 CHECK_EQ(4, break_point_hit_count);
3122 step_action = StepIn;
3123 break_point_hit_count = 0;
3125 foo->
Call(env->Global(), argc, argv_false);
3126 CHECK_EQ(5, break_point_hit_count);
3130 CheckDebuggerUnloaded();
3134 TEST(DebugStepSwitch) {
3136 DebugLocalContext env;
3144 const char* src =
"function foo(x) { "
3159 "a=0; b=0; c=0; d=0; e=0; f=0; foo()";
3161 SetBreakPoint(foo, 0);
3164 step_action = StepIn;
3165 break_point_hit_count = 0;
3167 foo->
Call(env->Global(), argc, argv_1);
3168 CHECK_EQ(6, break_point_hit_count);
3171 step_action = StepIn;
3172 break_point_hit_count = 0;
3174 foo->
Call(env->Global(), argc, argv_2);
3175 CHECK_EQ(5, break_point_hit_count);
3178 step_action = StepIn;
3179 break_point_hit_count = 0;
3181 foo->
Call(env->Global(), argc, argv_3);
3182 CHECK_EQ(7, break_point_hit_count);
3186 CheckDebuggerUnloaded();
3190 TEST(DebugStepWhile) {
3192 DebugLocalContext env;
3200 const char* src =
"function foo(x) { "
3208 SetBreakPoint(foo, 8);
3211 step_action = StepIn;
3212 break_point_hit_count = 0;
3214 foo->
Call(env->Global(), argc, argv_10);
3215 CHECK_EQ(22, break_point_hit_count);
3218 step_action = StepIn;
3219 break_point_hit_count = 0;
3221 foo->
Call(env->Global(), argc, argv_100);
3222 CHECK_EQ(202, break_point_hit_count);
3226 CheckDebuggerUnloaded();
3230 TEST(DebugStepDoWhile) {
3232 DebugLocalContext env;
3240 const char* src =
"function foo(x) { "
3248 SetBreakPoint(foo, 8);
3251 step_action = StepIn;
3252 break_point_hit_count = 0;
3254 foo->
Call(env->Global(), argc, argv_10);
3255 CHECK_EQ(22, break_point_hit_count);
3258 step_action = StepIn;
3259 break_point_hit_count = 0;
3261 foo->
Call(env->Global(), argc, argv_100);
3262 CHECK_EQ(202, break_point_hit_count);
3266 CheckDebuggerUnloaded();
3270 TEST(DebugStepFor) {
3272 DebugLocalContext env;
3280 const char* src =
"function foo(x) { "
3282 " for (i = 0; i < x; i++) {"
3286 "a=0; b=0; i=0; foo()";
3289 SetBreakPoint(foo, 8);
3292 step_action = StepIn;
3293 break_point_hit_count = 0;
3295 foo->
Call(env->Global(), argc, argv_10);
3296 CHECK_EQ(23, break_point_hit_count);
3299 step_action = StepIn;
3300 break_point_hit_count = 0;
3302 foo->
Call(env->Global(), argc, argv_100);
3303 CHECK_EQ(203, break_point_hit_count);
3307 CheckDebuggerUnloaded();
3311 TEST(DebugStepForContinue) {
3313 DebugLocalContext env;
3321 const char* src =
"function foo(x) { "
3325 " for (var i = 0; i < x; i++) {"
3327 " if (a % 2 == 0) continue;"
3336 SetBreakPoint(foo, 8);
3341 step_action = StepIn;
3342 break_point_hit_count = 0;
3344 result = foo->
Call(env->Global(), argc, argv_10);
3346 CHECK_EQ(51, break_point_hit_count);
3349 step_action = StepIn;
3350 break_point_hit_count = 0;
3352 result = foo->
Call(env->Global(), argc, argv_100);
3354 CHECK_EQ(456, break_point_hit_count);
3358 CheckDebuggerUnloaded();
3362 TEST(DebugStepForBreak) {
3364 DebugLocalContext env;
3372 const char* src =
"function foo(x) { "
3376 " for (var i = 0; i < 1000; i++) {"
3378 " if (a == x) break;"
3387 SetBreakPoint(foo, 8);
3393 step_action = StepIn;
3394 break_point_hit_count = 0;
3396 result = foo->
Call(env->Global(), argc, argv_10);
3398 CHECK_EQ(54, break_point_hit_count);
3401 step_action = StepIn;
3402 break_point_hit_count = 0;
3404 result = foo->
Call(env->Global(), argc, argv_100);
3406 CHECK_EQ(504, break_point_hit_count);
3410 CheckDebuggerUnloaded();
3414 TEST(DebugStepForIn) {
3416 DebugLocalContext env;
3424 const char* src_1 =
"function foo() { "
3431 foo = CompileFunction(&env, src_1,
"foo");
3432 SetBreakPoint(foo, 0);
3434 step_action = StepIn;
3435 break_point_hit_count = 0;
3437 CHECK_EQ(6, break_point_hit_count);
3441 const char* src_2 =
"function foo() { "
3442 " var a = {a:[1, 2, 3]};"
3448 foo = CompileFunction(&env, src_2,
"foo");
3449 SetBreakPoint(foo, 0);
3451 step_action = StepIn;
3452 break_point_hit_count = 0;
3454 CHECK_EQ(8, break_point_hit_count);
3458 CheckDebuggerUnloaded();
3462 TEST(DebugStepWith) {
3464 DebugLocalContext env;
3471 const char* src =
"function foo(x) { "
3480 SetBreakPoint(foo, 8);
3482 step_action = StepIn;
3483 break_point_hit_count = 0;
3485 CHECK_EQ(4, break_point_hit_count);
3489 CheckDebuggerUnloaded();
3493 TEST(DebugConditional) {
3495 DebugLocalContext env;
3502 const char* src =
"function foo(x) { "
3509 SetBreakPoint(foo, 0);
3511 step_action = StepIn;
3512 break_point_hit_count = 0;
3514 CHECK_EQ(5, break_point_hit_count);
3516 step_action = StepIn;
3517 break_point_hit_count = 0;
3520 foo->
Call(env->Global(), argc, argv_true);
3521 CHECK_EQ(5, break_point_hit_count);
3525 CheckDebuggerUnloaded();
3529 TEST(StepInOutSimple) {
3531 DebugLocalContext env;
3534 frame_function_name = CompileFunction(&env,
3535 frame_function_name_source,
3536 "frame_function_name");
3543 const char* src =
"function a() {b();c();}; "
3544 "function b() {c();}; "
3548 SetBreakPoint(a, 0);
3551 step_action = StepIn;
3552 break_point_hit_count = 0;
3553 expected_step_sequence =
"abcbaca";
3556 break_point_hit_count);
3559 step_action = StepNext;
3560 break_point_hit_count = 0;
3561 expected_step_sequence =
"aaa";
3564 break_point_hit_count);
3567 step_action = StepOut;
3568 break_point_hit_count = 0;
3569 expected_step_sequence =
"a";
3572 break_point_hit_count);
3576 CheckDebuggerUnloaded();
3580 TEST(StepInOutTree) {
3582 DebugLocalContext env;
3585 frame_function_name = CompileFunction(&env,
3586 frame_function_name_source,
3587 "frame_function_name");
3594 const char* src =
"function a() {b(c(d()),d());c(d());d()}; "
3595 "function b(x,y) {c();}; "
3596 "function c(x) {}; "
3598 "a(); b(); c(); d()";
3600 SetBreakPoint(a, 0);
3603 step_action = StepIn;
3604 break_point_hit_count = 0;
3605 expected_step_sequence =
"adacadabcbadacada";
3608 break_point_hit_count);
3611 step_action = StepNext;
3612 break_point_hit_count = 0;
3613 expected_step_sequence =
"aaaa";
3616 break_point_hit_count);
3619 step_action = StepOut;
3620 break_point_hit_count = 0;
3621 expected_step_sequence =
"a";
3624 break_point_hit_count);
3628 CheckDebuggerUnloaded(
true);
3632 TEST(StepInOutBranch) {
3634 DebugLocalContext env;
3637 frame_function_name = CompileFunction(&env,
3638 frame_function_name_source,
3639 "frame_function_name");
3646 const char* src =
"function a() {b(false);c();}; "
3647 "function b(x) {if(x){c();};}; "
3651 SetBreakPoint(a, 0);
3654 step_action = StepIn;
3655 break_point_hit_count = 0;
3656 expected_step_sequence =
"abbaca";
3659 break_point_hit_count);
3663 CheckDebuggerUnloaded();
3668 TEST(DebugStepNatives) {
3670 DebugLocalContext env;
3675 "function foo(){debugger;Math.sin(1);}",
3681 step_action = StepIn;
3682 break_point_hit_count = 0;
3686 CHECK_EQ(3, break_point_hit_count);
3689 CheckDebuggerUnloaded();
3694 break_point_hit_count = 0;
3698 CHECK_EQ(1, break_point_hit_count);
3701 CheckDebuggerUnloaded();
3706 TEST(DebugStepFunctionApply) {
3708 DebugLocalContext env;
3713 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
3714 "function foo(){ debugger; bar.apply(this, [1,2,3]); }",
3720 step_action = StepIn;
3721 break_point_hit_count = 0;
3725 CHECK_EQ(7, break_point_hit_count);
3728 CheckDebuggerUnloaded();
3733 break_point_hit_count = 0;
3737 CHECK_EQ(1, break_point_hit_count);
3740 CheckDebuggerUnloaded();
3745 TEST(DebugStepFunctionCall) {
3747 DebugLocalContext env;
3752 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
3753 "function foo(a){ debugger;"
3755 " bar.call(this, 1, 2, 3);"
3757 " bar.call(this, 0);"
3764 step_action = StepIn;
3767 break_point_hit_count = 0;
3769 CHECK_EQ(6, break_point_hit_count);
3772 break_point_hit_count = 0;
3775 foo->
Call(env->Global(), argc, argv);
3776 CHECK_EQ(8, break_point_hit_count);
3779 CheckDebuggerUnloaded();
3784 break_point_hit_count = 0;
3788 CHECK_EQ(1, break_point_hit_count);
3791 CheckDebuggerUnloaded();
3796 TEST(PauseInScript) {
3798 DebugLocalContext env;
3805 const char* src =
"(function (evt) {})";
3806 const char* script_name =
"StepInHandlerTest";
3809 SetScriptBreakPointByNameFromJS(script_name, 0, -1);
3810 break_point_hit_count = 0;
3818 CHECK_EQ(1, break_point_hit_count);
3822 CheckDebuggerUnloaded();
3832 TEST(BreakOnException) {
3834 DebugLocalContext env;
3837 v8::internal::Isolate::Current()->TraceException(
false);
3840 CompileFunction(&env,
"function throws(){throw 1;}",
"throws");
3842 CompileFunction(&env,
3843 "function caught(){try {throws();} catch(e) {};}",
3846 CompileFunction(&env,
"function notCaught(){throws();}",
"notCaught");
3852 DebugEventCounterClear();
3853 MessageCallbackCountClear();
3854 caught->
Call(env->Global(), 0,
NULL);
3856 CHECK_EQ(0, uncaught_exception_hit_count);
3857 CHECK_EQ(0, message_callback_count);
3858 notCaught->
Call(env->Global(), 0,
NULL);
3860 CHECK_EQ(0, uncaught_exception_hit_count);
3861 CHECK_EQ(1, message_callback_count);
3864 DebugEventCounterClear();
3865 MessageCallbackCountClear();
3866 ChangeBreakOnException(
false,
false);
3867 caught->
Call(env->Global(), 0,
NULL);
3869 CHECK_EQ(0, uncaught_exception_hit_count);
3870 CHECK_EQ(0, message_callback_count);
3871 notCaught->
Call(env->Global(), 0,
NULL);
3873 CHECK_EQ(0, uncaught_exception_hit_count);
3874 CHECK_EQ(1, message_callback_count);
3877 DebugEventCounterClear();
3878 MessageCallbackCountClear();
3879 ChangeBreakOnException(
false,
true);
3880 caught->
Call(env->Global(), 0,
NULL);
3882 CHECK_EQ(0, uncaught_exception_hit_count);
3883 CHECK_EQ(0, message_callback_count);
3884 notCaught->
Call(env->Global(), 0,
NULL);
3886 CHECK_EQ(1, uncaught_exception_hit_count);
3887 CHECK_EQ(1, message_callback_count);
3890 DebugEventCounterClear();
3891 MessageCallbackCountClear();
3892 ChangeBreakOnException(
true,
true);
3893 caught->
Call(env->Global(), 0,
NULL);
3895 CHECK_EQ(0, uncaught_exception_hit_count);
3896 CHECK_EQ(0, message_callback_count);
3897 notCaught->
Call(env->Global(), 0,
NULL);
3899 CHECK_EQ(1, uncaught_exception_hit_count);
3900 CHECK_EQ(1, message_callback_count);
3903 DebugEventCounterClear();
3904 MessageCallbackCountClear();
3905 ChangeBreakOnException(
true,
false);
3906 caught->
Call(env->Global(), 0,
NULL);
3908 CHECK_EQ(0, uncaught_exception_hit_count);
3909 CHECK_EQ(0, message_callback_count);
3910 notCaught->
Call(env->Global(), 0,
NULL);
3912 CHECK_EQ(1, uncaught_exception_hit_count);
3913 CHECK_EQ(1, message_callback_count);
3916 DebugEventCounterClear();
3917 MessageCallbackCountClear();
3918 ChangeBreakOnExceptionFromJS(
false,
false);
3919 caught->
Call(env->Global(), 0,
NULL);
3921 CHECK_EQ(0, uncaught_exception_hit_count);
3922 CHECK_EQ(0, message_callback_count);
3923 notCaught->
Call(env->Global(), 0,
NULL);
3925 CHECK_EQ(0, uncaught_exception_hit_count);
3926 CHECK_EQ(1, message_callback_count);
3929 DebugEventCounterClear();
3930 MessageCallbackCountClear();
3931 ChangeBreakOnExceptionFromJS(
false,
true);
3932 caught->
Call(env->Global(), 0,
NULL);
3934 CHECK_EQ(0, uncaught_exception_hit_count);
3935 CHECK_EQ(0, message_callback_count);
3936 notCaught->
Call(env->Global(), 0,
NULL);
3938 CHECK_EQ(1, uncaught_exception_hit_count);
3939 CHECK_EQ(1, message_callback_count);
3942 DebugEventCounterClear();
3943 MessageCallbackCountClear();
3944 ChangeBreakOnExceptionFromJS(
true,
true);
3945 caught->
Call(env->Global(), 0,
NULL);
3947 CHECK_EQ(0, message_callback_count);
3948 CHECK_EQ(0, uncaught_exception_hit_count);
3949 notCaught->
Call(env->Global(), 0,
NULL);
3951 CHECK_EQ(1, uncaught_exception_hit_count);
3952 CHECK_EQ(1, message_callback_count);
3955 DebugEventCounterClear();
3956 MessageCallbackCountClear();
3957 ChangeBreakOnExceptionFromJS(
true,
false);
3958 caught->
Call(env->Global(), 0,
NULL);
3960 CHECK_EQ(0, uncaught_exception_hit_count);
3961 CHECK_EQ(0, message_callback_count);
3962 notCaught->
Call(env->Global(), 0,
NULL);
3964 CHECK_EQ(1, uncaught_exception_hit_count);
3965 CHECK_EQ(1, message_callback_count);
3968 CheckDebuggerUnloaded();
3976 TEST(BreakOnCompileException) {
3978 DebugLocalContext env;
3981 ChangeBreakOnException(
false,
true);
3983 v8::internal::Isolate::Current()->TraceException(
false);
3986 frame_count = CompileFunction(&env, frame_count_source,
"frame_count");
3991 DebugEventCounterClear();
3992 MessageCallbackCountClear();
3996 CHECK_EQ(0, uncaught_exception_hit_count);
3997 CHECK_EQ(0, message_callback_count);
3998 CHECK_EQ(-1, last_js_stack_height);
4003 CHECK_EQ(1, uncaught_exception_hit_count);
4004 CHECK_EQ(1, message_callback_count);
4010 CHECK_EQ(2, uncaught_exception_hit_count);
4011 CHECK_EQ(2, message_callback_count);
4017 CHECK_EQ(3, uncaught_exception_hit_count);
4018 CHECK_EQ(3, message_callback_count);
4024 CHECK_EQ(4, uncaught_exception_hit_count);
4025 CHECK_EQ(4, message_callback_count);
4030 TEST(StepWithException) {
4032 DebugLocalContext env;
4035 ChangeBreakOnException(
false,
true);
4038 frame_function_name = CompileFunction(&env,
4039 frame_function_name_source,
4040 "frame_function_name");
4046 const char* src =
"function a() { n(); }; "
4047 "function b() { c(); }; "
4048 "function c() { n(); }; "
4049 "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; "
4050 "function e() { n(); }; "
4051 "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; "
4052 "function g() { h(); }; "
4053 "function h() { x = 1; throw 1; }; ";
4057 SetBreakPoint(a, 0);
4058 step_action = StepIn;
4059 break_point_hit_count = 0;
4060 expected_step_sequence =
"aa";
4063 break_point_hit_count);
4067 SetBreakPoint(b, 0);
4068 step_action = StepIn;
4069 break_point_hit_count = 0;
4070 expected_step_sequence =
"bcc";
4073 break_point_hit_count);
4076 SetBreakPoint(d, 0);
4077 ChangeBreakOnException(
false,
true);
4078 step_action = StepIn;
4079 break_point_hit_count = 0;
4080 expected_step_sequence =
"ddedd";
4083 break_point_hit_count);
4086 ChangeBreakOnException(
true,
true);
4087 step_action = StepIn;
4088 break_point_hit_count = 0;
4089 expected_step_sequence =
"ddeedd";
4092 break_point_hit_count);
4096 SetBreakPoint(f, 0);
4097 ChangeBreakOnException(
false,
true);
4098 step_action = StepIn;
4099 break_point_hit_count = 0;
4100 expected_step_sequence =
"ffghhff";
4103 break_point_hit_count);
4106 ChangeBreakOnException(
true,
true);
4107 step_action = StepIn;
4108 break_point_hit_count = 0;
4109 expected_step_sequence =
"ffghhhff";
4112 break_point_hit_count);
4116 CheckDebuggerUnloaded();
4122 i::FLAG_verify_heap =
true;
4125 DebugLocalContext env;
4131 const char* src =
"function f0() {}"
4132 "function f1(x1) {}"
4133 "function f2(x1,x2) {}"
4134 "function f3(x1,x2,x3) {}";
4156 break_point_hit_count = 0;
4157 for (
unsigned int i = 0; i <
ARRAY_SIZE(argv); i++) {
4158 f0->
Call(env->Global(), i, argv);
4159 f1->
Call(env->Global(), i, argv);
4160 f2->
Call(env->Global(), i, argv);
4161 f3->
Call(env->Global(), i, argv);
4169 CheckDebuggerUnloaded();
4175 TEST(DisableBreak) {
4177 DebugLocalContext env;
4183 const char* src =
"function f() {g()};function g(){i=0; while(i<10){i++}}";
4190 break_point_hit_count = 0;
4192 CHECK_EQ(1, break_point_hit_count);
4196 v8::internal::DisableBreak disable_break(
true);
4198 CHECK_EQ(1, break_point_hit_count);
4202 CHECK_EQ(2, break_point_hit_count);
4206 CheckDebuggerUnloaded();
4209 static const char* kSimpleExtensionSource =
4216 TEST(NoBreakWhenBootstrapping) {
4224 break_point_hit_count = 0;
4229 kSimpleExtensionSource));
4230 const char* extension_names[] = {
"simpletest" };
4236 CHECK_EQ(0, break_point_hit_count);
4240 CheckDebuggerUnloaded();
4263 if (strcmp(*n,
"a") == 0) {
4265 }
else if (strcmp(*n,
"b") == 0) {
4267 }
else if (strcmp(*n,
"c") == 0) {
4283 TEST(InterceptorPropertyMirror) {
4286 DebugLocalContext env;
4313 "var named_mirror = debug.MakeMirror(intercepted_named);"
4314 "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
4315 "var both_mirror = debug.MakeMirror(intercepted_both)");
4317 "named_mirror instanceof debug.ObjectMirror")->BooleanValue());
4319 "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue());
4321 "both_mirror instanceof debug.ObjectMirror")->BooleanValue());
4325 "named_names = named_mirror.propertyNames();"
4326 "indexed_names = indexed_mirror.propertyNames();"
4327 "both_names = both_mirror.propertyNames()");
4328 CHECK_EQ(3, CompileRun(
"named_names.length")->Int32Value());
4329 CHECK_EQ(2, CompileRun(
"indexed_names.length")->Int32Value());
4330 CHECK_EQ(5, CompileRun(
"both_names.length")->Int32Value());
4334 source =
"named_mirror.properties().length";
4335 CHECK_EQ(3, CompileRun(source)->Int32Value());
4337 source =
"indexed_mirror.properties().length";
4338 CHECK_EQ(2, CompileRun(source)->Int32Value());
4340 source =
"both_mirror.properties().length";
4341 CHECK_EQ(5, CompileRun(source)->Int32Value());
4344 source =
"both_mirror.properties(1).length";
4345 CHECK_EQ(3, CompileRun(source)->Int32Value());
4348 source =
"both_mirror.properties(2).length";
4349 CHECK_EQ(2, CompileRun(source)->Int32Value());
4352 source =
"both_mirror.properties(3).length";
4353 CHECK_EQ(5, CompileRun(source)->Int32Value());
4356 CompileRun(
"var named_values = named_mirror.properties()");
4359 for (
int i = 0; i < 3; i++) {
4360 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4361 OS::SNPrintF(buffer,
4362 "named_values[%d] instanceof debug.PropertyMirror", i);
4363 CHECK(CompileRun(buffer.start())->BooleanValue());
4365 OS::SNPrintF(buffer,
"named_values[%d].propertyType()", i);
4367 CompileRun(buffer.start())->Int32Value());
4369 OS::SNPrintF(buffer,
"named_values[%d].isNative()", i);
4370 CHECK(CompileRun(buffer.start())->BooleanValue());
4375 CompileRun(
"var indexed_values = indexed_mirror.properties()");
4378 for (
int i = 0; i < 2; i++) {
4379 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4380 OS::SNPrintF(buffer,
4381 "indexed_values[%d] instanceof debug.PropertyMirror", i);
4382 CHECK(CompileRun(buffer.start())->BooleanValue());
4387 CompileRun(
"var both_values = both_mirror.properties()");
4390 for (
int i = 0; i < 5; i++) {
4391 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4392 OS::SNPrintF(buffer,
"both_values[%d] instanceof debug.PropertyMirror", i);
4393 CHECK(CompileRun(buffer.start())->BooleanValue());
4397 source =
"both_values[0].name() == 'a'";
4398 CHECK(CompileRun(source)->BooleanValue());
4400 source =
"both_values[1].name() == 'b'";
4401 CHECK(CompileRun(source)->BooleanValue());
4403 source =
"both_values[2].name() == 'c'";
4404 CHECK(CompileRun(source)->BooleanValue());
4406 source =
"both_values[3].name() == 1";
4407 CHECK(CompileRun(source)->BooleanValue());
4409 source =
"both_values[4].name() == 10";
4410 CHECK(CompileRun(source)->BooleanValue());
4414 TEST(HiddenPrototypePropertyMirror) {
4417 DebugLocalContext env;
4443 "var o0_mirror = debug.MakeMirror(o0);"
4444 "var o1_mirror = debug.MakeMirror(o1);"
4445 "var o2_mirror = debug.MakeMirror(o2);"
4446 "var o3_mirror = debug.MakeMirror(o3)");
4447 CHECK(CompileRun(
"o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
4448 CHECK(CompileRun(
"o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
4449 CHECK(CompileRun(
"o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
4450 CHECK(CompileRun(
"o3_mirror instanceof debug.ObjectMirror")->BooleanValue());
4454 "o0_mirror.propertyNames().length")->Int32Value());
4456 "o1_mirror.propertyNames().length")->Int32Value());
4458 "o2_mirror.propertyNames().length")->Int32Value());
4460 "o3_mirror.propertyNames().length")->Int32Value());
4466 "o0_mirror.propertyNames().length")->Int32Value());
4468 "o0_mirror.property('x').value().value()")->Int32Value());
4470 "o0_mirror.property('y').value().value()")->Int32Value());
4477 "o0_mirror.propertyNames().length")->Int32Value());
4479 "o0_mirror.property('x').value().value()")->Int32Value());
4481 "o0_mirror.property('y').value().value()")->Int32Value());
4483 "o0_mirror.property('z').value().value()")->Int32Value());
4493 "o0_mirror.propertyNames().length")->Int32Value());
4495 "o3_mirror.propertyNames().length")->Int32Value());
4497 "o0_mirror.property('x').value().value()")->Int32Value());
4499 "o0_mirror.property('y').value().value()")->Int32Value());
4501 "o0_mirror.property('z').value().value()")->Int32Value());
4502 CHECK(CompileRun(
"o0_mirror.property('u').isUndefined()")->BooleanValue());
4505 CHECK(CompileRun(
"o0_mirror.protoObject() == o3_mirror")->BooleanValue());
4515 TEST(NativeGetterPropertyMirror) {
4518 DebugLocalContext env;
4529 CHECK_EQ(10, CompileRun(
"instance.x")->Int32Value());
4532 CompileRun(
"var instance_mirror = debug.MakeMirror(instance);");
4534 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4536 CompileRun(
"var named_names = instance_mirror.propertyNames();");
4537 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4538 CHECK(CompileRun(
"named_names[0] == 'x'")->BooleanValue());
4540 "instance_mirror.property('x').value().isNumber()")->BooleanValue());
4542 "instance_mirror.property('x').value().value() == 10")->BooleanValue());
4548 return CompileRun(
"throw new Error('Error message');");
4552 TEST(NativeGetterThrowingErrorPropertyMirror) {
4555 DebugLocalContext env;
4568 CompileRun(
"var instance_mirror = debug.MakeMirror(instance);");
4570 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4571 CompileRun(
"named_names = instance_mirror.propertyNames();");
4572 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4573 CHECK(CompileRun(
"named_names[0] == 'x'")->BooleanValue());
4575 "instance_mirror.property('x').value().isError()")->BooleanValue());
4579 "instance_mirror.property('x').value().message() == 'Error message'")->
4587 TEST(NoHiddenProperties) {
4590 DebugLocalContext env;
4594 const char* source =
"var obj = {a: 1};";
4603 CompileRun(
"var obj_mirror = debug.MakeMirror(obj);");
4605 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4606 CompileRun(
"var named_names = obj_mirror.propertyNames();");
4610 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4611 CHECK(CompileRun(
"named_names[0] == 'a'")->BooleanValue());
4613 "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4638 CompileRun(
"var obj_mirror = debug.MakeMirror(obj);");
4640 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4641 CompileRun(
"var named_names = obj_mirror.propertyNames();");
4644 CHECK_EQ(2, CompileRun(
"named_names.length")->Int32Value());
4645 CHECK(CompileRun(
"named_names.sort(); named_names[0] == 'a' &&"
4646 "named_names[1] == 'b'")->BooleanValue());
4648 "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4650 "obj_mirror.property('b').value().value() == 2")->BooleanValue());
4662 class ThreadBarrier {
4664 explicit ThreadBarrier(
int num_threads);
4675 ThreadBarrier::ThreadBarrier(
int num_threads)
4676 : num_threads_(num_threads), num_blocked_(0) {
4677 lock_ = OS::CreateMutex();
4678 sem_ = OS::CreateSemaphore(0);
4684 ThreadBarrier::~ThreadBarrier() {
4690 void ThreadBarrier::Wait() {
4693 if (num_blocked_ == num_threads_ - 1) {
4695 for (
int i = 0; i < num_threads_ - 1; ++i) {
4699 printf(
"BARRIER\n\n");
4714 ThreadBarrier barrier_1;
4715 ThreadBarrier barrier_2;
4716 ThreadBarrier barrier_3;
4717 ThreadBarrier barrier_4;
4718 ThreadBarrier barrier_5;
4723 Barriers::Barriers() : barrier_1(2), barrier_2(2),
4724 barrier_3(2), barrier_4(2), barrier_5(2) {}
4726 void Barriers::Initialize() {
4727 semaphore_1 = OS::CreateSemaphore(0);
4728 semaphore_2 = OS::CreateSemaphore(0);
4733 bool IsBreakEventMessage(
char *message) {
4734 const char* type_event =
"\"type\":\"event\"";
4735 const char* event_break =
"\"event\":\"break\"";
4737 return strstr(message, type_event) !=
NULL &&
4738 strstr(message, event_break) !=
NULL;
4743 bool IsExceptionEventMessage(
char *message) {
4744 const char* type_event =
"\"type\":\"event\"";
4745 const char* event_exception =
"\"event\":\"exception\"";
4747 return strstr(message, type_event) !=
NULL &&
4748 strstr(message, event_exception) !=
NULL;
4753 bool IsEvaluateResponseMessage(
char* message) {
4754 const char* type_response =
"\"type\":\"response\"";
4755 const char* command_evaluate =
"\"command\":\"evaluate\"";
4757 return strstr(message, type_response) !=
NULL &&
4758 strstr(message, command_evaluate) !=
NULL;
4768 int GetEvaluateIntResult(
char *message) {
4769 const char* value =
"\"value\":";
4770 char* pos = strstr(message, value);
4781 int GetBreakpointIdFromBreakEventMessage(
char *message) {
4782 const char* breakpoints =
"\"breakpoints\":[";
4783 char* pos = strstr(message, breakpoints);
4794 int GetTotalFramesInt(
char *message) {
4795 const char* prefix =
"\"totalFrames\":";
4796 char* pos = strstr(message, prefix);
4800 pos += strlen(prefix);
4807 int GetSourceLineFromBreakEventMessage(
char *message) {
4808 const char* source_line =
"\"sourceLine\":";
4809 char* pos = strstr(message, source_line);
4823 Barriers message_queue_barriers;
4829 MessageQueueDebuggerThread()
4830 : Thread(
"MessageQueueDebuggerThread") { }
4834 static void MessageHandler(
const uint16_t* message,
int length,
4836 static char print_buffer[1000];
4837 Utf16ToAscii(message, length, print_buffer);
4838 if (IsBreakEventMessage(print_buffer)) {
4841 message_queue_barriers.semaphore_2->Signal();
4846 message_queue_barriers.semaphore_1->Wait();
4849 void MessageQueueDebuggerThread::Run() {
4850 const int kBufferSize = 1000;
4853 const char* command_1 =
4855 "\"type\":\"request\","
4856 "\"command\":\"evaluate\","
4857 "\"arguments\":{\"expression\":\"1+2\"}}";
4858 const char* command_2 =
4860 "\"type\":\"request\","
4861 "\"command\":\"evaluate\","
4862 "\"arguments\":{\"expression\":\"1+a\"}}";
4863 const char* command_3 =
4865 "\"type\":\"request\","
4866 "\"command\":\"evaluate\","
4867 "\"arguments\":{\"expression\":\"c.d * b\"}}";
4868 const char* command_continue =
4870 "\"type\":\"request\","
4871 "\"command\":\"continue\"}";
4872 const char* command_single_step =
4874 "\"type\":\"request\","
4875 "\"command\":\"continue\","
4876 "\"arguments\":{\"stepaction\":\"next\"}}";
4880 message_queue_barriers.semaphore_1->Signal();
4881 message_queue_barriers.barrier_1.Wait();
4892 message_queue_barriers.barrier_2.Wait();
4900 for (
int i = 0; i < 6 ; ++i) {
4901 message_queue_barriers.semaphore_1->Signal();
4903 message_queue_barriers.barrier_3.Wait();
4906 message_queue_barriers.semaphore_1->Signal();
4909 message_queue_barriers.semaphore_2->Wait();
4916 for (
int i = 0; i < 6 ; ++i) {
4917 message_queue_barriers.semaphore_1->Signal();
4920 message_queue_barriers.semaphore_2->Wait();
4924 for (
int i = 0; i < 2 ; ++i) {
4925 message_queue_barriers.semaphore_1->Signal();
4932 TEST(MessageQueues) {
4933 MessageQueueDebuggerThread message_queue_debugger_thread;
4937 DebugLocalContext env;
4938 message_queue_barriers.Initialize();
4940 message_queue_debugger_thread.Start();
4942 const char* source_1 =
"a = 3; b = 4; c = new Object(); c.d = 5;";
4943 const char* source_2 =
"e = 17;";
4944 const char* source_3 =
"a = 4; debugger; a = 5; a = 6; a = 7;";
4948 CompileRun(source_1);
4949 message_queue_barriers.barrier_1.Wait();
4950 message_queue_barriers.barrier_2.Wait();
4951 CompileRun(source_2);
4952 message_queue_barriers.barrier_3.Wait();
4953 CompileRun(source_3);
4954 message_queue_debugger_thread.Join();
4962 constructor_call_counter++;
4964 virtual ~TestClientData() {
4965 destructor_call_counter++;
4968 static void ResetCounters() {
4969 constructor_call_counter = 0;
4970 destructor_call_counter = 0;
4973 static int constructor_call_counter;
4974 static int destructor_call_counter;
4977 int TestClientData::constructor_call_counter = 0;
4978 int TestClientData::destructor_call_counter = 0;
4983 TEST(MessageQueueExpandAndDestroy) {
4984 TestClientData::ResetCounters();
4986 CommandMessageQueue queue(1);
4987 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
4988 new TestClientData()));
4989 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
4990 new TestClientData()));
4991 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
4992 new TestClientData()));
4993 CHECK_EQ(0, TestClientData::destructor_call_counter);
4994 queue.Get().Dispose();
4995 CHECK_EQ(1, TestClientData::destructor_call_counter);
4996 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
4997 new TestClientData()));
4998 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
4999 new TestClientData()));
5000 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5001 new TestClientData()));
5002 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5003 new TestClientData()));
5004 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5005 new TestClientData()));
5006 CHECK_EQ(1, TestClientData::destructor_call_counter);
5007 queue.Get().Dispose();
5008 CHECK_EQ(2, TestClientData::destructor_call_counter);
5011 CHECK_EQ(TestClientData::destructor_call_counter,
5012 TestClientData::destructor_call_counter);
5016 static int handled_client_data_instances_count = 0;
5017 static void MessageHandlerCountingClientData(
5020 handled_client_data_instances_count++;
5026 TEST(SendClientDataToHandler) {
5029 DebugLocalContext env;
5030 TestClientData::ResetCounters();
5031 handled_client_data_instances_count = 0;
5033 const char* source_1 =
"a = 3; b = 4; c = new Object(); c.d = 5;";
5034 const int kBufferSize = 1000;
5036 const char* command_1 =
5038 "\"type\":\"request\","
5039 "\"command\":\"evaluate\","
5040 "\"arguments\":{\"expression\":\"1+2\"}}";
5041 const char* command_2 =
5043 "\"type\":\"request\","
5044 "\"command\":\"evaluate\","
5045 "\"arguments\":{\"expression\":\"1+a\"}}";
5046 const char* command_continue =
5048 "\"type\":\"request\","
5049 "\"command\":\"continue\"}";
5052 new TestClientData());
5055 new TestClientData());
5057 new TestClientData());
5059 CompileRun(source_1);
5061 CHECK_EQ(3, TestClientData::constructor_call_counter);
5062 CHECK_EQ(TestClientData::constructor_call_counter,
5063 handled_client_data_instances_count);
5064 CHECK_EQ(TestClientData::constructor_call_counter,
5065 TestClientData::destructor_call_counter);
5076 Barriers threaded_debugging_barriers;
5080 V8Thread() : Thread(
"V8Thread") { }
5086 DebuggerThread() : Thread(
"DebuggerThread") { }
5092 threaded_debugging_barriers.barrier_1.Wait();
5098 static char print_buffer[1000];
5100 Utf16ToAscii(*json, json.length(), print_buffer);
5101 if (IsBreakEventMessage(print_buffer)) {
5103 int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
5107 CHECK(7 <= source_line && source_line <= 13);
5108 threaded_debugging_barriers.barrier_2.Wait();
5113 void V8Thread::Run() {
5114 const char* source =
5116 "function bar( new_value ) {\n"
5117 " flag = new_value;\n"
5118 " return \"Return from bar(\" + new_value + \")\";\n"
5121 "function foo() {\n"
5123 " while ( flag == true ) {\n"
5124 " if ( x == 1 ) {\n"
5125 " ThreadedAtBarrier1();\n"
5135 DebugLocalContext env;
5146 void DebuggerThread::Run() {
5147 const int kBufSize = 1000;
5150 const char* command_1 =
"{\"seq\":102,"
5151 "\"type\":\"request\","
5152 "\"command\":\"evaluate\","
5153 "\"arguments\":{\"expression\":\"bar(false)\"}}";
5154 const char* command_2 =
"{\"seq\":103,"
5155 "\"type\":\"request\","
5156 "\"command\":\"continue\"}";
5158 threaded_debugging_barriers.barrier_1.Wait();
5160 threaded_debugging_barriers.barrier_2.Wait();
5166 TEST(ThreadedDebugging) {
5167 DebuggerThread debugger_thread;
5171 threaded_debugging_barriers.Initialize();
5174 debugger_thread.Start();
5177 debugger_thread.Join();
5189 BreakpointsV8Thread() : Thread(
"BreakpointsV8Thread") { }
5195 explicit BreakpointsDebuggerThread(
bool global_evaluate)
5196 : Thread(
"BreakpointsDebuggerThread"),
5197 global_evaluate_(global_evaluate) {}
5201 bool global_evaluate_;
5205 Barriers* breakpoints_barriers;
5206 int break_event_breakpoint_id;
5207 int evaluate_int_result;
5210 static char print_buffer[1000];
5212 Utf16ToAscii(*json, json.length(), print_buffer);
5214 if (IsBreakEventMessage(print_buffer)) {
5215 break_event_breakpoint_id =
5216 GetBreakpointIdFromBreakEventMessage(print_buffer);
5217 breakpoints_barriers->semaphore_1->Signal();
5218 }
else if (IsEvaluateResponseMessage(print_buffer)) {
5219 evaluate_int_result = GetEvaluateIntResult(print_buffer);
5220 breakpoints_barriers->semaphore_1->Signal();
5225 void BreakpointsV8Thread::Run() {
5226 const char* source_1 =
"var y_global = 3;\n"
5227 "function cat( new_value ) {\n"
5228 " var x = new_value;\n"
5229 " y_global = y_global + 4;\n"
5231 " y_global = y_global + 5;\n"
5235 "function dog() {\n"
5243 const char* source_2 =
"cat(17);\n"
5248 DebugLocalContext env;
5251 CompileRun(source_1);
5252 breakpoints_barriers->barrier_1.Wait();
5253 breakpoints_barriers->barrier_2.Wait();
5254 CompileRun(source_2);
5258 void BreakpointsDebuggerThread::Run() {
5259 const int kBufSize = 1000;
5262 const char* command_1 =
"{\"seq\":101,"
5263 "\"type\":\"request\","
5264 "\"command\":\"setbreakpoint\","
5265 "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5266 const char* command_2 =
"{\"seq\":102,"
5267 "\"type\":\"request\","
5268 "\"command\":\"setbreakpoint\","
5269 "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
5270 const char* command_3;
5271 if (this->global_evaluate_) {
5272 command_3 =
"{\"seq\":103,"
5273 "\"type\":\"request\","
5274 "\"command\":\"evaluate\","
5275 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
5276 "\"global\":true}}";
5278 command_3 =
"{\"seq\":103,"
5279 "\"type\":\"request\","
5280 "\"command\":\"evaluate\","
5281 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
5283 const char* command_4;
5284 if (this->global_evaluate_) {
5285 command_4 =
"{\"seq\":104,"
5286 "\"type\":\"request\","
5287 "\"command\":\"evaluate\","
5288 "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
5289 "\"global\":true}}";
5291 command_4 =
"{\"seq\":104,"
5292 "\"type\":\"request\","
5293 "\"command\":\"evaluate\","
5294 "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
5296 const char* command_5 =
"{\"seq\":105,"
5297 "\"type\":\"request\","
5298 "\"command\":\"continue\"}";
5299 const char* command_6 =
"{\"seq\":106,"
5300 "\"type\":\"request\","
5301 "\"command\":\"continue\"}";
5302 const char* command_7;
5303 if (this->global_evaluate_) {
5304 command_7 =
"{\"seq\":107,"
5305 "\"type\":\"request\","
5306 "\"command\":\"evaluate\","
5307 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
5308 "\"global\":true}}";
5310 command_7 =
"{\"seq\":107,"
5311 "\"type\":\"request\","
5312 "\"command\":\"evaluate\","
5313 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
5315 const char* command_8 =
"{\"seq\":108,"
5316 "\"type\":\"request\","
5317 "\"command\":\"continue\"}";
5321 breakpoints_barriers->barrier_1.Wait();
5326 breakpoints_barriers->barrier_2.Wait();
5333 breakpoints_barriers->semaphore_1->Wait();
5335 CHECK_EQ(1, break_event_breakpoint_id);
5339 breakpoints_barriers->semaphore_1->Wait();
5341 CHECK_EQ(2, break_event_breakpoint_id);
5345 breakpoints_barriers->semaphore_1->Wait();
5347 CHECK_EQ(108, evaluate_int_result);
5351 breakpoints_barriers->semaphore_1->Wait();
5353 CHECK_EQ(107, evaluate_int_result);
5358 breakpoints_barriers->semaphore_1->Wait();
5360 CHECK_EQ(1, break_event_breakpoint_id);
5364 breakpoints_barriers->semaphore_1->Wait();
5366 CHECK_EQ(116, evaluate_int_result);
5371 void TestRecursiveBreakpointsGeneric(
bool global_evaluate) {
5372 i::FLAG_debugger_auto_break =
true;
5374 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
5375 BreakpointsV8Thread breakpoints_v8_thread;
5378 Barriers stack_allocated_breakpoints_barriers;
5379 stack_allocated_breakpoints_barriers.Initialize();
5380 breakpoints_barriers = &stack_allocated_breakpoints_barriers;
5382 breakpoints_v8_thread.Start();
5383 breakpoints_debugger_thread.Start();
5385 breakpoints_v8_thread.Join();
5386 breakpoints_debugger_thread.Join();
5389 TEST(RecursiveBreakpoints) {
5390 TestRecursiveBreakpointsGeneric(
false);
5393 TEST(RecursiveBreakpointsGlobal) {
5394 TestRecursiveBreakpointsGeneric(
true);
5405 TEST(SetDebugEventListenerOnUninitializedVM) {
5414 TEST(SetMessageHandlerOnUninitializedVM) {
5419 TEST(DebugBreakOnUninitializedVM) {
5424 TEST(SendCommandToUninitializedVM) {
5425 const char* dummy_command =
"{}";
5427 int dummy_length = AsciiToUtf16(dummy_command, dummy_buffer);
5435 static const char* debugger_call_with_data_source =
5436 "function debugger_call_with_data(exec_state, data) {"
5437 " if (data) return data;"
5446 static const char* debugger_call_with_closure_source =
5448 "(function (exec_state) {"
5449 " if (exec_state.y) return x - 1;"
5450 " exec_state.y = x;"
5451 " return exec_state.y"
5503 TEST(CallFunctionInDebugger) {
5546 " CheckFrameCount(2);"
5552 " CheckSourceLine(1)\n"
5553 " CheckSourceLine(2)\n"
5554 " CheckSourceLine(3)\n"
5569 " CheckSourceLine(8)\n"
5570 " CheckSourceLine(9)\n"
5571 " CheckSourceLine(10)\n"
5572 "}; f()"), &origin)->Run();
5577 static void SendContinueCommand();
5578 static void MessageHandlerBreakPointHitCount(
5582 break_point_hit_count++;
5584 SendContinueCommand();
5591 TEST(DebuggerUnload) {
5592 DebugLocalContext env;
5595 CheckDebuggerUnloaded();
5598 break_point_hit_count = 0;
5605 CompileFunction(&env,
"function foo(){x=1}",
"foo");
5607 CompileFunction(&env,
"function bar(){y=2}",
"bar");
5610 SetBreakPoint(foo, 0);
5611 SetBreakPoint(foo, 4);
5612 SetBreakPoint(bar, 0);
5613 SetBreakPoint(bar, 4);
5616 break_point_hit_count = 0;
5618 CHECK_EQ(2, break_point_hit_count);
5620 CHECK_EQ(4, break_point_hit_count);
5626 CheckDebuggerUnloaded(
true);
5629 break_point_hit_count = 0;
5639 CHECK_EQ(0, break_point_hit_count);
5642 SetBreakPoint(foo, 0);
5643 SetBreakPoint(foo, 4);
5645 CHECK_EQ(2, break_point_hit_count);
5651 CheckDebuggerUnloaded(
true);
5656 static void SendContinueCommand() {
5657 const int kBufferSize = 1000;
5659 const char* command_continue =
5661 "\"type\":\"request\","
5662 "\"command\":\"continue\"}";
5669 static int message_handler_hit_count = 0;
5671 message_handler_hit_count++;
5673 static char print_buffer[1000];
5675 Utf16ToAscii(*json, json.length(), print_buffer);
5676 if (IsExceptionEventMessage(print_buffer)) {
5678 SendContinueCommand();
5684 TEST(DebuggerClearMessageHandler) {
5686 DebugLocalContext env;
5689 CheckDebuggerUnloaded();
5696 CompileRun(
"throw 1");
5699 CHECK_GT(message_handler_hit_count, 0);
5702 message_handler_hit_count = 0;
5707 CompileRun(
"throw 1");
5710 CHECK_EQ(0, message_handler_hit_count);
5712 CheckDebuggerUnloaded(
true);
5717 static void MessageHandlerClearingMessageHandler(
5719 message_handler_hit_count++;
5727 TEST(DebuggerClearMessageHandlerWhileActive) {
5729 DebugLocalContext env;
5732 CheckDebuggerUnloaded();
5739 CompileRun(
"throw 1");
5742 CHECK_EQ(1, message_handler_hit_count);
5744 CheckDebuggerUnloaded(
true);
5755 HostDispatchV8Thread() : Thread(
"HostDispatchV8Thread") { }
5761 HostDispatchDebuggerThread() : Thread(
"HostDispatchDebuggerThread") { }
5765 Barriers* host_dispatch_barriers;
5768 static char print_buffer[1000];
5770 Utf16ToAscii(*json, json.length(), print_buffer);
5774 static void HostDispatchDispatchHandler() {
5775 host_dispatch_barriers->semaphore_1->Signal();
5779 void HostDispatchV8Thread::Run() {
5780 const char* source_1 =
"var y_global = 3;\n"
5781 "function cat( new_value ) {\n"
5782 " var x = new_value;\n"
5789 const char* source_2 =
"cat(17);\n";
5793 DebugLocalContext env;
5799 CompileRun(source_1);
5800 host_dispatch_barriers->barrier_1.Wait();
5801 host_dispatch_barriers->barrier_2.Wait();
5802 CompileRun(source_2);
5806 void HostDispatchDebuggerThread::Run() {
5807 const int kBufSize = 1000;
5810 const char* command_1 =
"{\"seq\":101,"
5811 "\"type\":\"request\","
5812 "\"command\":\"setbreakpoint\","
5813 "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5814 const char* command_2 =
"{\"seq\":102,"
5815 "\"type\":\"request\","
5816 "\"command\":\"continue\"}";
5819 host_dispatch_barriers->barrier_1.Wait();
5823 host_dispatch_barriers->barrier_2.Wait();
5827 host_dispatch_barriers->semaphore_1->Wait();
5833 TEST(DebuggerHostDispatch) {
5834 HostDispatchDebuggerThread host_dispatch_debugger_thread;
5835 HostDispatchV8Thread host_dispatch_v8_thread;
5836 i::FLAG_debugger_auto_break =
true;
5839 Barriers stack_allocated_host_dispatch_barriers;
5840 stack_allocated_host_dispatch_barriers.Initialize();
5841 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
5843 host_dispatch_v8_thread.Start();
5844 host_dispatch_debugger_thread.Start();
5846 host_dispatch_v8_thread.Join();
5847 host_dispatch_debugger_thread.Join();
5859 DebugMessageDispatchV8Thread() : Thread(
"DebugMessageDispatchV8Thread") { }
5865 DebugMessageDispatchDebuggerThread()
5866 : Thread(
"DebugMessageDispatchDebuggerThread") { }
5870 Barriers* debug_message_dispatch_barriers;
5873 static void DebugMessageHandler() {
5874 debug_message_dispatch_barriers->semaphore_1->Signal();
5878 void DebugMessageDispatchV8Thread::Run() {
5881 DebugLocalContext env;
5886 CompileRun(
"var y = 1 + 2;\n");
5887 debug_message_dispatch_barriers->barrier_1.Wait();
5888 debug_message_dispatch_barriers->semaphore_1->Wait();
5889 debug_message_dispatch_barriers->barrier_2.Wait();
5893 void DebugMessageDispatchDebuggerThread::Run() {
5894 debug_message_dispatch_barriers->barrier_1.Wait();
5895 SendContinueCommand();
5896 debug_message_dispatch_barriers->barrier_2.Wait();
5900 TEST(DebuggerDebugMessageDispatch) {
5901 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
5902 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
5904 i::FLAG_debugger_auto_break =
true;
5907 Barriers stack_allocated_debug_message_dispatch_barriers;
5908 stack_allocated_debug_message_dispatch_barriers.Initialize();
5909 debug_message_dispatch_barriers =
5910 &stack_allocated_debug_message_dispatch_barriers;
5912 debug_message_dispatch_v8_thread.Start();
5913 debug_message_dispatch_debugger_thread.Start();
5915 debug_message_dispatch_v8_thread.Join();
5916 debug_message_dispatch_debugger_thread.Join();
5920 TEST(DebuggerAgent) {
5922 i::Debugger* debugger = i::Isolate::Current()->debugger();
5925 const int kPort1 = 5858 + FlagDependentPortOffset();
5926 const int kPort2 = 5857 + FlagDependentPortOffset();
5927 const int kPort3 = 5856 + FlagDependentPortOffset();
5930 const int kPortBufferLen = 6;
5931 char port2_str[kPortBufferLen];
5932 OS::SNPrintF(
i::Vector<char>(port2_str, kPortBufferLen),
"%d", kPort2);
5940 debugger->StartAgent(
"test", kPort1);
5941 debugger->StopAgent();
5944 ok = debugger->StartAgent(
"test", kPort2);
5946 debugger->WaitForAgent();
5948 ok = client->
Connect(
"localhost", port2_str);
5954 ok = client->
Receive(&buf, 1) == 1;
5956 debugger->StopAgent();
5962 server->
Bind(kPort3);
5964 debugger->StartAgent(
"test", kPort3);
5965 debugger->StopAgent();
5971 class DebuggerAgentProtocolServerThread :
public i::Thread {
5973 explicit DebuggerAgentProtocolServerThread(
int port)
5974 : Thread(
"DebuggerAgentProtocolServerThread"),
5978 listening_(OS::CreateSemaphore(0)) {
5980 ~DebuggerAgentProtocolServerThread() {
5988 void WaitForListening() { listening_->Wait(); }
5989 char* body() {
return *body_; }
6000 void DebuggerAgentProtocolServerThread::Run() {
6006 ok = server_->Bind(port_);
6010 ok = server_->Listen(1);
6012 listening_->Signal();
6015 client_ = server_->Accept();
6019 i::DebuggerAgentUtil::ReceiveMessage(client_);
6023 TEST(DebuggerAgentProtocolOverflowHeader) {
6026 const int kPort = 5860 + FlagDependentPortOffset();
6027 static const char* kLocalhost =
"localhost";
6030 const int kPortBufferLen = 6;
6031 char port_str[kPortBufferLen];
6038 DebuggerAgentProtocolServerThread* server =
6039 new DebuggerAgentProtocolServerThread(kPort);
6041 server->WaitForListening();
6046 bool ok = client->
Connect(kLocalhost, port_str);
6050 static const int kBufferSize = 1000;
6051 char buffer[kBufferSize];
6054 for (
int i = 0; i < kBufferSize - 4; i++) {
6057 buffer[kBufferSize - 4] =
':';
6058 buffer[kBufferSize - 3] =
'0';
6059 buffer[kBufferSize - 2] =
'\r';
6060 buffer[kBufferSize - 1] =
'\n';
6061 client->
Send(buffer, kBufferSize);
6066 for (
int i = 2; i < kBufferSize - 2; i++) {
6069 buffer[kBufferSize - 2] =
'\r';
6070 buffer[kBufferSize - 1] =
'\n';
6071 client->
Send(buffer, kBufferSize);
6074 const char* content_length_zero_header =
"Content-Length:0\r\n";
6075 client->
Send(content_length_zero_header,
6077 client->
Send(
"\r\n", 2);
6097 EmptyExternalStringResource() { empty_[0] = 0; }
6098 virtual ~EmptyExternalStringResource() {}
6099 virtual size_t length()
const {
return empty_.length(); }
6100 virtual const uint16_t*
data()
const {
return empty_.start(); }
6106 TEST(DebugGetLoadedScripts) {
6108 DebugLocalContext env;
6111 EmptyExternalStringResource source_ext_str;
6116 Handle<i::ExternalTwoByteString> i_source(
6120 i_source->set_resource(0);
6122 bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
6123 i::FLAG_allow_natives_syntax =
true;
6125 "var scripts = %DebugGetLoadedScripts();"
6126 "var count = scripts.length;"
6127 "for (var i = 0; i < count; ++i) {"
6128 " scripts[i].line_ends;"
6131 i::FLAG_allow_natives_syntax = allow_natives_syntax;
6139 TEST(ScriptNameAndData) {
6141 DebugLocalContext env;
6146 frame_script_name = CompileFunction(&env,
6147 frame_script_name_source,
6148 "frame_script_name");
6149 frame_script_data = CompileFunction(&env,
6150 frame_script_data_source,
6151 "frame_script_data");
6152 compiled_script_data = CompileFunction(&env,
6153 compiled_script_data_source,
6154 "compiled_script_data");
6173 CHECK_EQ(1, break_point_hit_count);
6174 CHECK_EQ(
"name", last_script_name_hit);
6175 CHECK_EQ(
"data", last_script_data_hit);
6182 CHECK_EQ(2, break_point_hit_count);
6183 CHECK_EQ(
"name", last_script_name_hit);
6184 CHECK_EQ(
"", last_script_data_hit);
6189 " toString: function() { return this.a + ' ' + this.b; }\n"
6198 CHECK_EQ(3, break_point_hit_count);
6199 CHECK_EQ(
"new name", last_script_name_hit);
6200 CHECK_EQ(
"abc 123", last_script_data_hit);
6205 CHECK_EQ(
"in compile", last_script_data_hit);
6209 CHECK_EQ(4, break_point_hit_count);
6210 CHECK_EQ(
"in compile", last_script_data_hit);
6222 expected_context_data));
6223 message_handler_hit_count++;
6225 static char print_buffer[1000];
6227 Utf16ToAscii(*json, json.length(), print_buffer);
6230 if (IsBreakEventMessage(print_buffer)) {
6231 SendContinueCommand();
6255 CHECK(context_2->GetData()->IsUndefined());
6260 context_1->SetData(data_1);
6261 context_2->SetData(data_2);
6263 CHECK(context_2->GetData()->StrictEquals(data_2));
6266 const char* source =
"function f() { debugger; }";
6271 expected_context = context_1;
6272 expected_context_data = data_1;
6274 f->
Call(context_1->Global(), 0,
NULL);
6281 expected_context = context_2;
6282 expected_context_data = data_2;
6284 f->
Call(context_2->Global(), 0,
NULL);
6288 CHECK_GT(message_handler_hit_count, 4);
6291 CheckDebuggerUnloaded();
6296 static int message_handler_break_hit_count = 0;
6300 message_handler_break_hit_count++;
6301 if (message_handler_break_hit_count == 1) {
6309 SendContinueCommand();
6315 TEST(DebugBreakInMessageHandler) {
6317 DebugLocalContext env;
6322 const char* script =
"function f() { debugger; g(); } function g() { }";
6332 CHECK_EQ(2, message_handler_break_hit_count);
6335 CHECK_EQ(2, message_handler_break_hit_count);
6339 #ifndef V8_INTERPRETED_REGEXP
6342 static void DebugEventDebugBreak(
6349 break_point_hit_count++;
6352 if (!frame_function_name.
IsEmpty()) {
6359 last_function_hit[0] =
'\0';
6363 function_name->WriteAscii(last_function_hit);
6368 if (break_point_hit_count < 20) {
6375 TEST(RegExpDebugBreak) {
6378 DebugLocalContext env;
6381 frame_function_name = CompileFunction(&env,
6382 frame_function_name_source,
6383 "frame_function_name");
6387 const char* script =
6388 "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n"
6389 "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }";
6399 result = f->
Call(env->Global(), argc, argv);
6403 CHECK_EQ(1, break_point_hit_count);
6406 #endif // V8_INTERPRETED_REGEXP
6410 static void ExecuteScriptForContextCheck() {
6418 CHECK(context_1->GetData()->IsUndefined());
6422 context_1->SetData(data_1);
6423 CHECK(context_1->GetData()->StrictEquals(data_1));
6426 const char* source =
"function f() { eval('debugger;'); }";
6431 expected_context = context_1;
6432 expected_context_data = data_1;
6434 f->
Call(context_1->Global(), 0,
NULL);
6443 TEST(EvalContextData) {
6447 ExecuteScriptForContextCheck();
6450 CHECK_GT(message_handler_hit_count, 2);
6452 CheckDebuggerUnloaded();
6456 static bool sent_eval =
false;
6457 static int break_count = 0;
6458 static int continue_command_send_count = 0;
6461 static void DebugEvalContextCheckMessageHandler(
6465 expected_context_data));
6466 message_handler_hit_count++;
6468 static char print_buffer[1000];
6470 Utf16ToAscii(*json, json.length(), print_buffer);
6472 if (IsBreakEventMessage(print_buffer)) {
6477 const int kBufferSize = 1000;
6479 const char* eval_command =
6481 "\"type\":\"request\","
6482 "\"command\":\"evaluate\","
6483 "\"arguments\":{\"expression\":\"debugger;\","
6484 "\"global\":true,\"disable_break\":false}}";
6491 SendContinueCommand();
6492 continue_command_send_count++;
6494 }
else if (IsEvaluateResponseMessage(print_buffer) &&
6495 continue_command_send_count < 2) {
6498 SendContinueCommand();
6499 continue_command_send_count++;
6506 TEST(NestedBreakEventContextData) {
6509 message_handler_hit_count = 0;
6512 ExecuteScriptForContextCheck();
6515 CHECK_GT(message_handler_hit_count, 3);
6520 CheckDebuggerUnloaded();
6525 int script_collected_count = 0;
6532 script_collected_count++;
6538 TEST(ScriptCollectedEvent) {
6539 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
6540 break_point_hit_count = 0;
6541 script_collected_count = 0;
6543 DebugLocalContext env;
6546 debug->GetLoadedScripts();
6550 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
6552 script_collected_count = 0;
6562 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
6564 CHECK_EQ(2, script_collected_count);
6567 CheckDebuggerUnloaded();
6572 int script_collected_message_count = 0;
6576 script_collected_message_count++;
6585 TEST(ScriptCollectedEventContext) {
6586 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
6587 script_collected_message_count = 0;
6591 DebugLocalContext env;
6594 debug->GetLoadedScripts();
6598 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
6609 HEAP->CollectAllGarbage(Heap::kNoGCFlags);
6611 CHECK_EQ(2, script_collected_message_count);
6618 int after_compile_message_count = 0;
6623 after_compile_message_count++;
6625 SendContinueCommand();
6633 TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
6635 DebugLocalContext env;
6636 after_compile_message_count = 0;
6637 const char* script =
"var a=1";
6649 CheckDebuggerUnloaded();
6652 CHECK_EQ(2, after_compile_message_count);
6657 TEST(BreakMessageWhenMessageHandlerIsReset) {
6659 DebugLocalContext env;
6660 after_compile_message_count = 0;
6661 const char* script =
"function f() {};";
6675 CheckDebuggerUnloaded();
6678 CHECK_EQ(1, after_compile_message_count);
6682 static int exception_event_count = 0;
6685 exception_event_count++;
6686 SendContinueCommand();
6692 TEST(ExceptionMessageWhenMessageHandlerIsReset) {
6694 DebugLocalContext env;
6697 ChangeBreakOnException(
false,
true);
6699 exception_event_count = 0;
6700 const char* script =
"function f() {throw new Error()};";
6713 CheckDebuggerUnloaded();
6715 CHECK_EQ(1, exception_event_count);
6721 TEST(ProvisionalBreakpointOnLineOutOfRange) {
6723 DebugLocalContext env;
6725 const char* script =
"function f() {};";
6726 const char* resource_name =
"test_resource";
6730 int sbp1 = SetScriptBreakPointByNameFromJS(resource_name, 3,
6732 int sbp2 = SetScriptBreakPointByNameFromJS(resource_name, 5, 5);
6734 after_compile_message_count = 0;
6748 CHECK_EQ(1, after_compile_message_count);
6750 ClearBreakPointFromJS(sbp1);
6751 ClearBreakPointFromJS(sbp2);
6760 break_point_hit_count++;
6765 SendContinueCommand();
6769 bool is_debug_break = isolate->
stack_guard()->IsDebugBreak();
6777 if (is_debug_break) {
6788 TEST(NoDebugBreakInAfterCompileMessageHandler) {
6790 DebugLocalContext env;
6799 const char* src =
"function f() { eval('var x = 10;'); } ";
6803 CHECK_EQ(1, break_point_hit_count);
6809 CHECK_EQ(2, break_point_hit_count);
6813 CheckDebuggerUnloaded();
6817 static int counting_message_handler_counter;
6820 counting_message_handler_counter++;
6824 TEST(ProcessDebugMessages) {
6826 DebugLocalContext env;
6828 counting_message_handler_counter = 0;
6832 const int kBufferSize = 1000;
6834 const char* scripts_command =
6836 "\"type\":\"request\","
6837 "\"command\":\"scripts\"}";
6842 CHECK_EQ(0, counting_message_handler_counter);
6845 CHECK_GE(counting_message_handler_counter, 1);
6847 counting_message_handler_counter = 0;
6851 CHECK_EQ(0, counting_message_handler_counter);
6854 CHECK_GE(counting_message_handler_counter, 2);
6858 CheckDebuggerUnloaded();
6862 struct BacktraceData {
6863 static int frame_counter;
6865 char print_buffer[1000];
6867 Utf16ToAscii(*json, json.length(), print_buffer, 1000);
6869 if (strstr(print_buffer,
"backtrace") ==
NULL) {
6872 frame_counter = GetTotalFramesInt(print_buffer);
6876 int BacktraceData::frame_counter;
6882 DebugLocalContext env;
6886 const int kBufferSize = 1000;
6888 const char* scripts_command =
6890 "\"type\":\"request\","
6891 "\"command\":\"backtrace\"}";
6894 BacktraceData::frame_counter = -10;
6897 CHECK_EQ(BacktraceData::frame_counter, 0);
6903 BacktraceData::frame_counter = -10;
6906 CHECK_EQ(BacktraceData::frame_counter, 1);
6910 CheckDebuggerUnloaded();
6916 DebugLocalContext env;
6921 "function runTest(mirror) {"
6922 " return mirror.isString() && (mirror.length() == 5);"
6925 "runTest;"))->Run());
6932 TEST(DebugBreakFunctionApply) {
6934 DebugLocalContext env;
6939 "function baz(x) { }"
6940 "function bar(x) { baz(); }"
6941 "function foo(){ bar.apply(this, [1]); }",
6952 break_point_hit_count = 0;
6953 max_break_point_hit_count = 10000;
6957 CHECK_GT(break_point_hit_count, 1);
6960 CheckDebuggerUnloaded();
6975 CHECK(current == debugee_context);
6976 CHECK(current != debugger_context);
6978 CHECK(calling == debugee_context);
6979 CHECK(calling != debugger_context);
6987 static void DebugEventGetAtgumentPropertyValue(
6993 break_point_hit_count++;
6996 "(function(exec_state) {\n"
6997 " return (exec_state.frame(0).argumentValue(0).property('a').\n"
6998 " value().value() == 1);\n"
7008 TEST(CallingContextIsNotDebugContext) {
7009 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
7012 DebugLocalContext env;
7023 NamedGetterWithCallingContextCheck);
7025 named->NewInstance());
7033 "function bar(x) { debugger; }"
7034 "function foo(){ bar(obj); }",
7037 break_point_hit_count = 0;
7039 CHECK_EQ(1, break_point_hit_count);
7044 CheckDebuggerUnloaded();
7048 TEST(DebugContextIsPreservedBetweenAccesses) {
7063 TEST(DebugEventContext) {
7067 expected_callback_data);
7072 expected_context.
Clear();
7075 CheckDebuggerUnloaded();
7079 static void* expected_break_data;
7080 static bool was_debug_break_called;
7081 static bool was_debug_event_called;
7085 was_debug_event_called =
true;
7087 was_debug_break_called =
true;
7093 TEST(DebugEventBreakData) {
7095 DebugLocalContext env;
7098 TestClientData::constructor_call_counter = 0;
7099 TestClientData::destructor_call_counter = 0;
7101 expected_break_data =
NULL;
7102 was_debug_event_called =
false;
7103 was_debug_break_called =
false;
7106 CHECK(was_debug_event_called);
7107 CHECK(!was_debug_break_called);
7109 TestClientData* data1 =
new TestClientData();
7110 expected_break_data = data1;
7111 was_debug_event_called =
false;
7112 was_debug_break_called =
false;
7115 CHECK(was_debug_event_called);
7116 CHECK(!was_debug_break_called);
7118 expected_break_data =
NULL;
7119 was_debug_event_called =
false;
7120 was_debug_break_called =
false;
7123 CHECK(!was_debug_event_called);
7124 CHECK(was_debug_break_called);
7126 TestClientData* data2 =
new TestClientData();
7127 expected_break_data = data2;
7128 was_debug_event_called =
false;
7129 was_debug_break_called =
false;
7133 CHECK(was_debug_event_called);
7134 CHECK(was_debug_break_called);
7136 CHECK_EQ(2, TestClientData::constructor_call_counter);
7137 CHECK_EQ(TestClientData::constructor_call_counter,
7138 TestClientData::destructor_call_counter);
7141 CheckDebuggerUnloaded();
7144 static bool debug_event_break_deoptimize_done =
false;
7151 if (!frame_function_name.
IsEmpty()) {
7156 frame_function_name->
Call(exec_state, argc, argv);
7161 function_name->WriteAscii(fn);
7162 if (strcmp(fn,
"bar") == 0) {
7164 debug_event_break_deoptimize_done =
true;
7176 TEST(DeoptimizeDuringDebugBreak) {
7178 DebugLocalContext env;
7182 frame_function_name = CompileFunction(&env,
7183 frame_function_name_source,
7184 "frame_function_name");
7202 CHECK(debug_event_break_deoptimize_done);
7208 static void DebugEventBreakWithOptimizedStack(
v8::DebugEvent event,
7213 if (!frame_function_name.
IsEmpty()) {
7214 for (
int i = 0; i < 2; i++) {
7219 frame_function_name->
Call(exec_state, argc, argv);
7224 result = frame_argument_name->
Call(exec_state, argc, argv);
7225 CHECK(result->IsString());
7234 result = frame_argument_value->
Call(exec_state, argc, argv);
7235 CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i));
7237 result = frame_local_name->
Call(exec_state, argc, argv);
7238 CHECK(result->IsString());
7247 result = frame_local_value->
Call(exec_state, argc, argv);
7248 CHECK(result->IsUndefined() || (result->Int32Value() == 42));
7263 TEST(DebugBreakStackInspection) {
7265 DebugLocalContext env;
7267 frame_function_name =
7268 CompileFunction(&env, frame_function_name_source,
"frame_function_name");
7269 frame_argument_name =
7270 CompileFunction(&env, frame_argument_name_source,
"frame_argument_name");
7271 frame_argument_value = CompileFunction(&env,
7272 frame_argument_value_source,
7273 "frame_argument_value");
7275 CompileFunction(&env, frame_local_name_source,
"frame_local_name");
7277 CompileFunction(&env, frame_local_value_source,
"frame_local_value");
7283 env->Global()->Set(v8_str(
"scheduleBreak"), schedule_break);
7286 "function loop(count) {"
7288 " if (count < 1) { scheduleBreak(); loop(count + 1); }"
7296 static void TestDebugBreakInLoop(
const char* loop_head,
7297 const char** loop_bodies,
7298 const char* loop_tail) {
7300 static const int kBreaksPerTest = 100;
7302 for (
int i = 0; loop_bodies[i] !=
NULL; i++) {
7305 for (
int j = 0; j < 11; j++) {
7306 break_point_hit_count_deoptimize = j;
7308 break_point_hit_count_deoptimize = kBreaksPerTest;
7311 break_point_hit_count = 0;
7312 max_break_point_hit_count = kBreaksPerTest;
7313 terminate_after_max_break_point_hit =
true;
7315 EmbeddedVector<char, 1024> buffer;
7316 OS::SNPrintF(buffer,
7317 "function f() {%s%s%s}",
7318 loop_head, loop_bodies[i], loop_tail);
7321 CompileRun(buffer.start());
7328 CHECK_EQ(kBreaksPerTest, break_point_hit_count);
7336 TEST(DebugBreakLoop) {
7338 DebugLocalContext env;
7344 frame_count = CompileFunction(&env, frame_count_source,
"frame_count");
7346 CompileRun(
"var a = 1;");
7347 CompileRun(
"function g() { }");
7348 CompileRun(
"function h() { }");
7350 const char* loop_bodies[] = {
7353 "if (a == 0) { g() }",
7354 "if (a == 1) { g() }",
7355 "if (a == 0) { g() } else { h() }",
7356 "if (a == 0) { continue }",
7357 "if (a == 1) { continue }",
7358 "switch (a) { case 1: g(); }",
7359 "switch (a) { case 1: continue; }",
7360 "switch (a) { case 1: g(); break; default: h() }",
7361 "switch (a) { case 1: continue; break; default: h() }",
7365 TestDebugBreakInLoop(
"while (true) {", loop_bodies,
"}");
7366 TestDebugBreakInLoop(
"while (a == 1) {", loop_bodies,
"}");
7368 TestDebugBreakInLoop(
"do {", loop_bodies,
"} while (true)");
7369 TestDebugBreakInLoop(
"do {", loop_bodies,
"} while (a == 1)");
7371 TestDebugBreakInLoop(
"for (;;) {", loop_bodies,
"}");
7372 TestDebugBreakInLoop(
"for (;a == 1;) {", loop_bodies,
"}");
7376 CheckDebuggerUnloaded();
7388 int expected_frame_count = 4;
7389 int expected_line_number[] = {1, 4, 7, 12};
7395 int break_id = v8::internal::Isolate::Current()->debug()->break_id();
7398 OS::SNPrintF(script_vector,
"%%GetFrameCount(%d)", break_id);
7402 CHECK_EQ(expected_frame_count, frame_count);
7404 for (
int i = 0; i < frame_count; i++) {
7407 OS::SNPrintF(script_vector,
"%%GetFrameDetails(%d, %d)[5]", break_id, i);
7417 TEST(DebugBreakInline) {
7418 i::FLAG_allow_natives_syntax =
true;
7420 DebugLocalContext env;
7421 const char* source =
7422 "function debug(b) { \n"
7423 " if (b) debugger; \n"
7425 "function f(b) { \n"
7428 "function g(b) { \n"
7433 "%OptimizeFunctionOnNextCall(g); \n"
7437 inline_script->
Run();
7446 PrepareStep(StepNext);
7451 static void RunScriptInANewCFrame(
const char* source) {
7458 TEST(Regress131642) {
7468 DebugLocalContext env;
7474 const char* script_1 =
"debugger; throw new Error();";
7475 RunScriptInANewCFrame(script_1);
7478 const char* script_2 =
"[0].forEach(function() { });";
7479 CompileRun(script_2);
7496 TEST(DebuggerCreatesContextIffActive) {
7498 DebugLocalContext env;
7502 CompileRun(
"debugger;");
7506 CompileRun(
"debugger;");
7513 TEST(LiveEditEnabled) {
7514 v8::internal::FLAG_allow_natives_syntax =
true;
7518 CompileRun(
"%LiveEditCompareStrings('', '')");
7522 TEST(LiveEditDisabled) {
7523 v8::internal::FLAG_allow_natives_syntax =
true;
7527 CompileRun(
"%LiveEditCompareStrings('', '')");
7531 #endif // ENABLE_DEBUGGER_SUPPORT
static Local< Context > GetCurrent()
virtual DebugEvent GetEvent() const =0
static void SetLiveEditEnabled(bool enable, Isolate *isolate=NULL)
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
virtual bool WillStartRunning() const =0
#define CHECK_EQ(expected, value)
V8EXPORT bool IsTrue() const
static bool IsExecutionTerminating(Isolate *isolate=NULL)
static Local< FunctionTemplate > New(InvocationCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >())
Handle< Boolean > V8EXPORT True()
Local< Value > Exception() const
V8EXPORT bool StrictEquals(Handle< Value > that) const
V8EXPORT Local< Value > Get(Handle< Value > key)
static Smi * FromInt(int value)
void V8EXPORT RegisterExtension(Extension *extension)
Local< Object > NewInstance()
static V8EXPORT Local< String > New(const char *data, int length=-1)
void SetData(Handle< String > data)
virtual bool Shutdown()=0
static ExternalTwoByteString * cast(Object *obj)
Local< ObjectTemplate > InstanceTemplate()
virtual Handle< Value > GetCallbackData() const =0
static Local< Context > GetDebugContext()
static Handle< T > Cast(Handle< S > that)
virtual int Receive(char *data, int len) const =0
void SetIndexedPropertyHandler(IndexedPropertyGetter getter, IndexedPropertySetter setter=0, IndexedPropertyQuery query=0, IndexedPropertyDeleter deleter=0, IndexedPropertyEnumerator enumerator=0, Handle< Value > data=Handle< Value >())
virtual DebugEvent GetEvent() const =0
V8EXPORT Local< Value > Call(Handle< Object > recv, int argc, Handle< Value > argv[])
static bool AddMessageListener(MessageCallback that)
static Script * cast(Object *obj)
static void DeoptimizeAll()
V8EXPORT Local< String > ToString() const
virtual bool IsEvent() const =0
virtual ClientData * GetClientData() const =0
void Set(Handle< String > name, Handle< Data > value, PropertyAttribute attributes=None)
static Function * Cast(Value *obj)
virtual int Send(const char *data, int len) const =0
virtual const uint16_t * data() const =0
StackGuard * stack_guard()
static void DebugBreakForCommand(ClientData *data=NULL, Isolate *isolate=NULL)
static Local< Script > New(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
void V8_Fatal(const char *file, int line, const char *format,...)
static bool SetDebugEventListener(EventCallback that, Handle< Value > data=Handle< Value >())
virtual size_t length() const =0
double StringToInt(UnicodeCache *unicode_cache, String *str, int radix)
static Local< ObjectTemplate > New()
static void SetHostDispatchHandler(HostDispatchHandler handler, int period=100)
virtual Handle< Object > GetExecutionState() const =0
static const int kNoGCFlags
void SetAccessor(Handle< String > name, AccessorGetter getter, AccessorSetter setter=0, Handle< Value > data=Handle< Value >(), AccessControl settings=DEFAULT, PropertyAttribute attribute=None, Handle< AccessorSignature > signature=Handle< AccessorSignature >())
Handle< Object > SetProperty(Handle< Object > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage message
static void TerminateExecution(int thread_id)
V8EXPORT int32_t Int32Value() const
static void RemoveMessageListeners(MessageCallback that)
V8EXPORT bool SetHiddenValue(Handle< String > key, Handle< Value > value)
static const int kMakeHeapIterableMask
virtual Handle< String > GetJSON() const =0
virtual bool Connect(const char *host, const char *port)=0
static Local< Context > GetCalling()
V8EXPORT bool IsFunction() const
#define CHECK_NE(unexpected, value)
static void SetMessageHandler(MessageHandler handler, bool message_handler_thread=false)
Handle< Boolean > V8EXPORT False()
void SetHiddenPrototype(bool value)
int StrLength(const char *string)
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
void SetNamedPropertyHandler(NamedPropertyGetter getter, NamedPropertySetter setter=0, NamedPropertyQuery query=0, NamedPropertyDeleter deleter=0, NamedPropertyEnumerator enumerator=0, Handle< Value > data=Handle< Value >())
static Local< T > Cast(Local< S > that)
static void SetMessageHandler2(MessageHandler2 handler)
int GetScriptLineNumber(Handle< Script > script, int code_pos)
static void SetDebugMessageDispatchHandler(DebugMessageDispatchHandler handler, bool provide_locker=false)
void Continue(InterruptFlag after_what)
V8EXPORT bool IsNumber() const
virtual ClientData * GetClientData() const =0
Local< Function > GetFunction()
static bool SetDebugEventListener2(EventCallback2 that, Handle< Value > data=Handle< Value >())
static V8EXPORT Local< Integer > New(int32_t value)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
virtual bool Bind(const int port)=0
static Local< Value > Call(v8::Handle< v8::Function > fun, Handle< Value > data=Handle< Value >())
Handle< Primitive > V8EXPORT Undefined()
static V8EXPORT Local< Number > New(double value)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
virtual Handle< Context > GetEventContext() const =0
virtual Handle< Context > GetEventContext() const =0
static void SendCommand(const uint16_t *command, int length, ClientData *client_data=NULL, Isolate *isolate=NULL)
static void DebugBreak(Isolate *isolate=NULL)
static V8EXPORT Local< String > NewExternal(ExternalStringResource *resource)
static Local< Value > GetMirror(v8::Handle< v8::Value > obj)
#define SMALL_STRING_BUFFER_SIZE
static void ProcessDebugMessages()
void CheckNonEqualsHelper(const char *file, int line, const char *unexpected_source, v8::Handle< v8::Value > unexpected, const char *value_source, v8::Handle< v8::Value > value)
void CheckEqualsHelper(const char *file, int line, const char *expected_source, v8::Handle< v8::Value > expected, const char *value_source, v8::Handle< v8::Value > value)
static V8EXPORT Local< Object > New()
int CountNativeContexts()
static Socket * CreateSocket()
V8EXPORT bool Set(Handle< Value > key, Handle< Value > value, PropertyAttribute attribs=None)
static JSFunction * cast(Object *obj)