28 #ifdef ENABLE_DEBUGGER_SUPPORT
47 using ::v8::internal::Mutex;
48 using ::v8::internal::LockGuard;
49 using ::v8::internal::ConditionVariable;
50 using ::v8::internal::Semaphore;
51 using ::v8::internal::EmbeddedVector;
53 using ::v8::internal::OS;
54 using ::v8::internal::Handle;
55 using ::v8::internal::Heap;
56 using ::v8::internal::JSGlobalProxy;
57 using ::v8::internal::Code;
58 using ::v8::internal::Debug;
59 using ::v8::internal::Debugger;
60 using ::v8::internal::CommandMessage;
61 using ::v8::internal::CommandMessageQueue;
63 using ::v8::internal::StepAction;
64 using ::v8::internal::StepIn;
65 using ::v8::internal::StepNext;
66 using ::v8::internal::StepOut;
67 using ::v8::internal::Vector;
71 #define SMALL_STRING_BUFFER_SIZE 80
77 class DebugLocalContext {
79 inline DebugLocalContext(
84 : scope_(
CcTest::isolate()),
86 v8::Context::New(
CcTest::isolate(),
92 inline ~DebugLocalContext() {
96 inline v8::Context* operator->() {
return *context_; }
97 inline v8::Context* operator*() {
return *context_; }
98 inline v8::Isolate* GetIsolate() {
return context_->GetIsolate(); }
99 inline bool IsReady() {
return !context_.IsEmpty(); }
104 v8::internal::Debug* debug = isolate->debug();
107 debug->debug_context()->set_security_token(
110 Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
112 Handle<v8::internal::String> debug_string =
115 Handle<Object>(debug->debug_context()->global_proxy(), isolate),
132 const char* function_name) {
143 const char* function_name) {
155 Handle<v8::internal::SharedFunctionInfo> shared(f->shared());
156 return Debug::HasDebugInfo(shared);
162 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun,
int position) {
163 static int break_point = 0;
165 v8::internal::Debug* debug = isolate->debug();
166 debug->SetBreakPoint(
183 static int SetBreakPointFromJS(
v8::Isolate* isolate,
184 const char* function_name,
185 int line,
int position) {
186 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
188 "debug.Debug.setBreakPoint(%s,%d,%d)",
189 function_name, line, position);
197 static int SetScriptBreakPointByIdFromJS(
v8::Isolate* isolate,
int script_id,
198 int line,
int column) {
199 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
203 "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
204 script_id, line, column);
208 "debug.Debug.setScriptBreakPointById(%d,%d)",
218 return value->Int32Value();
225 static int SetScriptBreakPointByNameFromJS(
v8::Isolate* isolate,
226 const char* script_name,
int line,
228 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
232 "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
233 script_name, line, column);
237 "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
247 return value->Int32Value();
253 static void ClearBreakPoint(
int break_point) {
255 v8::internal::Debug* debug = isolate->debug();
256 debug->ClearBreakPoint(
262 static void ClearBreakPointFromJS(
v8::Isolate* isolate,
263 int break_point_number) {
264 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
266 "debug.Debug.clearBreakPoint(%d)",
273 static void EnableScriptBreakPointFromJS(
v8::Isolate* isolate,
274 int break_point_number) {
275 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
277 "debug.Debug.enableScriptBreakPoint(%d)",
284 static void DisableScriptBreakPointFromJS(
v8::Isolate* isolate,
285 int break_point_number) {
286 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
288 "debug.Debug.disableScriptBreakPoint(%d)",
295 static void ChangeScriptBreakPointConditionFromJS(
v8::Isolate* isolate,
296 int break_point_number,
297 const char* condition) {
298 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
300 "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
301 break_point_number, condition);
307 static void ChangeScriptBreakPointIgnoreCountFromJS(
v8::Isolate* isolate,
308 int break_point_number,
310 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
312 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
313 break_point_number, ignoreCount);
320 static void ChangeBreakOnException(
bool caught,
bool uncaught) {
322 debug->ChangeBreakOnException(v8::internal::BreakException, caught);
323 debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
328 static void ChangeBreakOnExceptionFromJS(
v8::Isolate* isolate,
bool caught,
342 isolate,
"debug.Debug.setBreakOnUncaughtException()"))->Run();
346 isolate,
"debug.Debug.clearBreakOnUncaughtException()"))->Run();
352 static void PrepareStep(StepAction step_action) {
354 debug->PrepareStep(step_action, 1, StackFrame::NO_ID);
364 Handle<FixedArray> GetDebuggedFunctions() {
367 v8::internal::DebugInfoListNode* node = debug->debug_info_list_;
377 Handle<FixedArray> debugged_functions =
383 debugged_functions->set(count++, *node->debug_info());
387 return debugged_functions;
392 void CheckDebuggerUnloaded(
bool check_functions) {
404 for (HeapObject*
obj = iterator.next();
obj !=
NULL;
obj = iterator.next()) {
410 if (check_functions) {
411 if (
obj->IsJSFunction()) {
413 for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) {
414 RelocInfo::Mode rmode = it.rinfo()->rmode();
415 if (RelocInfo::IsCodeTarget(rmode)) {
416 CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address()));
417 }
else if (RelocInfo::IsJSReturn(rmode)) {
418 CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo()));
427 void ForceUnloadDebugger() {
437 static void CheckDebuggerUnloaded(
bool check_functions =
false) {
441 v8::internal::CheckDebuggerUnloaded(check_functions);
447 class TestBreakLocationIterator:
public v8::internal::BreakLocationIterator {
449 explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info)
450 : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {}
453 return reloc_iterator_original_;
460 void CheckDebugBreakFunction(DebugLocalContext* env,
461 const char* source,
const char*
name,
462 int position, v8::internal::RelocInfo::Mode
mode,
468 *CompileFunction(env, source, name));
469 int bp = SetBreakPoint(fun, position);
472 Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
473 CHECK(Debug::HasDebugInfo(shared));
474 TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
475 it1.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED);
476 v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode();
477 if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
478 actual_mode = v8::internal::RelocInfo::CODE_TARGET;
481 if (mode != v8::internal::RelocInfo::JS_RETURN) {
483 Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
485 CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo()));
491 CHECK(!debug->HasDebugInfo(shared));
492 CHECK(debug->EnsureDebugInfo(shared, fun));
493 TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
494 it2.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED);
495 actual_mode = it2.it()->rinfo()->rmode();
496 if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
497 actual_mode = v8::internal::RelocInfo::CODE_TARGET;
500 if (mode == v8::internal::RelocInfo::JS_RETURN) {
501 CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
514 const char* frame_function_name_source =
515 "function frame_function_name(exec_state, frame_number) {"
516 " return exec_state.frame(frame_number).func().name();"
523 const char* frame_argument_name_source =
524 "function frame_argument_name(exec_state, frame_number) {"
525 " return exec_state.frame(frame_number).argumentName(0);"
532 const char* frame_argument_value_source =
533 "function frame_argument_value(exec_state, frame_number) {"
534 " return exec_state.frame(frame_number).argumentValue(0).value_;"
541 const char* frame_local_name_source =
542 "function frame_local_name(exec_state, frame_number) {"
543 " return exec_state.frame(frame_number).localName(0);"
550 const char* frame_local_value_source =
551 "function frame_local_value(exec_state, frame_number) {"
552 " return exec_state.frame(frame_number).localValue(0).value_;"
559 const char* frame_source_line_source =
560 "function frame_source_line(exec_state) {"
561 " return exec_state.frame(0).sourceLine();"
568 const char* frame_source_column_source =
569 "function frame_source_column(exec_state) {"
570 " return exec_state.frame(0).sourceColumn();"
577 const char* frame_script_name_source =
578 "function frame_script_name(exec_state) {"
579 " return exec_state.frame(0).func().script().name();"
585 static const char* frame_count_source =
586 "function frame_count(exec_state) {"
587 " return exec_state.frameCount();"
593 char last_function_hit[80];
596 char last_script_name_hit[80];
599 int last_source_line = -1;
600 int last_source_column = -1;
603 int break_point_hit_count = 0;
604 int break_point_hit_count_deoptimize = 0;
605 static void DebugEventBreakPointHitCount(
610 Debug* debug = isolate->debug();
616 break_point_hit_count++;
617 if (!frame_function_name.
IsEmpty()) {
626 last_function_hit[0] =
'\0';
630 function_name->
WriteUtf8(last_function_hit);
634 if (!frame_source_line.
IsEmpty()) {
644 if (!frame_source_column.
IsEmpty()) {
654 if (!frame_script_name.
IsEmpty()) {
661 last_script_name_hit[0] =
'\0';
665 script_name->
WriteUtf8(last_script_name_hit);
671 if (break_point_hit_count == break_point_hit_count_deoptimize) {
680 int exception_hit_count = 0;
681 int uncaught_exception_hit_count = 0;
682 int last_js_stack_height = -1;
684 static void DebugEventCounterClear() {
685 break_point_hit_count = 0;
686 exception_hit_count = 0;
687 uncaught_exception_hit_count = 0;
690 static void DebugEventCounter(
702 break_point_hit_count++;
704 exception_hit_count++;
713 uncaught_exception_hit_count++;
720 static const int kArgc = 1;
737 struct EvaluateCheck {
744 struct EvaluateCheck* checks =
NULL;
747 const char* evaluate_check_source =
748 "function evaluate_check(exec_state, expr, expected) {"
749 " return exec_state.frame(0).evaluate(expr).value() === expected;"
754 static void DebugEventEvaluate(
763 for (
int i = 0; checks[i].expr !=
NULL; i++) {
770 evaluate_check_function->
Call(exec_state, argc, argv);
773 V8_Fatal(__FILE__, __LINE__,
"%s != %s", checks[i].expr, *utf8);
781 int debug_event_remove_break_point = 0;
782 static void DebugEventRemoveBreakPoint(
791 break_point_hit_count++;
793 ClearBreakPoint(debug_event_remove_break_point);
800 StepAction step_action = StepIn;
801 static void DebugEventStep(
809 break_point_hit_count++;
810 PrepareStep(step_action);
824 const char* expected_step_sequence =
NULL;
827 static void DebugEventStepSequence(
837 CHECK(break_point_hit_count <
849 expected_step_sequence[break_point_hit_count]);
852 break_point_hit_count++;
853 PrepareStep(step_action);
859 static void DebugEventBreakPointCollectGarbage(
870 break_point_hit_count++;
871 if (break_point_hit_count % 2 == 0) {
884 static void DebugEventBreak(
893 break_point_hit_count++;
907 int max_break_point_hit_count = 0;
908 bool terminate_after_max_break_point_hit =
false;
909 static void DebugEventBreakMax(
915 v8::internal::Debug* debug = isolate->debug();
920 if (break_point_hit_count < max_break_point_hit_count) {
922 break_point_hit_count++;
927 static const int kArgc = 1;
931 frame_count->
Call(exec_state, kArgc, argv);
938 }
else if (terminate_after_max_break_point_hit) {
945 if (break_point_hit_count == break_point_hit_count_deoptimize) {
956 int message_callback_count = 0;
958 static void MessageCallbackCountClear() {
959 message_callback_count = 0;
964 message_callback_count++;
974 using ::v8::internal::Builtins;
975 using ::v8::internal::Isolate;
976 DebugLocalContext env;
979 CheckDebugBreakFunction(&env,
980 "function f1(){}",
"f1",
982 v8::internal::RelocInfo::JS_RETURN,
984 CheckDebugBreakFunction(&env,
985 "function f2(){x=1;}",
"f2",
987 v8::internal::RelocInfo::CODE_TARGET,
989 Builtins::kStoreIC_DebugBreak));
990 CheckDebugBreakFunction(&env,
991 "function f3(){var a=x;}",
"f3",
993 v8::internal::RelocInfo::CODE_TARGET,
995 Builtins::kLoadIC_DebugBreak));
1001 #if !defined (__arm__) && !defined(__thumb__)
1002 CheckDebugBreakFunction(
1004 "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
1007 v8::internal::RelocInfo::CODE_TARGET,
1009 Builtins::kKeyedStoreIC_DebugBreak));
1010 CheckDebugBreakFunction(
1012 "function f5(){var index='propertyName'; var a={}; return a[index];}",
1015 v8::internal::RelocInfo::CODE_TARGET,
1017 Builtins::kKeyedLoadIC_DebugBreak));
1020 CheckDebugBreakFunction(
1022 "function f6(a){return a==null;}",
1025 v8::internal::RelocInfo::CODE_TARGET,
1027 Builtins::kCompareNilIC_DebugBreak));
1059 DebugLocalContext env;
1063 CompileFunction(&env,
"function foo(){}",
"foo");
1065 CompileFunction(&env,
"function bar(){}",
"bar");
1067 CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1068 CHECK(!HasDebugInfo(foo));
1069 CHECK(!HasDebugInfo(bar));
1071 int bp1 = SetBreakPoint(foo, 0);
1072 CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1073 CHECK(HasDebugInfo(foo));
1074 CHECK(!HasDebugInfo(bar));
1076 int bp2 = SetBreakPoint(bar, 0);
1077 CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length());
1078 CHECK(HasDebugInfo(foo));
1079 CHECK(HasDebugInfo(bar));
1081 ClearBreakPoint(bp1);
1082 CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1083 CHECK(!HasDebugInfo(foo));
1084 CHECK(HasDebugInfo(bar));
1086 ClearBreakPoint(bp2);
1087 CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1088 CHECK(!HasDebugInfo(foo));
1089 CHECK(!HasDebugInfo(bar));
1094 TEST(BreakPointICStore) {
1095 break_point_hit_count = 0;
1096 DebugLocalContext env;
1101 "function foo(){bar=0;}"))->Run();
1107 CHECK_EQ(0, break_point_hit_count);
1110 int bp = SetBreakPoint(foo, 0);
1112 CHECK_EQ(1, break_point_hit_count);
1114 CHECK_EQ(2, break_point_hit_count);
1117 ClearBreakPoint(bp);
1119 CHECK_EQ(2, break_point_hit_count);
1122 CheckDebuggerUnloaded();
1127 TEST(BreakPointICLoad) {
1128 break_point_hit_count = 0;
1129 DebugLocalContext env;
1142 CHECK_EQ(0, break_point_hit_count);
1145 int bp = SetBreakPoint(foo, 0);
1147 CHECK_EQ(1, break_point_hit_count);
1149 CHECK_EQ(2, break_point_hit_count);
1152 ClearBreakPoint(bp);
1154 CHECK_EQ(2, break_point_hit_count);
1157 CheckDebuggerUnloaded();
1162 TEST(BreakPointICCall) {
1163 break_point_hit_count = 0;
1164 DebugLocalContext env;
1170 "function foo(){bar();}"))->Run();
1176 CHECK_EQ(0, break_point_hit_count);
1179 int bp = SetBreakPoint(foo, 0);
1181 CHECK_EQ(1, break_point_hit_count);
1183 CHECK_EQ(2, break_point_hit_count);
1186 ClearBreakPoint(bp);
1188 CHECK_EQ(2, break_point_hit_count);
1191 CheckDebuggerUnloaded();
1196 TEST(BreakPointICCallWithGC) {
1197 break_point_hit_count = 0;
1198 DebugLocalContext env;
1205 "function foo(){return bar();}"))
1212 CHECK_EQ(0, break_point_hit_count);
1215 int bp = SetBreakPoint(foo, 0);
1217 CHECK_EQ(1, break_point_hit_count);
1219 CHECK_EQ(2, break_point_hit_count);
1222 ClearBreakPoint(bp);
1224 CHECK_EQ(2, break_point_hit_count);
1227 CheckDebuggerUnloaded();
1232 TEST(BreakPointConstructCallWithGC) {
1233 break_point_hit_count = 0;
1234 DebugLocalContext env;
1238 "function bar(){ this.x = 1;}"))
1242 "function foo(){return new bar(1).x;}"))->Run();
1248 CHECK_EQ(0, break_point_hit_count);
1251 int bp = SetBreakPoint(foo, 0);
1253 CHECK_EQ(1, break_point_hit_count);
1255 CHECK_EQ(2, break_point_hit_count);
1258 ClearBreakPoint(bp);
1260 CHECK_EQ(2, break_point_hit_count);
1263 CheckDebuggerUnloaded();
1268 TEST(BreakPointReturn) {
1269 break_point_hit_count = 0;
1270 DebugLocalContext env;
1275 frame_source_line = CompileFunction(&env,
1276 frame_source_line_source,
1277 "frame_source_line");
1278 frame_source_column = CompileFunction(&env,
1279 frame_source_column_source,
1280 "frame_source_column");
1291 CHECK_EQ(0, break_point_hit_count);
1294 int bp = SetBreakPoint(foo, 0);
1296 CHECK_EQ(1, break_point_hit_count);
1300 CHECK_EQ(2, break_point_hit_count);
1305 ClearBreakPoint(bp);
1307 CHECK_EQ(2, break_point_hit_count);
1310 CheckDebuggerUnloaded();
1316 int break_point_count,
1318 break_point_hit_count = 0;
1321 CHECK_EQ((i + 1) * break_point_count, break_point_hit_count);
1327 TEST(GCDuringBreakPointProcessing) {
1328 break_point_hit_count = 0;
1329 DebugLocalContext env;
1336 foo = CompileFunction(&env,
"function foo(){bar=0;}",
"foo");
1337 SetBreakPoint(foo, 0);
1338 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1341 foo = CompileFunction(&env,
"bar=1;function foo(){var x=bar;}",
"foo");
1342 SetBreakPoint(foo, 0);
1343 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1346 foo = CompileFunction(&env,
"function bar(){};function foo(){bar();}",
"foo");
1347 SetBreakPoint(foo, 0);
1348 CallWithBreakPoints(env->Global(),
foo, 1, 10);
1351 foo = CompileFunction(&env,
"function foo(){}",
"foo");
1352 SetBreakPoint(foo, 0);
1353 CallWithBreakPoints(env->Global(),
foo, 1, 25);
1356 foo = CompileFunction(&env,
"function foo(){var a;}",
"foo");
1357 SetBreakPoint(foo, 0);
1358 CallWithBreakPoints(env->Global(),
foo, 1, 25);
1361 CheckDebuggerUnloaded();
1369 break_point_hit_count = 0;
1371 for (
int i = 0; i < 3; i++) {
1374 CHECK_EQ(1 + i * 3, break_point_hit_count);
1379 CHECK_EQ(2 + i * 3, break_point_hit_count);
1384 CHECK_EQ(3 + i * 3, break_point_hit_count);
1390 TEST(BreakPointSurviveGC) {
1391 break_point_hit_count = 0;
1392 DebugLocalContext env;
1400 CompileFunction(&env,
"function foo(){}",
"foo");
1401 foo = CompileFunction(&env,
"function foo(){bar=0;}",
"foo");
1402 SetBreakPoint(foo, 0);
1404 CallAndGC(env->Global(),
foo);
1408 CompileFunction(&env,
"function foo(){}",
"foo");
1409 foo = CompileFunction(&env,
"bar=1;function foo(){var x=bar;}",
"foo");
1410 SetBreakPoint(foo, 0);
1412 CallAndGC(env->Global(),
foo);
1416 CompileFunction(&env,
"function foo(){}",
"foo");
1417 foo = CompileFunction(&env,
1418 "function bar(){};function foo(){bar();}",
1420 SetBreakPoint(foo, 0);
1422 CallAndGC(env->Global(),
foo);
1426 CompileFunction(&env,
"function foo(){}",
"foo");
1427 foo = CompileFunction(&env,
"function foo(){}",
"foo");
1428 SetBreakPoint(foo, 0);
1430 CallAndGC(env->Global(),
foo);
1434 CompileFunction(&env,
"function foo(){}",
"foo");
1435 foo = CompileFunction(&env,
"function foo(){var bar=0;}",
"foo");
1436 SetBreakPoint(foo, 0);
1438 CallAndGC(env->Global(),
foo);
1442 CheckDebuggerUnloaded();
1447 TEST(BreakPointThroughJavaScript) {
1448 break_point_hit_count = 0;
1449 DebugLocalContext env;
1457 "function foo(){bar();bar();}"))
1467 CHECK_EQ(0, break_point_hit_count);
1470 int bp1 = SetBreakPointFromJS(env->GetIsolate(),
"foo", 0, 3);
1472 CHECK_EQ(1, break_point_hit_count);
1474 CHECK_EQ(2, break_point_hit_count);
1477 int bp2 = SetBreakPointFromJS(env->GetIsolate(),
"foo", 0, 9);
1479 CHECK_EQ(4, break_point_hit_count);
1481 CHECK_EQ(6, break_point_hit_count);
1484 ClearBreakPointFromJS(env->GetIsolate(), bp2);
1486 CHECK_EQ(7, break_point_hit_count);
1488 CHECK_EQ(8, break_point_hit_count);
1491 ClearBreakPointFromJS(env->GetIsolate(), bp1);
1493 CHECK_EQ(8, break_point_hit_count);
1496 CheckDebuggerUnloaded();
1506 TEST(ScriptBreakPointByNameThroughJavaScript) {
1507 break_point_hit_count = 0;
1508 DebugLocalContext env;
1518 " a = 0; // line 2\n"
1520 " b = 1; // line 4\n"
1528 " b = 2; // line 12\n"
1530 " b = 3; // line 14\n"
1531 " f(); // line 15\n"
1544 break_point_hit_count = 0;
1546 CHECK_EQ(0, break_point_hit_count);
1548 CHECK_EQ(0, break_point_hit_count);
1551 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 12, 0);
1552 break_point_hit_count = 0;
1554 CHECK_EQ(0, break_point_hit_count);
1556 CHECK_EQ(1, break_point_hit_count);
1559 break_point_hit_count = 0;
1560 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
1562 CHECK_EQ(0, break_point_hit_count);
1564 CHECK_EQ(0, break_point_hit_count);
1567 int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 2, 0);
1568 break_point_hit_count = 0;
1570 CHECK_EQ(1, break_point_hit_count);
1572 CHECK_EQ(2, break_point_hit_count);
1575 int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 4, 0);
1576 int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 12, 0);
1577 int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 14, 0);
1578 int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 15, 0);
1579 break_point_hit_count = 0;
1581 CHECK_EQ(2, break_point_hit_count);
1583 CHECK_EQ(7, break_point_hit_count);
1586 break_point_hit_count = 0;
1587 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
1588 ClearBreakPointFromJS(env->GetIsolate(), sbp3);
1589 ClearBreakPointFromJS(env->GetIsolate(), sbp4);
1590 ClearBreakPointFromJS(env->GetIsolate(), sbp5);
1591 ClearBreakPointFromJS(env->GetIsolate(), sbp6);
1593 CHECK_EQ(0, break_point_hit_count);
1595 CHECK_EQ(0, break_point_hit_count);
1598 CheckDebuggerUnloaded();
1610 TEST(ScriptBreakPointByIdThroughJavaScript) {
1611 break_point_hit_count = 0;
1612 DebugLocalContext env;
1622 " a = 0; // line 2\n"
1624 " b = 1; // line 4\n"
1632 " b = 2; // line 12\n"
1634 " b = 3; // line 14\n"
1635 " f(); // line 15\n"
1649 int script_id = script->
GetId();
1652 break_point_hit_count = 0;
1654 CHECK_EQ(0, break_point_hit_count);
1656 CHECK_EQ(0, break_point_hit_count);
1659 int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0);
1660 break_point_hit_count = 0;
1662 CHECK_EQ(0, break_point_hit_count);
1664 CHECK_EQ(1, break_point_hit_count);
1667 break_point_hit_count = 0;
1668 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
1670 CHECK_EQ(0, break_point_hit_count);
1672 CHECK_EQ(0, break_point_hit_count);
1675 int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0);
1676 break_point_hit_count = 0;
1678 CHECK_EQ(1, break_point_hit_count);
1680 CHECK_EQ(2, break_point_hit_count);
1683 int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0);
1684 int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0);
1685 int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0);
1686 int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0);
1687 break_point_hit_count = 0;
1689 CHECK_EQ(2, break_point_hit_count);
1691 CHECK_EQ(7, break_point_hit_count);
1694 break_point_hit_count = 0;
1695 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
1696 ClearBreakPointFromJS(env->GetIsolate(), sbp3);
1697 ClearBreakPointFromJS(env->GetIsolate(), sbp4);
1698 ClearBreakPointFromJS(env->GetIsolate(), sbp5);
1699 ClearBreakPointFromJS(env->GetIsolate(), sbp6);
1701 CHECK_EQ(0, break_point_hit_count);
1703 CHECK_EQ(0, break_point_hit_count);
1706 CheckDebuggerUnloaded();
1719 TEST(EnableDisableScriptBreakPoint) {
1720 break_point_hit_count = 0;
1721 DebugLocalContext env;
1730 " a = 0; // line 1\n"
1741 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 1, 0);
1744 break_point_hit_count = 0;
1746 CHECK_EQ(1, break_point_hit_count);
1748 DisableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1750 CHECK_EQ(1, break_point_hit_count);
1752 EnableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1754 CHECK_EQ(2, break_point_hit_count);
1756 DisableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1758 CHECK_EQ(2, break_point_hit_count);
1765 CHECK_EQ(2, break_point_hit_count);
1767 EnableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1769 CHECK_EQ(3, break_point_hit_count);
1772 CheckDebuggerUnloaded();
1777 TEST(ConditionalScriptBreakPoint) {
1778 break_point_hit_count = 0;
1779 DebugLocalContext env;
1789 " g(count++); // line 2\n"
1792 " var a=x; // line 5\n"
1803 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 5, 0);
1806 break_point_hit_count = 0;
1807 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1,
"false");
1809 CHECK_EQ(0, break_point_hit_count);
1811 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1,
"true");
1812 break_point_hit_count = 0;
1814 CHECK_EQ(1, break_point_hit_count);
1816 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1,
"x % 2 == 0");
1817 break_point_hit_count = 0;
1818 for (
int i = 0; i < 10; i++) {
1821 CHECK_EQ(5, break_point_hit_count);
1828 break_point_hit_count = 0;
1829 for (
int i = 0; i < 10; i++) {
1832 CHECK_EQ(5, break_point_hit_count);
1835 CheckDebuggerUnloaded();
1840 TEST(ScriptBreakPointIgnoreCount) {
1841 break_point_hit_count = 0;
1842 DebugLocalContext env;
1851 " a = 0; // line 1\n"
1862 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 1, 0);
1865 break_point_hit_count = 0;
1866 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1);
1868 CHECK_EQ(0, break_point_hit_count);
1870 CHECK_EQ(1, break_point_hit_count);
1872 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5);
1873 break_point_hit_count = 0;
1874 for (
int i = 0; i < 10; i++) {
1877 CHECK_EQ(5, break_point_hit_count);
1884 break_point_hit_count = 0;
1885 for (
int i = 0; i < 10; i++) {
1888 CHECK_EQ(5, break_point_hit_count);
1891 CheckDebuggerUnloaded();
1896 TEST(ScriptBreakPointReload) {
1897 break_point_hit_count = 0;
1898 DebugLocalContext env;
1909 " a = 0; // line 2\n"
1911 " b = 1; // line 4\n"
1921 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"1", 2, 0);
1929 break_point_hit_count = 0;
1931 CHECK_EQ(1, break_point_hit_count);
1940 break_point_hit_count = 0;
1942 CHECK_EQ(0, break_point_hit_count);
1950 break_point_hit_count = 0;
1952 CHECK_EQ(1, break_point_hit_count);
1955 CheckDebuggerUnloaded();
1960 TEST(ScriptBreakPointMultiple) {
1961 break_point_hit_count = 0;
1962 DebugLocalContext env;
1972 " a = 0; // line 1\n"
1979 " b = 0; // line 1\n"
1986 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 1, 0);
1997 break_point_hit_count = 0;
1999 CHECK_EQ(1, break_point_hit_count);
2000 g->Call(env->Global(), 0,
NULL);
2001 CHECK_EQ(2, break_point_hit_count);
2004 ClearBreakPointFromJS(env->GetIsolate(), sbp);
2007 break_point_hit_count = 0;
2009 CHECK_EQ(0, break_point_hit_count);
2010 g->Call(env->Global(), 0,
NULL);
2011 CHECK_EQ(0, break_point_hit_count);
2014 sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test", 1, 0);
2017 break_point_hit_count = 0;
2019 CHECK_EQ(1, break_point_hit_count);
2020 g->Call(env->Global(), 0,
NULL);
2021 CHECK_EQ(2, break_point_hit_count);
2024 CheckDebuggerUnloaded();
2029 TEST(ScriptBreakPointLineOffset) {
2030 break_point_hit_count = 0;
2031 DebugLocalContext env;
2041 " a = 0; // line 8 as this script has line offset 7\n"
2042 " b = 0; // line 9 as this script has line offset 7\n"
2052 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 8, 0);
2054 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 9, 0);
2062 break_point_hit_count = 0;
2064 CHECK_EQ(2, break_point_hit_count);
2067 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2068 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2071 break_point_hit_count = 0;
2073 CHECK_EQ(0, break_point_hit_count);
2076 sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 9, 0);
2079 break_point_hit_count = 0;
2081 CHECK_EQ(1, break_point_hit_count);
2084 CheckDebuggerUnloaded();
2089 TEST(ScriptBreakPointLine) {
2090 DebugLocalContext env;
2095 frame_function_name = CompileFunction(&env,
2096 frame_function_name_source,
2097 "frame_function_name");
2107 " a = 1; // line 2\n"
2109 " a = 2; // line 4\n"
2110 " /* xx */ function g() { // line 5\n"
2111 " function h() { // line 6\n"
2112 " a = 3; // line 7\n"
2115 " a = 4; // line 10\n"
2117 " a=5; // line 12");
2121 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 0, -1);
2123 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 1, -1);
2125 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 5, -1);
2128 break_point_hit_count = 0;
2139 CHECK_EQ(1, break_point_hit_count);
2144 CHECK_EQ(2, break_point_hit_count);
2149 CHECK_EQ(3, break_point_hit_count);
2153 ClearBreakPointFromJS(env->GetIsolate(), sbp3);
2155 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 6, -1);
2159 CHECK_EQ(4, break_point_hit_count);
2165 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2166 ClearBreakPointFromJS(env->GetIsolate(), sbp4);
2168 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 4, -1);
2169 break_point_hit_count = 0;
2172 CHECK_EQ(0, break_point_hit_count);
2175 break_point_hit_count = 0;
2177 CHECK_EQ(2, break_point_hit_count);
2182 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 12, -1);
2185 break_point_hit_count = 0;
2187 CHECK_EQ(3, break_point_hit_count);
2192 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2193 ClearBreakPointFromJS(env->GetIsolate(), sbp5);
2194 ClearBreakPointFromJS(env->GetIsolate(), sbp6);
2195 break_point_hit_count = 0;
2197 CHECK_EQ(0, break_point_hit_count);
2200 CheckDebuggerUnloaded();
2205 TEST(ScriptBreakPointLineTopLevel) {
2206 DebugLocalContext env;
2215 " a = 1; // line 1\n"
2217 "a = 2; // line 3\n");
2221 CompileRunWithOrigin(script,
"test.html");
2228 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 3, -1);
2231 break_point_hit_count = 0;
2232 f->Call(env->Global(), 0,
NULL);
2233 CHECK_EQ(0, break_point_hit_count);
2236 break_point_hit_count = 0;
2237 CompileRunWithOrigin(script,
"test.html");
2238 CHECK_EQ(1, break_point_hit_count);
2241 break_point_hit_count = 0;
2244 CHECK_EQ(0, break_point_hit_count);
2247 CheckDebuggerUnloaded();
2253 TEST(ScriptBreakPointTopLevelCrash) {
2254 DebugLocalContext env;
2268 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 3, -1);
2271 break_point_hit_count = 0;
2272 CompileRunWithOrigin(script_source,
"test.html");
2273 CHECK_EQ(1, break_point_hit_count);
2277 SetScriptBreakPointByNameFromJS(env->GetIsolate(),
"test.html", 3, -1);
2278 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2279 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2282 CheckDebuggerUnloaded();
2288 TEST(RemoveBreakPointInBreak) {
2289 DebugLocalContext env;
2293 CompileFunction(&env,
"function foo(){a=1;}",
"foo");
2294 debug_event_remove_break_point = SetBreakPoint(foo, 0);
2299 break_point_hit_count = 0;
2300 foo->Call(env->Global(), 0,
NULL);
2301 CHECK_EQ(1, break_point_hit_count);
2303 break_point_hit_count = 0;
2304 foo->Call(env->Global(), 0,
NULL);
2305 CHECK_EQ(0, break_point_hit_count);
2308 CheckDebuggerUnloaded();
2313 TEST(DebuggerStatement) {
2314 break_point_hit_count = 0;
2315 DebugLocalContext env;
2323 "function foo(){debugger;debugger;}"))->Run();
2331 CHECK_EQ(1, break_point_hit_count);
2335 CHECK_EQ(3, break_point_hit_count);
2338 CheckDebuggerUnloaded();
2343 TEST(DebuggerStatementBreakpoint) {
2344 break_point_hit_count = 0;
2345 DebugLocalContext env;
2356 CHECK_EQ(1, break_point_hit_count);
2358 int bp = SetBreakPoint(foo, 0);
2362 CHECK_EQ(2, break_point_hit_count);
2364 ClearBreakPoint(bp);
2366 CheckDebuggerUnloaded();
2372 TEST(DebugEvaluate) {
2373 DebugLocalContext env;
2379 evaluate_check_function = CompileFunction(&env,
2380 evaluate_check_source,
2387 struct EvaluateCheck checks_uu[] = {
2392 struct EvaluateCheck checks_hu[] = {
2397 struct EvaluateCheck checks_hh[] = {
2415 const int foo_break_position_1 = 15;
2416 const int foo_break_position_2 = 29;
2423 int bp = SetBreakPoint(foo, foo_break_position_1);
2425 foo->Call(env->Global(), 0,
NULL);
2429 foo->Call(env->Global(), 1, argv_foo);
2432 ClearBreakPoint(bp);
2433 SetBreakPoint(foo, foo_break_position_2);
2435 foo->Call(env->Global(), 1, argv_foo);
2443 "x = 'Goodbye, world!';"
2444 "function bar(x, b) {"
2446 " function barbar() {"
2447 " y=0; /* To ensure break location.*/"
2450 " debug.Debug.clearAllBreakPoints();"
2455 const int barbar_break_position = 8;
2464 bar->
Call(env->Global(), 2, argv_bar_1);
2473 bar->
Call(env->Global(), 2, argv_bar_2);
2482 bar->
Call(env->Global(), 2, argv_bar_3);
2485 CheckDebuggerUnloaded();
2489 int debugEventCount = 0;
2497 TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
2498 DebugLocalContext env;
2505 "function foo(x) {\n"
2506 " var s = 'String value2';\n"
2512 CompileRun(
"debug.Debug.setBreakPoint(foo, 2, 0, 'true')");
2514 debugEventCount = 0;
2515 env->AllowCodeGenerationFromStrings(
false);
2520 CheckDebuggerUnloaded();
2524 bool checkedDebugEvals =
true;
2544 TEST(DebugEvaluateWithCodeGenerationDisallowed) {
2545 DebugLocalContext env;
2552 "var global = 'Global';\n"
2553 "function foo(x) {\n"
2554 " var local = 'Local';\n"
2556 " return local + x;\n"
2559 checkGlobalEvalFunction = CompileFunction(&env,
2560 "function checkGlobalEval(exec_state) {\n"
2561 " return exec_state.evaluateGlobal('global').value() === 'Global';\n"
2565 checkFrameEvalFunction = CompileFunction(&env,
2566 "function checkFrameEval(exec_state) {\n"
2567 " return exec_state.frame(0).evaluate('local').value() === 'Local';\n"
2570 debugEventCount = 0;
2571 env->AllowCodeGenerationFromStrings(
false);
2575 checkGlobalEvalFunction.
Clear();
2576 checkFrameEvalFunction.
Clear();
2578 CheckDebuggerUnloaded();
2585 int AsciiToUtf16(
const char* input_buffer,
uint16_t* output_buffer) {
2587 for (i = 0; input_buffer[i] !=
'\0'; ++i) {
2589 output_buffer[i] =
static_cast<unsigned char>(input_buffer[i]);
2591 output_buffer[i] = 0;
2599 int Utf16ToAscii(
const uint16_t* input_buffer,
int length,
2600 char* output_buffer,
int output_len = -1) {
2601 if (output_len >= 0) {
2602 if (length > output_len - 1) {
2603 length = output_len - 1;
2607 for (
int i = 0; i < length; ++i) {
2608 output_buffer[i] =
static_cast<char>(input_buffer[i]);
2610 output_buffer[length] =
'\0';
2616 bool GetEvaluateStringResult(
char *
message,
char* buffer,
int buffer_size) {
2617 if (strstr(message,
"\"command\":\"evaluate\"") ==
NULL) {
2620 const char* prefix =
"\"text\":\"";
2621 char* pos1 = strstr(message, prefix);
2625 pos1 += strlen(prefix);
2626 char* pos2 = strchr(pos1,
'"');
2630 Vector<char> buf(buffer, buffer_size);
2631 int len =
static_cast<int>(pos2 - pos1);
2632 if (len > buffer_size - 1) {
2633 len = buffer_size - 1;
2635 OS::StrNCpy(buf, pos1, len);
2636 buffer[buffer_size - 1] =
'\0';
2641 struct EvaluateResult {
2642 static const int kBufferSize = 20;
2643 char buffer[kBufferSize];
2646 struct DebugProcessDebugMessagesData {
2647 static const int kArraySize = 5;
2649 EvaluateResult results[kArraySize];
2654 EvaluateResult* current() {
2655 return &results[counter % kArraySize];
2662 DebugProcessDebugMessagesData process_debug_messages_data;
2664 static void DebugProcessDebugMessagesHandler(
2668 EvaluateResult* array_item = process_debug_messages_data.current();
2670 bool res = GetEvaluateStringResult(*utf8,
2672 EvaluateResult::kBufferSize);
2674 process_debug_messages_data.next();
2681 TEST(DebugEvaluateWithoutStack) {
2684 DebugLocalContext env;
2687 const char* source =
2688 "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
2695 const int kBufferSize = 1000;
2698 const char* command_111 =
"{\"seq\":111,"
2699 "\"type\":\"request\","
2700 "\"command\":\"evaluate\","
2703 " \"expression\":\"v1\",\"disable_break\":true"
2709 const char* command_112 =
"{\"seq\":112,"
2710 "\"type\":\"request\","
2711 "\"command\":\"evaluate\","
2714 " \"expression\":\"getAnimal()\",\"disable_break\":true"
2719 const char* command_113 =
"{\"seq\":113,"
2720 "\"type\":\"request\","
2721 "\"command\":\"evaluate\","
2724 " \"expression\":\"239 + 566\",\"disable_break\":true"
2731 CHECK_EQ(3, process_debug_messages_data.counter);
2733 CHECK_EQ(strcmp(
"Pinguin", process_debug_messages_data.results[0].buffer), 0);
2734 CHECK_EQ(strcmp(
"Capybara", process_debug_messages_data.results[1].buffer),
2736 CHECK_EQ(strcmp(
"805", process_debug_messages_data.results[2].buffer), 0);
2740 CheckDebuggerUnloaded();
2745 TEST(DebugStepLinear) {
2746 DebugLocalContext env;
2751 "function foo(){a=1;b=1;c=1;}",
2755 CompileRun(
"a=0; b=0; c=0; foo();");
2757 SetBreakPoint(foo, 3);
2762 step_action = StepIn;
2763 break_point_hit_count = 0;
2764 foo->Call(env->Global(), 0,
NULL);
2767 CHECK_EQ(4, break_point_hit_count);
2770 CheckDebuggerUnloaded();
2775 SetBreakPoint(foo, 3);
2776 break_point_hit_count = 0;
2777 foo->Call(env->Global(), 0,
NULL);
2780 CHECK_EQ(1, break_point_hit_count);
2783 CheckDebuggerUnloaded();
2788 TEST(DebugStepKeyedLoadLoop) {
2789 DebugLocalContext env;
2799 "function foo(a) {\n"
2801 " var len = a.length;\n"
2802 " for (var i = 0; i < len; i++) {\n"
2812 for (
int i = 0; i < 10; i++) {
2818 const int kArgc = 1;
2820 foo->
Call(env->Global(), kArgc, args);
2823 SetBreakPoint(foo, 3);
2824 step_action = StepNext;
2825 break_point_hit_count = 0;
2826 foo->
Call(env->Global(), kArgc, args);
2829 CHECK_EQ(35, break_point_hit_count);
2832 CheckDebuggerUnloaded();
2837 TEST(DebugStepKeyedStoreLoop) {
2838 DebugLocalContext env;
2848 "function foo(a) {\n"
2849 " var len = a.length;\n"
2850 " for (var i = 0; i < len; i++) {\n"
2860 for (
int i = 0; i < 10; i++) {
2866 const int kArgc = 1;
2868 foo->
Call(env->Global(), kArgc, args);
2871 SetBreakPoint(foo, 3);
2872 step_action = StepNext;
2873 break_point_hit_count = 0;
2874 foo->
Call(env->Global(), kArgc, args);
2877 CHECK_EQ(34, break_point_hit_count);
2880 CheckDebuggerUnloaded();
2885 TEST(DebugStepNamedLoadLoop) {
2886 DebugLocalContext env;
2895 "function foo() {\n"
2898 " for (var i = 0; i < 10; i++) {\n"
2899 " var v = new V(i, i + 1);\n"
2905 "function V(x, y) {\n"
2915 SetBreakPoint(foo, 4);
2916 step_action = StepNext;
2917 break_point_hit_count = 0;
2921 CHECK_EQ(55, break_point_hit_count);
2924 CheckDebuggerUnloaded();
2928 static void DoDebugStepNamedStoreLoop(
int expected) {
2929 DebugLocalContext env;
2938 "function foo() {\n"
2940 " for (var i = 0; i < 10; i++) {\n"
2950 SetBreakPoint(foo, 3);
2951 step_action = StepNext;
2952 break_point_hit_count = 0;
2956 CHECK_EQ(expected, break_point_hit_count);
2959 CheckDebuggerUnloaded();
2964 TEST(DebugStepNamedStoreLoop) {
2965 DoDebugStepNamedStoreLoop(24);
2970 TEST(DebugStepLinearMixedICs) {
2971 DebugLocalContext env;
2979 "function bar() {};"
2982 " var index='name';"
2984 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}",
"foo");
2987 CompileRun(
"a=0; b=0; bar(); foo();");
2989 SetBreakPoint(foo, 0);
2991 step_action = StepIn;
2992 break_point_hit_count = 0;
2996 CHECK_EQ(11, break_point_hit_count);
2999 CheckDebuggerUnloaded();
3004 SetBreakPoint(foo, 0);
3005 break_point_hit_count = 0;
3009 CHECK_EQ(1, break_point_hit_count);
3012 CheckDebuggerUnloaded();
3016 TEST(DebugStepDeclarations) {
3017 DebugLocalContext env;
3025 const char* src =
"function foo() { "
3029 " var d = Math.floor;"
3030 " var e = b + d(1.2);"
3035 SetBreakPoint(foo, 0);
3038 step_action = StepIn;
3039 break_point_hit_count = 0;
3041 CHECK_EQ(6, break_point_hit_count);
3045 CheckDebuggerUnloaded();
3049 TEST(DebugStepLocals) {
3050 DebugLocalContext env;
3058 const char* src =
"function foo() { "
3063 " a = Math.floor(b);"
3068 SetBreakPoint(foo, 0);
3071 step_action = StepIn;
3072 break_point_hit_count = 0;
3074 CHECK_EQ(6, break_point_hit_count);
3078 CheckDebuggerUnloaded();
3083 DebugLocalContext env;
3093 const char* src =
"function foo(x) { "
3102 "a=0; b=0; c=0; d=0; foo()";
3104 SetBreakPoint(foo, 0);
3107 step_action = StepIn;
3108 break_point_hit_count = 0;
3110 foo->
Call(env->Global(), argc, argv_true);
3111 CHECK_EQ(4, break_point_hit_count);
3114 step_action = StepIn;
3115 break_point_hit_count = 0;
3117 foo->
Call(env->Global(), argc, argv_false);
3118 CHECK_EQ(5, break_point_hit_count);
3122 CheckDebuggerUnloaded();
3126 TEST(DebugStepSwitch) {
3127 DebugLocalContext env;
3137 const char* src =
"function foo(x) { "
3152 "a=0; b=0; c=0; d=0; e=0; f=0; foo()";
3154 SetBreakPoint(foo, 0);
3157 step_action = StepIn;
3158 break_point_hit_count = 0;
3160 foo->
Call(env->Global(), argc, argv_1);
3161 CHECK_EQ(6, break_point_hit_count);
3164 step_action = StepIn;
3165 break_point_hit_count = 0;
3167 foo->
Call(env->Global(), argc, argv_2);
3168 CHECK_EQ(5, break_point_hit_count);
3171 step_action = StepIn;
3172 break_point_hit_count = 0;
3174 foo->
Call(env->Global(), argc, argv_3);
3175 CHECK_EQ(7, break_point_hit_count);
3179 CheckDebuggerUnloaded();
3183 TEST(DebugStepWhile) {
3184 DebugLocalContext env;
3194 const char* src =
"function foo(x) { "
3202 SetBreakPoint(foo, 8);
3205 step_action = StepIn;
3206 break_point_hit_count = 0;
3208 foo->
Call(env->Global(), argc, argv_10);
3209 CHECK_EQ(22, break_point_hit_count);
3212 step_action = StepIn;
3213 break_point_hit_count = 0;
3215 foo->
Call(env->Global(), argc, argv_100);
3216 CHECK_EQ(202, break_point_hit_count);
3220 CheckDebuggerUnloaded();
3224 TEST(DebugStepDoWhile) {
3225 DebugLocalContext env;
3235 const char* src =
"function foo(x) { "
3243 SetBreakPoint(foo, 8);
3246 step_action = StepIn;
3247 break_point_hit_count = 0;
3249 foo->
Call(env->Global(), argc, argv_10);
3250 CHECK_EQ(22, break_point_hit_count);
3253 step_action = StepIn;
3254 break_point_hit_count = 0;
3256 foo->
Call(env->Global(), argc, argv_100);
3257 CHECK_EQ(202, break_point_hit_count);
3261 CheckDebuggerUnloaded();
3265 TEST(DebugStepFor) {
3266 DebugLocalContext env;
3276 const char* src =
"function foo(x) { "
3278 " for (i = 0; i < x; i++) {"
3282 "a=0; b=0; i=0; foo()";
3285 SetBreakPoint(foo, 8);
3288 step_action = StepIn;
3289 break_point_hit_count = 0;
3291 foo->
Call(env->Global(), argc, argv_10);
3292 CHECK_EQ(23, break_point_hit_count);
3295 step_action = StepIn;
3296 break_point_hit_count = 0;
3298 foo->
Call(env->Global(), argc, argv_100);
3299 CHECK_EQ(203, break_point_hit_count);
3303 CheckDebuggerUnloaded();
3307 TEST(DebugStepForContinue) {
3308 DebugLocalContext env;
3318 const char* src =
"function foo(x) { "
3322 " for (var i = 0; i < x; i++) {"
3324 " if (a % 2 == 0) continue;"
3333 SetBreakPoint(foo, 8);
3338 step_action = StepIn;
3339 break_point_hit_count = 0;
3341 result = foo->
Call(env->Global(), argc, argv_10);
3343 CHECK_EQ(52, break_point_hit_count);
3346 step_action = StepIn;
3347 break_point_hit_count = 0;
3349 result = foo->
Call(env->Global(), argc, argv_100);
3351 CHECK_EQ(457, break_point_hit_count);
3355 CheckDebuggerUnloaded();
3359 TEST(DebugStepForBreak) {
3360 DebugLocalContext env;
3370 const char* src =
"function foo(x) { "
3374 " for (var i = 0; i < 1000; i++) {"
3376 " if (a == x) break;"
3385 SetBreakPoint(foo, 8);
3391 step_action = StepIn;
3392 break_point_hit_count = 0;
3394 result = foo->
Call(env->Global(), argc, argv_10);
3396 CHECK_EQ(55, break_point_hit_count);
3399 step_action = StepIn;
3400 break_point_hit_count = 0;
3402 result = foo->
Call(env->Global(), argc, argv_100);
3404 CHECK_EQ(505, break_point_hit_count);
3408 CheckDebuggerUnloaded();
3412 TEST(DebugStepForIn) {
3413 DebugLocalContext env;
3422 const char* src_1 =
"function foo() { "
3429 foo = CompileFunction(&env, src_1,
"foo");
3430 SetBreakPoint(foo, 0);
3432 step_action = StepIn;
3433 break_point_hit_count = 0;
3435 CHECK_EQ(6, break_point_hit_count);
3439 const char* src_2 =
"function foo() { "
3440 " var a = {a:[1, 2, 3]};"
3446 foo = CompileFunction(&env, src_2,
"foo");
3447 SetBreakPoint(foo, 0);
3449 step_action = StepIn;
3450 break_point_hit_count = 0;
3452 CHECK_EQ(8, break_point_hit_count);
3456 CheckDebuggerUnloaded();
3460 TEST(DebugStepWith) {
3461 DebugLocalContext env;
3469 const char* src =
"function foo(x) { "
3479 SetBreakPoint(foo, 8);
3481 step_action = StepIn;
3482 break_point_hit_count = 0;
3484 CHECK_EQ(4, break_point_hit_count);
3488 CheckDebuggerUnloaded();
3492 TEST(DebugConditional) {
3493 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) {
3530 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) {
3581 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) {
3633 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) {
3669 DebugLocalContext env;
3675 "function foo(){debugger;Math.sin(1);}",
3681 step_action = StepIn;
3682 break_point_hit_count = 0;
3683 foo->Call(env->Global(), 0,
NULL);
3686 CHECK_EQ(3, break_point_hit_count);
3689 CheckDebuggerUnloaded();
3694 break_point_hit_count = 0;
3695 foo->Call(env->Global(), 0,
NULL);
3698 CHECK_EQ(1, break_point_hit_count);
3701 CheckDebuggerUnloaded();
3706 TEST(DebugStepFunctionApply) {
3707 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;
3722 foo->Call(env->Global(), 0,
NULL);
3725 CHECK_EQ(7, break_point_hit_count);
3728 CheckDebuggerUnloaded();
3733 break_point_hit_count = 0;
3734 foo->Call(env->Global(), 0,
NULL);
3737 CHECK_EQ(1, break_point_hit_count);
3740 CheckDebuggerUnloaded();
3745 TEST(DebugStepFunctionCall) {
3746 DebugLocalContext env;
3753 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
3754 "function foo(a){ debugger;"
3756 " bar.call(this, 1, 2, 3);"
3758 " bar.call(this, 0);"
3765 step_action = StepIn;
3768 break_point_hit_count = 0;
3770 CHECK_EQ(6, break_point_hit_count);
3773 break_point_hit_count = 0;
3776 foo->
Call(env->Global(), argc, argv);
3777 CHECK_EQ(8, break_point_hit_count);
3780 CheckDebuggerUnloaded();
3785 break_point_hit_count = 0;
3789 CHECK_EQ(1, break_point_hit_count);
3792 CheckDebuggerUnloaded();
3797 TEST(PauseInScript) {
3798 DebugLocalContext env;
3806 const char* src =
"(function (evt) {})";
3807 const char* script_name =
"StepInHandlerTest";
3810 SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1);
3811 break_point_hit_count = 0;
3820 CHECK(r->IsFunction());
3821 CHECK_EQ(1, break_point_hit_count);
3825 CheckDebuggerUnloaded();
3835 TEST(BreakOnException) {
3836 DebugLocalContext env;
3841 CompileFunction(&env,
"function throws(){throw 1;}",
"throws");
3843 CompileFunction(&env,
3844 "function caught(){try {throws();} catch(e) {};}",
3847 CompileFunction(&env,
"function notCaught(){throws();}",
"notCaught");
3853 DebugEventCounterClear();
3854 MessageCallbackCountClear();
3855 caught->
Call(env->Global(), 0,
NULL);
3857 CHECK_EQ(0, uncaught_exception_hit_count);
3858 CHECK_EQ(0, message_callback_count);
3859 notCaught->
Call(env->Global(), 0,
NULL);
3861 CHECK_EQ(0, uncaught_exception_hit_count);
3862 CHECK_EQ(1, message_callback_count);
3865 DebugEventCounterClear();
3866 MessageCallbackCountClear();
3867 ChangeBreakOnException(
false,
false);
3868 caught->
Call(env->Global(), 0,
NULL);
3870 CHECK_EQ(0, uncaught_exception_hit_count);
3871 CHECK_EQ(0, message_callback_count);
3872 notCaught->
Call(env->Global(), 0,
NULL);
3874 CHECK_EQ(0, uncaught_exception_hit_count);
3875 CHECK_EQ(1, message_callback_count);
3878 DebugEventCounterClear();
3879 MessageCallbackCountClear();
3880 ChangeBreakOnException(
false,
true);
3881 caught->
Call(env->Global(), 0,
NULL);
3883 CHECK_EQ(0, uncaught_exception_hit_count);
3884 CHECK_EQ(0, message_callback_count);
3885 notCaught->
Call(env->Global(), 0,
NULL);
3887 CHECK_EQ(1, uncaught_exception_hit_count);
3888 CHECK_EQ(1, message_callback_count);
3891 DebugEventCounterClear();
3892 MessageCallbackCountClear();
3893 ChangeBreakOnException(
true,
true);
3894 caught->
Call(env->Global(), 0,
NULL);
3896 CHECK_EQ(0, uncaught_exception_hit_count);
3897 CHECK_EQ(0, message_callback_count);
3898 notCaught->
Call(env->Global(), 0,
NULL);
3900 CHECK_EQ(1, uncaught_exception_hit_count);
3901 CHECK_EQ(1, message_callback_count);
3904 DebugEventCounterClear();
3905 MessageCallbackCountClear();
3906 ChangeBreakOnException(
true,
false);
3907 caught->
Call(env->Global(), 0,
NULL);
3909 CHECK_EQ(0, uncaught_exception_hit_count);
3910 CHECK_EQ(0, message_callback_count);
3911 notCaught->
Call(env->Global(), 0,
NULL);
3913 CHECK_EQ(1, uncaught_exception_hit_count);
3914 CHECK_EQ(1, message_callback_count);
3917 DebugEventCounterClear();
3918 MessageCallbackCountClear();
3919 ChangeBreakOnExceptionFromJS(env->GetIsolate(),
false,
false);
3920 caught->
Call(env->Global(), 0,
NULL);
3922 CHECK_EQ(0, uncaught_exception_hit_count);
3923 CHECK_EQ(0, message_callback_count);
3924 notCaught->
Call(env->Global(), 0,
NULL);
3926 CHECK_EQ(0, uncaught_exception_hit_count);
3927 CHECK_EQ(1, message_callback_count);
3930 DebugEventCounterClear();
3931 MessageCallbackCountClear();
3932 ChangeBreakOnExceptionFromJS(env->GetIsolate(),
false,
true);
3933 caught->
Call(env->Global(), 0,
NULL);
3935 CHECK_EQ(0, uncaught_exception_hit_count);
3936 CHECK_EQ(0, message_callback_count);
3937 notCaught->
Call(env->Global(), 0,
NULL);
3939 CHECK_EQ(1, uncaught_exception_hit_count);
3940 CHECK_EQ(1, message_callback_count);
3943 DebugEventCounterClear();
3944 MessageCallbackCountClear();
3945 ChangeBreakOnExceptionFromJS(env->GetIsolate(),
true,
true);
3946 caught->
Call(env->Global(), 0,
NULL);
3948 CHECK_EQ(0, message_callback_count);
3949 CHECK_EQ(0, uncaught_exception_hit_count);
3950 notCaught->
Call(env->Global(), 0,
NULL);
3952 CHECK_EQ(1, uncaught_exception_hit_count);
3953 CHECK_EQ(1, message_callback_count);
3956 DebugEventCounterClear();
3957 MessageCallbackCountClear();
3958 ChangeBreakOnExceptionFromJS(env->GetIsolate(),
true,
false);
3959 caught->
Call(env->Global(), 0,
NULL);
3961 CHECK_EQ(0, uncaught_exception_hit_count);
3962 CHECK_EQ(0, message_callback_count);
3963 notCaught->
Call(env->Global(), 0,
NULL);
3965 CHECK_EQ(1, uncaught_exception_hit_count);
3966 CHECK_EQ(1, message_callback_count);
3969 CheckDebuggerUnloaded();
3977 TEST(BreakOnCompileException) {
3978 DebugLocalContext env;
3982 ChangeBreakOnException(
false,
true);
3985 frame_count = CompileFunction(&env, frame_count_source,
"frame_count");
3990 DebugEventCounterClear();
3991 MessageCallbackCountClear();
3995 CHECK_EQ(0, uncaught_exception_hit_count);
3996 CHECK_EQ(0, message_callback_count);
3997 CHECK_EQ(-1, last_js_stack_height);
4002 CHECK_EQ(1, uncaught_exception_hit_count);
4003 CHECK_EQ(1, message_callback_count);
4009 CHECK_EQ(2, uncaught_exception_hit_count);
4010 CHECK_EQ(2, message_callback_count);
4017 CHECK_EQ(3, uncaught_exception_hit_count);
4018 CHECK_EQ(3, message_callback_count);
4025 CHECK_EQ(4, uncaught_exception_hit_count);
4026 CHECK_EQ(4, message_callback_count);
4031 TEST(StepWithException) {
4032 DebugLocalContext env;
4036 ChangeBreakOnException(
false,
true);
4039 frame_function_name = CompileFunction(&env,
4040 frame_function_name_source,
4041 "frame_function_name");
4047 const char* src =
"function a() { n(); }; "
4048 "function b() { c(); }; "
4049 "function c() { n(); }; "
4050 "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; "
4051 "function e() { n(); }; "
4052 "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; "
4053 "function g() { h(); }; "
4054 "function h() { x = 1; throw 1; }; ";
4058 SetBreakPoint(a, 0);
4059 step_action = StepIn;
4060 break_point_hit_count = 0;
4061 expected_step_sequence =
"aa";
4064 break_point_hit_count);
4068 SetBreakPoint(b, 0);
4069 step_action = StepIn;
4070 break_point_hit_count = 0;
4071 expected_step_sequence =
"bcc";
4074 break_point_hit_count);
4077 SetBreakPoint(d, 0);
4078 ChangeBreakOnException(
false,
true);
4079 step_action = StepIn;
4080 break_point_hit_count = 0;
4081 expected_step_sequence =
"ddedd";
4084 break_point_hit_count);
4087 ChangeBreakOnException(
true,
true);
4088 step_action = StepIn;
4089 break_point_hit_count = 0;
4090 expected_step_sequence =
"ddeedd";
4093 break_point_hit_count);
4097 SetBreakPoint(f, 0);
4098 ChangeBreakOnException(
false,
true);
4099 step_action = StepIn;
4100 break_point_hit_count = 0;
4101 expected_step_sequence =
"ffghhff";
4104 break_point_hit_count);
4107 ChangeBreakOnException(
true,
true);
4108 step_action = StepIn;
4109 break_point_hit_count = 0;
4110 expected_step_sequence =
"ffghhhff";
4113 break_point_hit_count);
4117 CheckDebuggerUnloaded();
4122 i::FLAG_stress_compaction =
false;
4124 i::FLAG_verify_heap =
true;
4126 DebugLocalContext env;
4134 const char* src =
"function f0() {}"
4135 "function f1(x1) {}"
4136 "function f2(x1,x2) {}"
4137 "function f3(x1,x2,x3) {}";
4159 break_point_hit_count = 0;
4160 for (
unsigned int i = 0; i <
ARRAY_SIZE(argv); i++) {
4161 f0->
Call(env->Global(), i, argv);
4162 f1->
Call(env->Global(), i, argv);
4163 f2->
Call(env->Global(), i, argv);
4164 f3->
Call(env->Global(), i, argv);
4172 CheckDebuggerUnloaded();
4178 TEST(DisableBreak) {
4179 DebugLocalContext env;
4186 const char* src =
"function f() {g()};function g(){i=0; while(i<10){i++}}";
4193 break_point_hit_count = 0;
4195 CHECK_EQ(1, break_point_hit_count);
4200 v8::internal::DisableBreak disable_break(isolate,
true);
4202 CHECK_EQ(1, break_point_hit_count);
4206 CHECK_EQ(2, break_point_hit_count);
4210 CheckDebuggerUnloaded();
4213 static const char* kSimpleExtensionSource =
4220 TEST(NoBreakWhenBootstrapping) {
4229 break_point_hit_count = 0;
4234 kSimpleExtensionSource));
4235 const char* extension_names[] = {
"simpletest" };
4241 CHECK_EQ(0, break_point_hit_count);
4245 CheckDebuggerUnloaded();
4273 if (strcmp(*n,
"a") == 0) {
4276 }
else if (strcmp(*n,
"b") == 0) {
4279 }
else if (strcmp(*n,
"c") == 0) {
4290 static void IndexedGetter(uint32_t index,
4296 TEST(InterceptorPropertyMirror) {
4298 DebugLocalContext env;
4331 "var named_mirror = debug.MakeMirror(intercepted_named);"
4332 "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
4333 "var both_mirror = debug.MakeMirror(intercepted_both)");
4335 "named_mirror instanceof debug.ObjectMirror")->BooleanValue());
4337 "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue());
4339 "both_mirror instanceof debug.ObjectMirror")->BooleanValue());
4343 "named_names = named_mirror.propertyNames();"
4344 "indexed_names = indexed_mirror.propertyNames();"
4345 "both_names = both_mirror.propertyNames()");
4346 CHECK_EQ(3, CompileRun(
"named_names.length")->Int32Value());
4347 CHECK_EQ(2, CompileRun(
"indexed_names.length")->Int32Value());
4348 CHECK_EQ(5, CompileRun(
"both_names.length")->Int32Value());
4352 source =
"named_mirror.properties().length";
4353 CHECK_EQ(3, CompileRun(source)->Int32Value());
4355 source =
"indexed_mirror.properties().length";
4356 CHECK_EQ(2, CompileRun(source)->Int32Value());
4358 source =
"both_mirror.properties().length";
4359 CHECK_EQ(5, CompileRun(source)->Int32Value());
4362 source =
"both_mirror.properties(1).length";
4363 CHECK_EQ(3, CompileRun(source)->Int32Value());
4366 source =
"both_mirror.properties(2).length";
4367 CHECK_EQ(2, CompileRun(source)->Int32Value());
4370 source =
"both_mirror.properties(3).length";
4371 CHECK_EQ(5, CompileRun(source)->Int32Value());
4374 CompileRun(
"var named_values = named_mirror.properties()");
4377 for (
int i = 0; i < 3; i++) {
4378 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4379 OS::SNPrintF(buffer,
4380 "named_values[%d] instanceof debug.PropertyMirror", i);
4381 CHECK(CompileRun(buffer.start())->BooleanValue());
4383 OS::SNPrintF(buffer,
"named_values[%d].propertyType()", i);
4385 CompileRun(buffer.start())->Int32Value());
4387 OS::SNPrintF(buffer,
"named_values[%d].isNative()", i);
4388 CHECK(CompileRun(buffer.start())->BooleanValue());
4393 CompileRun(
"var indexed_values = indexed_mirror.properties()");
4396 for (
int i = 0; i < 2; i++) {
4397 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4398 OS::SNPrintF(buffer,
4399 "indexed_values[%d] instanceof debug.PropertyMirror", i);
4400 CHECK(CompileRun(buffer.start())->BooleanValue());
4405 CompileRun(
"var both_values = both_mirror.properties()");
4408 for (
int i = 0; i < 5; i++) {
4409 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4410 OS::SNPrintF(buffer,
"both_values[%d] instanceof debug.PropertyMirror", i);
4411 CHECK(CompileRun(buffer.start())->BooleanValue());
4415 source =
"both_values[0].name() == 'a'";
4416 CHECK(CompileRun(source)->BooleanValue());
4418 source =
"both_values[1].name() == 'b'";
4419 CHECK(CompileRun(source)->BooleanValue());
4421 source =
"both_values[2].name() == 'c'";
4422 CHECK(CompileRun(source)->BooleanValue());
4424 source =
"both_values[3].name() == 1";
4425 CHECK(CompileRun(source)->BooleanValue());
4427 source =
"both_values[4].name() == 10";
4428 CHECK(CompileRun(source)->BooleanValue());
4432 TEST(HiddenPrototypePropertyMirror) {
4434 DebugLocalContext env;
4466 "var o0_mirror = debug.MakeMirror(o0);"
4467 "var o1_mirror = debug.MakeMirror(o1);"
4468 "var o2_mirror = debug.MakeMirror(o2);"
4469 "var o3_mirror = debug.MakeMirror(o3)");
4470 CHECK(CompileRun(
"o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
4471 CHECK(CompileRun(
"o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
4472 CHECK(CompileRun(
"o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
4473 CHECK(CompileRun(
"o3_mirror instanceof debug.ObjectMirror")->BooleanValue());
4477 "o0_mirror.propertyNames().length")->Int32Value());
4479 "o1_mirror.propertyNames().length")->Int32Value());
4481 "o2_mirror.propertyNames().length")->Int32Value());
4483 "o3_mirror.propertyNames().length")->Int32Value());
4489 "o0_mirror.propertyNames().length")->Int32Value());
4491 "o0_mirror.property('x').value().value()")->Int32Value());
4493 "o0_mirror.property('y').value().value()")->Int32Value());
4500 "o0_mirror.propertyNames().length")->Int32Value());
4502 "o0_mirror.property('x').value().value()")->Int32Value());
4504 "o0_mirror.property('y').value().value()")->Int32Value());
4506 "o0_mirror.property('z').value().value()")->Int32Value());
4516 "o0_mirror.propertyNames().length")->Int32Value());
4518 "o3_mirror.propertyNames().length")->Int32Value());
4520 "o0_mirror.property('x').value().value()")->Int32Value());
4522 "o0_mirror.property('y').value().value()")->Int32Value());
4524 "o0_mirror.property('z').value().value()")->Int32Value());
4525 CHECK(CompileRun(
"o0_mirror.property('u').isUndefined()")->BooleanValue());
4528 CHECK(CompileRun(
"o0_mirror.protoObject() == o3_mirror")->BooleanValue());
4532 static void ProtperyXNativeGetter(
4539 TEST(NativeGetterPropertyMirror) {
4541 DebugLocalContext env;
4555 CHECK_EQ(10, CompileRun(
"instance.x")->Int32Value());
4558 CompileRun(
"var instance_mirror = debug.MakeMirror(instance);");
4560 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4562 CompileRun(
"var named_names = instance_mirror.propertyNames();");
4563 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4564 CHECK(CompileRun(
"named_names[0] == 'x'")->BooleanValue());
4566 "instance_mirror.property('x').value().isNumber()")->BooleanValue());
4568 "instance_mirror.property('x').value().value() == 10")->BooleanValue());
4572 static void ProtperyXNativeGetterThrowingError(
4575 CompileRun(
"throw new Error('Error message');");
4579 TEST(NativeGetterThrowingErrorPropertyMirror) {
4581 DebugLocalContext env;
4597 CompileRun(
"var instance_mirror = debug.MakeMirror(instance);");
4599 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4600 CompileRun(
"named_names = instance_mirror.propertyNames();");
4601 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4602 CHECK(CompileRun(
"named_names[0] == 'x'")->BooleanValue());
4604 "instance_mirror.property('x').value().isError()")->BooleanValue());
4608 "instance_mirror.property('x').value().message() == 'Error message'")->
4616 TEST(NoHiddenProperties) {
4618 DebugLocalContext env;
4624 const char* source =
"var obj = {a: 1};";
4635 CompileRun(
"var obj_mirror = debug.MakeMirror(obj);");
4637 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4638 CompileRun(
"var named_names = obj_mirror.propertyNames();");
4642 CHECK_EQ(1, CompileRun(
"named_names.length")->Int32Value());
4643 CHECK(CompileRun(
"named_names[0] == 'a'")->BooleanValue());
4645 "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4678 CompileRun(
"var obj_mirror = debug.MakeMirror(obj);");
4680 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4681 CompileRun(
"var named_names = obj_mirror.propertyNames();");
4684 CHECK_EQ(2, CompileRun(
"named_names.length")->Int32Value());
4685 CHECK(CompileRun(
"named_names.sort(); named_names[0] == 'a' &&"
4686 "named_names[1] == 'b'")->BooleanValue());
4688 "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4690 "obj_mirror.property('b').value().value() == 2")->BooleanValue());
4704 ThreadBarrier() : num_blocked_(0) {}
4707 LockGuard<Mutex> lock_guard(&mutex_);
4708 if (num_blocked_ != 0) {
4714 LockGuard<Mutex> lock_guard(&mutex_);
4717 if (
N == num_blocked_) {
4720 printf(
"BARRIER\n\n");
4723 while (num_blocked_ <
N) {
4731 ConditionVariable cv_;
4744 Barriers() : semaphore_1(0), semaphore_2(0) {}
4745 ThreadBarrier<2> barrier_1;
4746 ThreadBarrier<2> barrier_2;
4747 ThreadBarrier<2> barrier_3;
4748 ThreadBarrier<2> barrier_4;
4749 ThreadBarrier<2> barrier_5;
4750 v8::internal::Semaphore semaphore_1;
4751 v8::internal::Semaphore semaphore_2;
4756 bool IsBreakEventMessage(
char *message) {
4757 const char* type_event =
"\"type\":\"event\"";
4758 const char* event_break =
"\"event\":\"break\"";
4760 return strstr(message, type_event) !=
NULL &&
4761 strstr(message, event_break) !=
NULL;
4766 bool IsExceptionEventMessage(
char *message) {
4767 const char* type_event =
"\"type\":\"event\"";
4768 const char* event_exception =
"\"event\":\"exception\"";
4770 return strstr(message, type_event) !=
NULL &&
4771 strstr(message, event_exception) !=
NULL;
4776 bool IsEvaluateResponseMessage(
char* message) {
4777 const char* type_response =
"\"type\":\"response\"";
4778 const char* command_evaluate =
"\"command\":\"evaluate\"";
4780 return strstr(message, type_response) !=
NULL &&
4781 strstr(message, command_evaluate) !=
NULL;
4791 int GetEvaluateIntResult(
char *message) {
4792 const char* value =
"\"value\":";
4793 char* pos = strstr(message, value);
4804 int GetBreakpointIdFromBreakEventMessage(
char *message) {
4805 const char* breakpoints =
"\"breakpoints\":[";
4806 char* pos = strstr(message, breakpoints);
4817 int GetTotalFramesInt(
char *message) {
4818 const char* prefix =
"\"totalFrames\":";
4819 char* pos = strstr(message, prefix);
4823 pos += strlen(prefix);
4830 int GetSourceLineFromBreakEventMessage(
char *message) {
4831 const char* source_line =
"\"sourceLine\":";
4832 char* pos = strstr(message, source_line);
4847 Barriers message_queue_barriers;
4853 MessageQueueDebuggerThread()
4854 : Thread(
"MessageQueueDebuggerThread") { }
4862 if (IsBreakEventMessage(*utf8)) {
4865 message_queue_barriers.semaphore_2.Signal();
4870 message_queue_barriers.semaphore_1.Wait();
4874 void MessageQueueDebuggerThread::Run() {
4875 const int kBufferSize = 1000;
4878 const char* command_1 =
4880 "\"type\":\"request\","
4881 "\"command\":\"evaluate\","
4882 "\"arguments\":{\"expression\":\"1+2\"}}";
4883 const char* command_2 =
4885 "\"type\":\"request\","
4886 "\"command\":\"evaluate\","
4887 "\"arguments\":{\"expression\":\"1+a\"}}";
4888 const char* command_3 =
4890 "\"type\":\"request\","
4891 "\"command\":\"evaluate\","
4892 "\"arguments\":{\"expression\":\"c.d * b\"}}";
4893 const char* command_continue =
4895 "\"type\":\"request\","
4896 "\"command\":\"continue\"}";
4897 const char* command_single_step =
4899 "\"type\":\"request\","
4900 "\"command\":\"continue\","
4901 "\"arguments\":{\"stepaction\":\"next\"}}";
4905 message_queue_barriers.semaphore_1.Signal();
4906 message_queue_barriers.barrier_1.Wait();
4918 message_queue_barriers.barrier_2.Wait();
4926 for (
int i = 0; i < 6 ; ++i) {
4927 message_queue_barriers.semaphore_1.Signal();
4929 message_queue_barriers.barrier_3.Wait();
4932 message_queue_barriers.semaphore_1.Signal();
4935 message_queue_barriers.semaphore_2.Wait();
4941 isolate, buffer_2, AsciiToUtf16(command_single_step, buffer_2));
4943 for (
int i = 0; i < 6 ; ++i) {
4944 message_queue_barriers.semaphore_1.Signal();
4947 message_queue_barriers.semaphore_2.Wait();
4950 isolate, buffer_2, AsciiToUtf16(command_continue, buffer_2));
4952 for (
int i = 0; i < 2 ; ++i) {
4953 message_queue_barriers.semaphore_1.Signal();
4960 TEST(MessageQueues) {
4961 MessageQueueDebuggerThread message_queue_debugger_thread;
4964 DebugLocalContext env;
4967 message_queue_debugger_thread.Start();
4969 const char* source_1 =
"a = 3; b = 4; c = new Object(); c.d = 5;";
4970 const char* source_2 =
"e = 17;";
4971 const char* source_3 =
"a = 4; debugger; a = 5; a = 6; a = 7;";
4975 CompileRun(source_1);
4976 message_queue_barriers.barrier_1.Wait();
4977 message_queue_barriers.barrier_2.Wait();
4978 CompileRun(source_2);
4979 message_queue_barriers.barrier_3.Wait();
4980 CompileRun(source_3);
4981 message_queue_debugger_thread.Join();
4989 constructor_call_counter++;
4991 virtual ~TestClientData() {
4992 destructor_call_counter++;
4995 static void ResetCounters() {
4996 constructor_call_counter = 0;
4997 destructor_call_counter = 0;
5000 static int constructor_call_counter;
5001 static int destructor_call_counter;
5004 int TestClientData::constructor_call_counter = 0;
5005 int TestClientData::destructor_call_counter = 0;
5010 TEST(MessageQueueExpandAndDestroy) {
5011 TestClientData::ResetCounters();
5013 CommandMessageQueue queue(1);
5014 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5015 new TestClientData()));
5016 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5017 new TestClientData()));
5018 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5019 new TestClientData()));
5020 CHECK_EQ(0, TestClientData::destructor_call_counter);
5021 queue.Get().Dispose();
5022 CHECK_EQ(1, TestClientData::destructor_call_counter);
5023 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5024 new TestClientData()));
5025 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5026 new TestClientData()));
5027 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5028 new TestClientData()));
5029 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5030 new TestClientData()));
5031 queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5032 new TestClientData()));
5033 CHECK_EQ(1, TestClientData::destructor_call_counter);
5034 queue.Get().Dispose();
5035 CHECK_EQ(2, TestClientData::destructor_call_counter);
5038 CHECK_EQ(TestClientData::destructor_call_counter,
5039 TestClientData::destructor_call_counter);
5043 static int handled_client_data_instances_count = 0;
5044 static void MessageHandlerCountingClientData(
5047 handled_client_data_instances_count++;
5053 TEST(SendClientDataToHandler) {
5055 DebugLocalContext env;
5058 TestClientData::ResetCounters();
5059 handled_client_data_instances_count = 0;
5061 const char* source_1 =
"a = 3; b = 4; c = new Object(); c.d = 5;";
5062 const int kBufferSize = 1000;
5064 const char* command_1 =
5066 "\"type\":\"request\","
5067 "\"command\":\"evaluate\","
5068 "\"arguments\":{\"expression\":\"1+2\"}}";
5069 const char* command_2 =
5071 "\"type\":\"request\","
5072 "\"command\":\"evaluate\","
5073 "\"arguments\":{\"expression\":\"1+a\"}}";
5074 const char* command_continue =
5076 "\"type\":\"request\","
5077 "\"command\":\"continue\"}";
5080 new TestClientData());
5082 isolate, buffer, AsciiToUtf16(command_2, buffer),
NULL);
5084 new TestClientData());
5086 new TestClientData());
5088 CompileRun(source_1);
5090 isolate, buffer, AsciiToUtf16(command_continue, buffer));
5091 CHECK_EQ(3, TestClientData::constructor_call_counter);
5092 CHECK_EQ(TestClientData::constructor_call_counter,
5093 handled_client_data_instances_count);
5094 CHECK_EQ(TestClientData::constructor_call_counter,
5095 TestClientData::destructor_call_counter);
5106 Barriers threaded_debugging_barriers;
5110 V8Thread() : Thread(
"V8Thread") { }
5116 DebuggerThread() : Thread(
"DebuggerThread") { }
5121 static void ThreadedAtBarrier1(
5123 threaded_debugging_barriers.barrier_1.Wait();
5128 static char print_buffer[1000];
5130 Utf16ToAscii(*json, json.length(), print_buffer);
5131 if (IsBreakEventMessage(print_buffer)) {
5133 int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
5137 CHECK(7 <= source_line && source_line <= 13);
5138 threaded_debugging_barriers.barrier_2.Wait();
5143 void V8Thread::Run() {
5144 const char* source =
5146 "function bar( new_value ) {\n"
5147 " flag = new_value;\n"
5148 " return \"Return from bar(\" + new_value + \")\";\n"
5151 "function foo() {\n"
5153 " while ( flag == true ) {\n"
5154 " if ( x == 1 ) {\n"
5155 " ThreadedAtBarrier1();\n"
5165 DebugLocalContext env;
5170 global_template->
Set(
5182 void DebuggerThread::Run() {
5183 const int kBufSize = 1000;
5186 const char* command_1 =
"{\"seq\":102,"
5187 "\"type\":\"request\","
5188 "\"command\":\"evaluate\","
5189 "\"arguments\":{\"expression\":\"bar(false)\"}}";
5190 const char* command_2 =
"{\"seq\":103,"
5191 "\"type\":\"request\","
5192 "\"command\":\"continue\"}";
5195 threaded_debugging_barriers.barrier_1.Wait();
5197 threaded_debugging_barriers.barrier_2.Wait();
5203 TEST(ThreadedDebugging) {
5204 DebuggerThread debugger_thread;
5209 debugger_thread.Start();
5212 debugger_thread.Join();
5225 BreakpointsV8Thread() : Thread(
"BreakpointsV8Thread") { }
5231 explicit BreakpointsDebuggerThread(
bool global_evaluate)
5232 : Thread(
"BreakpointsDebuggerThread"),
5233 global_evaluate_(global_evaluate) {}
5237 bool global_evaluate_;
5241 Barriers* breakpoints_barriers;
5242 int break_event_breakpoint_id;
5243 int evaluate_int_result;
5246 static char print_buffer[1000];
5248 Utf16ToAscii(*json, json.length(), print_buffer);
5250 if (IsBreakEventMessage(print_buffer)) {
5251 break_event_breakpoint_id =
5252 GetBreakpointIdFromBreakEventMessage(print_buffer);
5253 breakpoints_barriers->semaphore_1.Signal();
5254 }
else if (IsEvaluateResponseMessage(print_buffer)) {
5255 evaluate_int_result = GetEvaluateIntResult(print_buffer);
5256 breakpoints_barriers->semaphore_1.Signal();
5261 void BreakpointsV8Thread::Run() {
5262 const char* source_1 =
"var y_global = 3;\n"
5263 "function cat( new_value ) {\n"
5264 " var x = new_value;\n"
5265 " y_global = y_global + 4;\n"
5267 " y_global = y_global + 5;\n"
5271 "function dog() {\n"
5279 const char* source_2 =
"cat(17);\n"
5284 DebugLocalContext env;
5288 CompileRun(source_1);
5289 breakpoints_barriers->barrier_1.Wait();
5290 breakpoints_barriers->barrier_2.Wait();
5291 CompileRun(source_2);
5295 void BreakpointsDebuggerThread::Run() {
5296 const int kBufSize = 1000;
5299 const char* command_1 =
"{\"seq\":101,"
5300 "\"type\":\"request\","
5301 "\"command\":\"setbreakpoint\","
5302 "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5303 const char* command_2 =
"{\"seq\":102,"
5304 "\"type\":\"request\","
5305 "\"command\":\"setbreakpoint\","
5306 "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
5307 const char* command_3;
5308 if (this->global_evaluate_) {
5309 command_3 =
"{\"seq\":103,"
5310 "\"type\":\"request\","
5311 "\"command\":\"evaluate\","
5312 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
5313 "\"global\":true}}";
5315 command_3 =
"{\"seq\":103,"
5316 "\"type\":\"request\","
5317 "\"command\":\"evaluate\","
5318 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
5320 const char* command_4;
5321 if (this->global_evaluate_) {
5322 command_4 =
"{\"seq\":104,"
5323 "\"type\":\"request\","
5324 "\"command\":\"evaluate\","
5325 "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
5326 "\"global\":true}}";
5328 command_4 =
"{\"seq\":104,"
5329 "\"type\":\"request\","
5330 "\"command\":\"evaluate\","
5331 "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
5333 const char* command_5 =
"{\"seq\":105,"
5334 "\"type\":\"request\","
5335 "\"command\":\"continue\"}";
5336 const char* command_6 =
"{\"seq\":106,"
5337 "\"type\":\"request\","
5338 "\"command\":\"continue\"}";
5339 const char* command_7;
5340 if (this->global_evaluate_) {
5341 command_7 =
"{\"seq\":107,"
5342 "\"type\":\"request\","
5343 "\"command\":\"evaluate\","
5344 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
5345 "\"global\":true}}";
5347 command_7 =
"{\"seq\":107,"
5348 "\"type\":\"request\","
5349 "\"command\":\"evaluate\","
5350 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
5352 const char* command_8 =
"{\"seq\":108,"
5353 "\"type\":\"request\","
5354 "\"command\":\"continue\"}";
5360 breakpoints_barriers->barrier_1.Wait();
5365 breakpoints_barriers->barrier_2.Wait();
5372 breakpoints_barriers->semaphore_1.Wait();
5374 CHECK_EQ(1, break_event_breakpoint_id);
5378 breakpoints_barriers->semaphore_1.Wait();
5380 CHECK_EQ(2, break_event_breakpoint_id);
5384 breakpoints_barriers->semaphore_1.Wait();
5386 CHECK_EQ(108, evaluate_int_result);
5390 breakpoints_barriers->semaphore_1.Wait();
5392 CHECK_EQ(107, evaluate_int_result);
5397 breakpoints_barriers->semaphore_1.Wait();
5399 CHECK_EQ(1, break_event_breakpoint_id);
5403 breakpoints_barriers->semaphore_1.Wait();
5405 CHECK_EQ(116, evaluate_int_result);
5411 void TestRecursiveBreakpointsGeneric(
bool global_evaluate) {
5412 i::FLAG_debugger_auto_break =
true;
5414 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
5415 BreakpointsV8Thread breakpoints_v8_thread;
5418 Barriers stack_allocated_breakpoints_barriers;
5419 breakpoints_barriers = &stack_allocated_breakpoints_barriers;
5421 breakpoints_v8_thread.Start();
5422 breakpoints_debugger_thread.Start();
5424 breakpoints_v8_thread.Join();
5425 breakpoints_debugger_thread.Join();
5429 TEST(RecursiveBreakpoints) {
5430 TestRecursiveBreakpointsGeneric(
false);
5434 TEST(RecursiveBreakpointsGlobal) {
5435 TestRecursiveBreakpointsGeneric(
true);
5439 static void DummyDebugEventListener(
5444 TEST(SetDebugEventListenerOnUninitializedVM) {
5453 TEST(SetMessageHandlerOnUninitializedVM) {
5461 static const char* debugger_call_with_data_source =
5462 "function debugger_call_with_data(exec_state, data) {"
5463 " if (data) return data;"
5472 static const char* debugger_call_with_closure_source =
5474 "(function (exec_state) {"
5475 " if (exec_state.y) return x - 1;"
5476 " exec_state.y = x;"
5477 " return exec_state.y"
5502 static void CheckDataParameter(
5526 TEST(CallFunctionInDebugger) {
5533 global_template->
Set(
5536 global_template->
Set(
5539 global_template->
Set(
5542 global_template->
Set(
5558 frame_source_line_source))->Run();
5564 debugger_call_with_data_source))
5568 isolate,
"debugger_call_with_data")));
5571 debugger_call_with_closure =
5574 debugger_call_with_closure_source))->Run());
5586 " CheckFrameCount(2);"
5594 " CheckSourceLine(1)\n"
5595 " CheckSourceLine(2)\n"
5596 " CheckSourceLine(3)\n"
5601 "CheckDataParameter()"))->Run();
5615 " CheckSourceLine(8)\n"
5616 " CheckSourceLine(9)\n"
5617 " CheckSourceLine(10)\n"
5624 static void SendContinueCommand();
5625 static void MessageHandlerBreakPointHitCount(
5629 break_point_hit_count++;
5631 SendContinueCommand();
5638 TEST(DebuggerUnload) {
5639 DebugLocalContext env;
5642 CheckDebuggerUnloaded();
5645 break_point_hit_count = 0;
5651 CompileFunction(&env,
"function foo(){x=1}",
"foo");
5653 CompileFunction(&env,
"function bar(){y=2}",
"bar");
5656 SetBreakPoint(foo, 0);
5657 SetBreakPoint(foo, 4);
5658 SetBreakPoint(bar, 0);
5659 SetBreakPoint(bar, 4);
5662 break_point_hit_count = 0;
5663 foo->Call(env->Global(), 0,
NULL);
5664 CHECK_EQ(2, break_point_hit_count);
5666 CHECK_EQ(4, break_point_hit_count);
5672 CheckDebuggerUnloaded(
true);
5675 break_point_hit_count = 0;
5684 foo->Call(env->Global(), 0,
NULL);
5685 CHECK_EQ(0, break_point_hit_count);
5688 SetBreakPoint(foo, 0);
5689 SetBreakPoint(foo, 4);
5690 foo->Call(env->Global(), 0,
NULL);
5691 CHECK_EQ(2, break_point_hit_count);
5697 CheckDebuggerUnloaded(
true);
5702 static void SendContinueCommand() {
5703 const int kBufferSize = 1000;
5705 const char* command_continue =
5707 "\"type\":\"request\","
5708 "\"command\":\"continue\"}";
5716 static int message_handler_hit_count = 0;
5718 message_handler_hit_count++;
5720 static char print_buffer[1000];
5722 Utf16ToAscii(*json, json.length(), print_buffer);
5723 if (IsExceptionEventMessage(print_buffer)) {
5725 SendContinueCommand();
5731 TEST(DebuggerClearMessageHandler) {
5732 DebugLocalContext env;
5736 CheckDebuggerUnloaded();
5743 CompileRun(
"throw 1");
5746 CHECK_GT(message_handler_hit_count, 0);
5749 message_handler_hit_count = 0;
5754 CompileRun(
"throw 1");
5757 CHECK_EQ(0, message_handler_hit_count);
5759 CheckDebuggerUnloaded(
true);
5764 static void MessageHandlerClearingMessageHandler(
5766 message_handler_hit_count++;
5774 TEST(DebuggerClearMessageHandlerWhileActive) {
5775 DebugLocalContext env;
5779 CheckDebuggerUnloaded();
5786 CompileRun(
"throw 1");
5789 CHECK_EQ(1, message_handler_hit_count);
5791 CheckDebuggerUnloaded(
true);
5802 HostDispatchV8Thread() : Thread(
"HostDispatchV8Thread") { }
5808 HostDispatchDebuggerThread() : Thread(
"HostDispatchDebuggerThread") { }
5812 Barriers* host_dispatch_barriers;
5815 static char print_buffer[1000];
5817 Utf16ToAscii(*json, json.length(), print_buffer);
5821 static void HostDispatchDispatchHandler() {
5822 host_dispatch_barriers->semaphore_1.Signal();
5826 void HostDispatchV8Thread::Run() {
5827 const char* source_1 =
"var y_global = 3;\n"
5828 "function cat( new_value ) {\n"
5829 " var x = new_value;\n"
5836 const char* source_2 =
"cat(17);\n";
5839 DebugLocalContext env;
5846 CompileRun(source_1);
5847 host_dispatch_barriers->barrier_1.Wait();
5848 host_dispatch_barriers->barrier_2.Wait();
5849 CompileRun(source_2);
5853 void HostDispatchDebuggerThread::Run() {
5854 const int kBufSize = 1000;
5857 const char* command_1 =
"{\"seq\":101,"
5858 "\"type\":\"request\","
5859 "\"command\":\"setbreakpoint\","
5860 "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5861 const char* command_2 =
"{\"seq\":102,"
5862 "\"type\":\"request\","
5863 "\"command\":\"continue\"}";
5867 host_dispatch_barriers->barrier_1.Wait();
5871 host_dispatch_barriers->barrier_2.Wait();
5875 host_dispatch_barriers->semaphore_1.Wait();
5881 TEST(DebuggerHostDispatch) {
5882 HostDispatchDebuggerThread host_dispatch_debugger_thread;
5883 HostDispatchV8Thread host_dispatch_v8_thread;
5884 i::FLAG_debugger_auto_break =
true;
5887 Barriers stack_allocated_host_dispatch_barriers;
5888 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
5890 host_dispatch_v8_thread.Start();
5891 host_dispatch_debugger_thread.Start();
5893 host_dispatch_v8_thread.Join();
5894 host_dispatch_debugger_thread.Join();
5906 DebugMessageDispatchV8Thread() : Thread(
"DebugMessageDispatchV8Thread") { }
5912 DebugMessageDispatchDebuggerThread()
5913 : Thread(
"DebugMessageDispatchDebuggerThread") { }
5917 Barriers* debug_message_dispatch_barriers;
5920 static void DebugMessageHandler() {
5921 debug_message_dispatch_barriers->semaphore_1.Signal();
5925 void DebugMessageDispatchV8Thread::Run() {
5927 DebugLocalContext env;
5933 CompileRun(
"var y = 1 + 2;\n");
5934 debug_message_dispatch_barriers->barrier_1.Wait();
5935 debug_message_dispatch_barriers->semaphore_1.Wait();
5936 debug_message_dispatch_barriers->barrier_2.Wait();
5940 void DebugMessageDispatchDebuggerThread::Run() {
5941 debug_message_dispatch_barriers->barrier_1.Wait();
5942 SendContinueCommand();
5943 debug_message_dispatch_barriers->barrier_2.Wait();
5947 TEST(DebuggerDebugMessageDispatch) {
5948 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
5949 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
5951 i::FLAG_debugger_auto_break =
true;
5954 Barriers stack_allocated_debug_message_dispatch_barriers;
5955 debug_message_dispatch_barriers =
5956 &stack_allocated_debug_message_dispatch_barriers;
5958 debug_message_dispatch_v8_thread.Start();
5959 debug_message_dispatch_debugger_thread.Start();
5961 debug_message_dispatch_v8_thread.Join();
5962 debug_message_dispatch_debugger_thread.Join();
5966 TEST(DebuggerAgent) {
5971 const int kPort1 = 5858 + FlagDependentPortOffset();
5972 const int kPort2 = 5857 + FlagDependentPortOffset();
5973 const int kPort3 = 5856 + FlagDependentPortOffset();
5976 const int kPortBufferLen = 6;
5977 char port2_str[kPortBufferLen];
5978 OS::SNPrintF(
i::Vector<char>(port2_str, kPortBufferLen),
"%d", kPort2);
5983 debugger->StartAgent(
"test", kPort1);
5984 debugger->StopAgent();
5987 ok = debugger->StartAgent(
"test", kPort2);
5989 debugger->WaitForAgent();
5990 i::Socket* client =
new i::Socket;
5991 ok = client->Connect(
"localhost", port2_str);
5997 ok = client->Receive(&buf, 1) == 1;
5999 debugger->StopAgent();
6004 i::Socket* server =
new i::Socket;
6005 ok = server->Bind(kPort3);
6008 debugger->StartAgent(
"test", kPort3);
6009 debugger->StopAgent();
6015 class DebuggerAgentProtocolServerThread :
public i::Thread {
6017 explicit DebuggerAgentProtocolServerThread(
int port)
6018 : Thread(
"DebuggerAgentProtocolServerThread"),
6024 ~DebuggerAgentProtocolServerThread() {
6031 void WaitForListening() { listening_.Wait(); }
6032 char* body() {
return body_.get(); }
6039 i::Semaphore listening_;
6043 void DebuggerAgentProtocolServerThread::Run() {
6047 server_ =
new i::Socket;
6049 ok = server_->Bind(port_);
6053 ok = server_->Listen(1);
6055 listening_.Signal();
6058 client_ = server_->Accept();
6062 i::DebuggerAgentUtil::ReceiveMessage(client_);
6066 TEST(DebuggerAgentProtocolOverflowHeader) {
6069 const int kPort = 5860 + FlagDependentPortOffset();
6070 static const char* kLocalhost =
"localhost";
6073 const int kPortBufferLen = 6;
6074 char port_str[kPortBufferLen];
6078 DebuggerAgentProtocolServerThread* server =
6079 new DebuggerAgentProtocolServerThread(kPort);
6081 server->WaitForListening();
6084 i::Socket* client =
new i::Socket;
6086 bool ok = client->Connect(kLocalhost, port_str);
6090 static const int kBufferSize = 1000;
6091 char buffer[kBufferSize];
6094 for (
int i = 0; i < kBufferSize - 4; i++) {
6097 buffer[kBufferSize - 4] =
':';
6098 buffer[kBufferSize - 3] =
'0';
6099 buffer[kBufferSize - 2] =
'\r';
6100 buffer[kBufferSize - 1] =
'\n';
6101 int result = client->Send(buffer, kBufferSize);
6107 for (
int i = 2; i < kBufferSize - 2; i++) {
6110 buffer[kBufferSize - 2] =
'\r';
6111 buffer[kBufferSize - 1] =
'\n';
6112 result = client->Send(buffer, kBufferSize);
6116 const char* content_length_zero_header =
"Content-Length:0\r\n";
6117 int length =
StrLength(content_length_zero_header);
6118 result = client->Send(content_length_zero_header, length);
6120 result = client->Send(
"\r\n", 2);
6141 EmptyExternalStringResource() { empty_[0] = 0; }
6142 virtual ~EmptyExternalStringResource() {}
6143 virtual size_t length()
const {
return empty_.length(); }
6144 virtual const uint16_t*
data()
const {
return empty_.start(); }
6150 TEST(DebugGetLoadedScripts) {
6151 DebugLocalContext env;
6155 EmptyExternalStringResource source_ext_str;
6161 Handle<i::ExternalTwoByteString> i_source(
6165 i_source->set_resource(0);
6167 bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
6168 i::FLAG_allow_natives_syntax =
true;
6170 "var scripts = %DebugGetLoadedScripts();"
6171 "var count = scripts.length;"
6172 "for (var i = 0; i < count; ++i) {"
6173 " scripts[i].line_ends;"
6176 i::FLAG_allow_natives_syntax = allow_natives_syntax;
6188 TEST(ScriptNameAndData) {
6189 DebugLocalContext env;
6195 frame_script_name = CompileFunction(&env,
6196 frame_script_name_source,
6197 "frame_script_name");
6216 CHECK_EQ(1, break_point_hit_count);
6217 CHECK_EQ(
"name", last_script_name_hit);
6225 CHECK_EQ(2, break_point_hit_count);
6226 CHECK_EQ(
"name", last_script_name_hit);
6232 " toString: function() { return this.a + ' ' + this.b; }\n"
6242 CHECK_EQ(3, break_point_hit_count);
6243 CHECK_EQ(
"new name", last_script_name_hit);
6250 CHECK_EQ(4, break_point_hit_count);
6262 expected_context_data));
6263 message_handler_hit_count++;
6265 static char print_buffer[1000];
6267 Utf16ToAscii(*json, json.length(), print_buffer);
6270 if (IsBreakEventMessage(print_buffer)) {
6271 SendContinueCommand();
6301 context_1->SetEmbedderData(0, data_1);
6307 const char* source =
"function f() { debugger; }";
6312 expected_context = context_1;
6313 expected_context_data = data_1;
6315 f->
Call(context_1->Global(), 0,
NULL);
6322 expected_context = context_2;
6323 expected_context_data = data_2;
6329 CHECK_GT(message_handler_hit_count, 4);
6332 CheckDebuggerUnloaded();
6337 static int message_handler_break_hit_count = 0;
6341 message_handler_break_hit_count++;
6342 if (message_handler_break_hit_count == 1) {
6350 SendContinueCommand();
6356 TEST(DebugBreakInMessageHandler) {
6357 DebugLocalContext env;
6363 const char* script =
"function f() { debugger; g(); } function g() { }";
6373 CHECK_EQ(2, message_handler_break_hit_count);
6376 CHECK_EQ(2, message_handler_break_hit_count);
6380 #ifndef V8_INTERPRETED_REGEXP
6383 static void DebugEventDebugBreak(
6389 break_point_hit_count++;
6392 if (!frame_function_name.IsEmpty()) {
6401 last_function_hit[0] =
'\0';
6405 function_name->
WriteUtf8(last_function_hit);
6410 if (break_point_hit_count < 20) {
6417 TEST(RegExpDebugBreak) {
6419 DebugLocalContext env;
6423 frame_function_name = CompileFunction(&env,
6424 frame_function_name_source,
6425 "frame_function_name");
6429 const char* script =
6430 "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n"
6431 "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }";
6438 CHECK_EQ(12, result->Int32Value());
6442 result = f->
Call(env->Global(), argc, argv);
6446 CHECK_EQ(1, break_point_hit_count);
6449 #endif // V8_INTERPRETED_REGEXP
6453 static void ExecuteScriptForContextCheck(
6465 CHECK(context_1->GetEmbedderData(0)->IsUndefined());
6470 context_1->SetEmbedderData(0, data_1);
6471 CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1));
6474 const char* source =
"function f() { eval('debugger;'); }";
6479 expected_context = context_1;
6480 expected_context_data = data_1;
6482 f->
Call(context_1->Global(), 0,
NULL);
6493 TEST(EvalContextData) {
6496 ExecuteScriptForContextCheck(ContextCheckMessageHandler);
6499 CHECK_GT(message_handler_hit_count, 2);
6500 CheckDebuggerUnloaded();
6504 static bool sent_eval =
false;
6505 static int break_count = 0;
6506 static int continue_command_send_count = 0;
6509 static void DebugEvalContextCheckMessageHandler(
6513 expected_context_data));
6514 message_handler_hit_count++;
6516 static char print_buffer[1000];
6518 Utf16ToAscii(*json, json.length(), print_buffer);
6521 if (IsBreakEventMessage(print_buffer)) {
6526 const int kBufferSize = 1000;
6528 const char* eval_command =
6530 "\"type\":\"request\","
6531 "\"command\":\"evaluate\","
6532 "\"arguments\":{\"expression\":\"debugger;\","
6533 "\"global\":true,\"disable_break\":false}}";
6537 isolate, buffer, AsciiToUtf16(eval_command, buffer));
6541 SendContinueCommand();
6542 continue_command_send_count++;
6544 }
else if (IsEvaluateResponseMessage(print_buffer) &&
6545 continue_command_send_count < 2) {
6548 SendContinueCommand();
6549 continue_command_send_count++;
6556 TEST(NestedBreakEventContextData) {
6559 message_handler_hit_count = 0;
6561 ExecuteScriptForContextCheck(DebugEvalContextCheckMessageHandler);
6564 CHECK_GT(message_handler_hit_count, 3);
6568 CheckDebuggerUnloaded();
6573 int script_collected_count = 0;
6574 static void DebugEventScriptCollectedEvent(
6579 script_collected_count++;
6585 TEST(ScriptCollectedEvent) {
6587 break_point_hit_count = 0;
6588 script_collected_count = 0;
6589 DebugLocalContext env;
6593 debug->GetLoadedScripts();
6599 script_collected_count = 0;
6612 CHECK_EQ(2, script_collected_count);
6615 CheckDebuggerUnloaded();
6620 int script_collected_message_count = 0;
6624 script_collected_message_count++;
6633 TEST(ScriptCollectedEventContext) {
6634 i::FLAG_stress_compaction =
false;
6636 v8::internal::Debug* debug =
6638 script_collected_message_count = 0;
6653 local_context->
Enter();
6657 debug->GetLoadedScripts();
6672 local_context->
Exit();
6680 CHECK_EQ(2, script_collected_message_count);
6687 int after_compile_message_count = 0;
6692 after_compile_message_count++;
6694 SendContinueCommand();
6702 TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
6703 DebugLocalContext env;
6705 after_compile_message_count = 0;
6706 const char* script =
"var a=1";
6720 CheckDebuggerUnloaded();
6723 CHECK_EQ(2, after_compile_message_count);
6728 TEST(BreakMessageWhenMessageHandlerIsReset) {
6729 DebugLocalContext env;
6731 after_compile_message_count = 0;
6732 const char* script =
"function f() {};";
6743 f->Call(env->Global(), 0,
NULL);
6747 CheckDebuggerUnloaded();
6750 CHECK_EQ(1, after_compile_message_count);
6754 static int exception_event_count = 0;
6757 exception_event_count++;
6758 SendContinueCommand();
6764 TEST(ExceptionMessageWhenMessageHandlerIsReset) {
6765 DebugLocalContext env;
6769 ChangeBreakOnException(
false,
true);
6771 exception_event_count = 0;
6772 const char* script =
"function f() {throw new Error()};";
6786 CheckDebuggerUnloaded();
6788 CHECK_EQ(1, exception_event_count);
6794 TEST(ProvisionalBreakpointOnLineOutOfRange) {
6795 DebugLocalContext env;
6798 const char* script =
"function f() {};";
6799 const char* resource_name =
"test_resource";
6803 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name,
6806 SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
6808 after_compile_message_count = 0;
6823 CHECK_EQ(1, after_compile_message_count);
6825 ClearBreakPointFromJS(env->GetIsolate(), sbp1);
6826 ClearBreakPointFromJS(env->GetIsolate(), sbp2);
6835 break_point_hit_count++;
6840 SendContinueCommand();
6844 bool is_debug_break = isolate->
stack_guard()->IsDebugBreak();
6852 if (is_debug_break) {
6863 TEST(NoDebugBreakInAfterCompileMessageHandler) {
6864 DebugLocalContext env;
6874 const char* src =
"function f() { eval('var x = 10;'); } ";
6878 CHECK_EQ(1, break_point_hit_count);
6884 CHECK_EQ(2, break_point_hit_count);
6888 CheckDebuggerUnloaded();
6892 static int counting_message_handler_counter;
6895 counting_message_handler_counter++;
6900 TEST(ProcessDebugMessages) {
6901 DebugLocalContext env;
6905 counting_message_handler_counter = 0;
6909 const int kBufferSize = 1000;
6911 const char* scripts_command =
6913 "\"type\":\"request\","
6914 "\"command\":\"scripts\"}";
6918 isolate, buffer, AsciiToUtf16(scripts_command, buffer));
6920 CHECK_EQ(0, counting_message_handler_counter);
6923 CHECK_GE(counting_message_handler_counter, 1);
6925 counting_message_handler_counter = 0;
6928 isolate, buffer, AsciiToUtf16(scripts_command, buffer));
6930 isolate, buffer, AsciiToUtf16(scripts_command, buffer));
6931 CHECK_EQ(0, counting_message_handler_counter);
6934 CHECK_GE(counting_message_handler_counter, 2);
6938 CheckDebuggerUnloaded();
6942 struct BacktraceData {
6943 static int frame_counter;
6945 char print_buffer[1000];
6947 Utf16ToAscii(*json, json.length(), print_buffer, 1000);
6949 if (strstr(print_buffer,
"backtrace") ==
NULL) {
6952 frame_counter = GetTotalFramesInt(print_buffer);
6956 int BacktraceData::frame_counter;
6961 DebugLocalContext env;
6967 const int kBufferSize = 1000;
6969 const char* scripts_command =
6971 "\"type\":\"request\","
6972 "\"command\":\"backtrace\"}";
6975 BacktraceData::frame_counter = -10;
6979 AsciiToUtf16(scripts_command, buffer),
6982 CHECK_EQ(BacktraceData::frame_counter, 0);
6989 BacktraceData::frame_counter = -10;
6993 AsciiToUtf16(scripts_command, buffer),
6996 CHECK_EQ(BacktraceData::frame_counter, 1);
7000 CheckDebuggerUnloaded();
7005 DebugLocalContext env;
7011 "function runTest(mirror) {"
7012 " return mirror.isString() && (mirror.length() == 5);"
7018 ->BindToCurrentContext()
7026 TEST(DebugBreakFunctionApply) {
7027 DebugLocalContext env;
7033 "function baz(x) { }"
7034 "function bar(x) { baz(); }"
7035 "function foo(){ bar.apply(this, [1]); }",
7046 break_point_hit_count = 0;
7047 max_break_point_hit_count = 10000;
7048 foo->Call(env->Global(), 0,
NULL);
7051 CHECK_GT(break_point_hit_count, 1);
7054 CheckDebuggerUnloaded();
7064 static void NamedGetterWithCallingContextCheck(
7069 CHECK(current == debugee_context);
7070 CHECK(current != debugger_context);
7072 CHECK(calling == debugee_context);
7073 CHECK(calling != debugger_context);
7081 static void DebugEventGetAtgumentPropertyValue(
7086 break_point_hit_count++;
7089 "(function(exec_state) {\n"
7090 " return (exec_state.frame(0).argumentValue(0).property('a').\n"
7091 " value().value() == 1);\n"
7101 TEST(CallingContextIsNotDebugContext) {
7104 DebugLocalContext env;
7111 debugee_context = env.context();
7117 NamedGetterWithCallingContextCheck);
7119 named->NewInstance());
7127 "function bar(x) { debugger; }"
7128 "function foo(){ bar(obj); }",
7131 break_point_hit_count = 0;
7133 CHECK_EQ(1, break_point_hit_count);
7138 CheckDebuggerUnloaded();
7142 TEST(DebugContextIsPreservedBetweenAccesses) {
7158 TEST(DebugEventContext) {
7164 expected_callback_data);
7168 expected_context.
Clear();
7171 CheckDebuggerUnloaded();
7175 static void* expected_break_data;
7176 static bool was_debug_break_called;
7177 static bool was_debug_event_called;
7181 was_debug_event_called =
true;
7183 was_debug_break_called =
true;
7189 TEST(DebugEventBreakData) {
7190 DebugLocalContext env;
7195 TestClientData::constructor_call_counter = 0;
7196 TestClientData::destructor_call_counter = 0;
7198 expected_break_data =
NULL;
7199 was_debug_event_called =
false;
7200 was_debug_break_called =
false;
7203 "(function(x){return x;})(1);"))
7205 CHECK(was_debug_event_called);
7206 CHECK(!was_debug_break_called);
7208 TestClientData* data1 =
new TestClientData();
7209 expected_break_data = data1;
7210 was_debug_event_called =
false;
7211 was_debug_break_called =
false;
7214 "(function(x){return x+1;})(1);"))
7216 CHECK(was_debug_event_called);
7217 CHECK(!was_debug_break_called);
7219 expected_break_data =
NULL;
7220 was_debug_event_called =
false;
7221 was_debug_break_called =
false;
7224 "(function(x){return x+2;})(1);"))
7226 CHECK(!was_debug_event_called);
7227 CHECK(was_debug_break_called);
7229 TestClientData* data2 =
new TestClientData();
7230 expected_break_data = data2;
7231 was_debug_event_called =
false;
7232 was_debug_break_called =
false;
7236 "(function(x){return x+3;})(1);"))
7238 CHECK(was_debug_event_called);
7239 CHECK(was_debug_break_called);
7241 CHECK_EQ(2, TestClientData::constructor_call_counter);
7242 CHECK_EQ(TestClientData::constructor_call_counter,
7243 TestClientData::destructor_call_counter);
7246 CheckDebuggerUnloaded();
7249 static bool debug_event_break_deoptimize_done =
false;
7251 static void DebugEventBreakDeoptimize(
7256 if (!frame_function_name.IsEmpty()) {
7263 frame_function_name->Call(exec_state, argc, argv);
7269 if (strcmp(fn,
"bar") == 0) {
7271 debug_event_break_deoptimize_done =
true;
7283 TEST(DeoptimizeDuringDebugBreak) {
7284 DebugLocalContext env;
7289 frame_function_name = CompileFunction(&env,
7290 frame_function_name_source,
7291 "frame_function_name");
7303 env->GetIsolate(),
"function bar(){}; bar()"))->Run();
7310 CHECK(debug_event_break_deoptimize_done);
7316 static void DebugEventBreakWithOptimizedStack(
7322 if (!frame_function_name.IsEmpty()) {
7323 for (
int i = 0; i < 2; i++) {
7330 frame_function_name->Call(exec_state, argc, argv);
7335 result = frame_argument_name->
Call(exec_state, argc, argv);
7336 CHECK(result->IsString());
7345 result = frame_argument_value->
Call(exec_state, argc, argv);
7346 CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i));
7348 result = frame_local_name->
Call(exec_state, argc, argv);
7349 CHECK(result->IsString());
7358 result = frame_local_value->
Call(exec_state, argc, argv);
7359 CHECK(result->IsUndefined() || (result->Int32Value() == 42));
7372 TEST(DebugBreakStackInspection) {
7373 DebugLocalContext env;
7376 frame_function_name =
7377 CompileFunction(&env, frame_function_name_source,
"frame_function_name");
7378 frame_argument_name =
7379 CompileFunction(&env, frame_argument_name_source,
"frame_argument_name");
7380 frame_argument_value = CompileFunction(&env,
7381 frame_argument_value_source,
7382 "frame_argument_value");
7384 CompileFunction(&env, frame_local_name_source,
"frame_local_name");
7386 CompileFunction(&env, frame_local_value_source,
"frame_local_value");
7392 env->Global()->Set(v8_str(
"scheduleBreak"), schedule_break);
7395 "function loop(count) {"
7397 " if (count < 1) { scheduleBreak(); loop(count + 1); }"
7405 static void TestDebugBreakInLoop(
const char* loop_head,
7406 const char** loop_bodies,
7407 const char* loop_tail) {
7409 static const int kBreaksPerTest = 100;
7411 for (
int i = 0; loop_bodies[i] !=
NULL; i++) {
7414 for (
int j = 0; j < 7; j++) {
7415 break_point_hit_count_deoptimize = j;
7417 break_point_hit_count_deoptimize = kBreaksPerTest;
7420 break_point_hit_count = 0;
7421 max_break_point_hit_count = kBreaksPerTest;
7422 terminate_after_max_break_point_hit =
true;
7424 EmbeddedVector<char, 1024> buffer;
7425 OS::SNPrintF(buffer,
7426 "function f() {%s%s%s}",
7427 loop_head, loop_bodies[i], loop_tail);
7430 CompileRun(buffer.start());
7437 CHECK_EQ(kBreaksPerTest, break_point_hit_count);
7445 TEST(DebugBreakLoop) {
7446 DebugLocalContext env;
7453 frame_count = CompileFunction(&env, frame_count_source,
"frame_count");
7455 CompileRun(
"var a = 1;");
7456 CompileRun(
"function g() { }");
7457 CompileRun(
"function h() { }");
7459 const char* loop_bodies[] = {
7462 "if (a == 0) { g() }",
7463 "if (a == 1) { g() }",
7464 "if (a == 0) { g() } else { h() }",
7465 "if (a == 0) { continue }",
7466 "if (a == 1) { continue }",
7467 "switch (a) { case 1: g(); }",
7468 "switch (a) { case 1: continue; }",
7469 "switch (a) { case 1: g(); break; default: h() }",
7470 "switch (a) { case 1: continue; break; default: h() }",
7474 TestDebugBreakInLoop(
"while (true) {", loop_bodies,
"}");
7475 TestDebugBreakInLoop(
"while (a == 1) {", loop_bodies,
"}");
7477 TestDebugBreakInLoop(
"do {", loop_bodies,
"} while (true)");
7478 TestDebugBreakInLoop(
"do {", loop_bodies,
"} while (a == 1)");
7480 TestDebugBreakInLoop(
"for (;;) {", loop_bodies,
"}");
7481 TestDebugBreakInLoop(
"for (;a == 1;) {", loop_bodies,
"}");
7485 CheckDebuggerUnloaded();
7491 static void DebugBreakInlineListener(
7496 int expected_frame_count = 4;
7497 int expected_line_number[] = {1, 4, 7, 12};
7506 OS::SNPrintF(script_vector,
"%%GetFrameCount(%d)", break_id);
7509 int frame_count = result->Int32Value();
7510 CHECK_EQ(expected_frame_count, frame_count);
7512 for (
int i = 0; i < frame_count; i++) {
7515 OS::SNPrintF(script_vector,
"%%GetFrameDetails(%d, %d)[5]", break_id, i);
7525 TEST(DebugBreakInline) {
7526 i::FLAG_allow_natives_syntax =
true;
7527 DebugLocalContext env;
7529 const char* source =
7530 "function debug(b) { \n"
7531 " if (b) debugger; \n"
7533 "function f(b) { \n"
7536 "function g(b) { \n"
7541 "%OptimizeFunctionOnNextCall(g); \n"
7546 inline_script->
Run();
7550 static void DebugEventStepNext(
7554 PrepareStep(StepNext);
7559 static void RunScriptInANewCFrame(
const char* source) {
7566 TEST(Regress131642) {
7575 DebugLocalContext env;
7582 const char* script_1 =
"debugger; throw new Error();";
7583 RunScriptInANewCFrame(script_1);
7586 const char* script_2 =
"[0].forEach(function() { });";
7587 CompileRun(script_2);
7601 TEST(DebuggerCreatesContextIffActive) {
7602 DebugLocalContext env;
7607 CompileRun(
"debugger;");
7611 CompileRun(
"debugger;");
7618 TEST(LiveEditEnabled) {
7619 v8::internal::FLAG_allow_natives_syntax =
true;
7623 CompileRun(
"%LiveEditCompareStrings('', '')");
7627 TEST(LiveEditDisabled) {
7628 v8::internal::FLAG_allow_natives_syntax =
true;
7632 CompileRun(
"%LiveEditCompareStrings('', '')");
7636 TEST(PrecompiledFunction) {
7641 DebugLocalContext env;
7647 CompileFunction(&env,
"function break_here(){}",
"break_here");
7648 SetBreakPoint(break_here, 0);
7650 const char* source =
7651 "var a = b = c = 1; \n"
7652 "function this_is_lazy() { \n"
7656 "function bar() { \n"
7657 " return \"bar\"; \n"
7662 CHECK(result->IsString());
7667 CheckDebuggerUnloaded();
7671 #endif // ENABLE_DEBUGGER_SUPPORT
void SetAccessor(Handle< String > name, AccessorGetterCallback getter, AccessorSetterCallback setter=0, Handle< Value > data=Handle< Value >(), AccessControl settings=DEFAULT, PropertyAttribute attribute=None, Handle< AccessorSignature > signature=Handle< AccessorSignature >())
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
V8_INLINE Local< Value > GetEmbedderData(int index)
static V8_INLINE Local< T > New(Isolate *isolate, Handle< T > that)
virtual DebugEvent GetEvent() const =0
static void SetLiveEditEnabled(bool enable, Isolate *isolate=NULL)
virtual bool WillStartRunning() const =0
int WriteUtf8(char *buffer, int length=-1, int *nchars_ref=NULL, int options=NO_OPTIONS) const
#define CHECK_EQ(expected, value)
static bool IsExecutionTerminating(Isolate *isolate=NULL)
Local< Value > Call(Handle< Value > recv, int argc, Handle< Value > argv[])
void CollectAllGarbage(int flags, const char *gc_reason=NULL, const GCCallbackFlags gc_callback_flags=kNoGCCallbackFlags)
Local< Value > Exception() const
bool StrictEquals(Handle< Value > that) const
V8_INLINE Isolate * GetIsolate() const
Local< Value > Get(Handle< Value > key)
static Smi * FromInt(int value)
virtual Handle< Object > GetEventData() const =0
void V8_EXPORT RegisterExtension(Extension *extension)
Local< Object > NewInstance()
#define STATIC_CHECK(test)
static ExternalTwoByteString * cast(Object *obj)
Local< ObjectTemplate > InstanceTemplate()
kSerializedDataOffset Object
virtual Handle< Value > GetCallbackData() const =0
static Local< Context > GetDebugContext()
virtual DebugEvent GetEvent() const =0
Local< Context > GetCurrentContext()
static Script * cast(Object *obj)
void(* MessageHandler2)(const Message &message)
static Local< Integer > New(Isolate *isolate, int32_t value)
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)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization 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 VFP3 instructions if available enable use of NEON instructions if 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 d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing 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 statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot testing_bool_flag testing_int_flag string flag tmp file in which to serialize heap Print the time it takes to lazily compile hydrogen code stubs concurrent_recompilation concurrent_sweeping Print usage message
virtual const uint16_t * data() const =0
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization 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 VFP3 instructions if available enable use of NEON instructions if 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 d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing 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 statistics of the maximum memory committed for the heap in name
v8::Isolate * GetIsolate()
static Local< UnboundScript > CompileUnbound(Isolate *isolate, Source *source, CompileOptions options=kNoCompileOptions)
void SetNamedPropertyHandler(NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter=0, NamedPropertyQueryCallback query=0, NamedPropertyDeleterCallback deleter=0, NamedPropertyEnumeratorCallback enumerator=0, Handle< Value > data=Handle< Value >())
StackGuard * stack_guard()
static void DebugBreakForCommand(ClientData *data=NULL, Isolate *isolate=NULL)
V8_INLINE Handle< Boolean > True(Isolate *isolate)
static void TerminateExecution(Isolate *isolate=NULL)
virtual Isolate * GetIsolate() const =0
void V8_Fatal(const char *file, int line, const char *format,...)
HANDLE HANDLE LPSTACKFRAME64 StackFrame
virtual size_t length() const =0
static bool AddMessageListener(MessageCallback that, Handle< Value > data=Handle< Value >())
void SetEmbedderData(int index, Handle< Value > value)
double StringToInt(UnicodeCache *unicode_cache, String *str, int radix)
static Local< ObjectTemplate > New()
V8_INLINE Isolate * GetIsolate() const
static void SetHostDispatchHandler(HostDispatchHandler handler, int period=100)
virtual Handle< Object > GetExecutionState() const =0
static const int kNoGCFlags
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >(), int length=0)
int32_t Int32Value() const
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *script_data=NULL)
static V8_INLINE Handle< T > Cast(Handle< S > that)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
static void DeoptimizeAll(Isolate *isolate)
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
V8_INLINE ReturnValue< T > GetReturnValue() const
static i::Isolate * i_isolate()
static void RemoveMessageListeners(MessageCallback that)
bool SetHiddenValue(Handle< String > key, Handle< Value > value)
static const int kMakeHeapIterableMask
virtual Handle< String > GetJSON() const =0
static Local< Number > New(Isolate *isolate, double value)
#define STATIC_ASCII_VECTOR(x)
static Local< Array > New(Isolate *isolate, int length=0)
V8_INLINE bool IsUndefined() const
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
V8_INLINE Handle< Primitive > Undefined(Isolate *isolate)
#define CHECK_NE(unexpected, value)
static V8_INLINE Local< T > Cast(Local< S > that)
void SetHiddenPrototype(bool value)
bool CollectGarbage(AllocationSpace space, const char *gc_reason=NULL, const GCCallbackFlags gc_callback_flags=kNoGCCallbackFlags)
int StrLength(const char *string)
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static Local< Object > New(Isolate *isolate)
V8_INLINE bool IsString() const
static Local< Context > New(Isolate *isolate, ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
static void SetMessageHandler2(MessageHandler2 handler)
int GetScriptLineNumber(Handle< Script > script, int code_pos)
V8_INLINE Handle< Boolean > False(Isolate *isolate)
Handle< String > InternalizeOneByteString(Vector< const uint8_t > str)
static void SetDebugMessageDispatchHandler(DebugMessageDispatchHandler handler, bool provide_locker=false)
void Continue(InterruptFlag after_what)
V8_INLINE bool IsEmpty() const
virtual ClientData * GetClientData() const =0
Local< Function > GetFunction()
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
static Local< String > NewExternal(Isolate *isolate, ExternalStringResource *resource)
static bool SetDebugEventListener2(EventCallback2 that, Handle< Value > data=Handle< Value >())
static Local< Value > Call(v8::Handle< v8::Function > fun, Handle< Value > data=Handle< Value >())
static Handle< Object > SetObjectProperty(Isolate *isolate, Handle< Object > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attr, StrictMode strict_mode)
virtual Handle< Context > GetEventContext() const =0
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization 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 VFP3 instructions if available enable use of NEON instructions if 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 d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
virtual Handle< Context > GetEventContext() const =0
static void SendCommand(const uint16_t *command, int length, ClientData *client_data=NULL, Isolate *isolate=NULL)
void SetIndexedPropertyHandler(IndexedPropertyGetterCallback getter, IndexedPropertySetterCallback setter=0, IndexedPropertyQueryCallback query=0, IndexedPropertyDeleterCallback deleter=0, IndexedPropertyEnumeratorCallback enumerator=0, Handle< Value > data=Handle< Value >())
static void DebugBreak(Isolate *isolate=NULL)
static Local< Value > GetMirror(v8::Handle< v8::Value > obj)
#define SMALL_STRING_BUFFER_SIZE
static void ProcessDebugMessages()
int CountNativeContexts()
bool Set(Handle< Value > key, Handle< Value > value, PropertyAttribute attribs=None)
static v8::Isolate * isolate()
static Local< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=kNormalString, int length=-1)
static JSFunction * cast(Object *obj)