| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" |
| 5 #include "vm/dart_api_impl.h" | 6 #include "vm/dart_api_impl.h" |
| 6 #include "vm/dart_api_message.h" | 7 #include "vm/dart_api_message.h" |
| 7 #include "vm/debugger.h" | |
| 8 #include "vm/message.h" | 8 #include "vm/message.h" |
| 9 #include "vm/unit_test.h" | 9 #include "vm/unit_test.h" |
| 10 | 10 |
| 11 namespace dart { | 11 namespace dart { |
| 12 | 12 |
| 13 #ifndef PRODUCT | 13 #ifndef PRODUCT |
| 14 | 14 |
| 15 DECLARE_FLAG(bool, background_compilation); | 15 DECLARE_FLAG(bool, background_compilation); |
| 16 DECLARE_FLAG(bool, enable_inlining_annotations); | 16 DECLARE_FLAG(bool, enable_inlining_annotations); |
| 17 DECLARE_FLAG(bool, prune_dead_locals); | 17 DECLARE_FLAG(bool, prune_dead_locals); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 "test-lib\\/" | 276 "test-lib\\/" |
| 277 "0\",\"uri\":\"test-lib\",\"_kind\":\"script\"},\"line\":2}},{\"type\":" | 277 "0\",\"uri\":\"test-lib\",\"_kind\":\"script\"},\"line\":2}},{\"type\":" |
| 278 "\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/" | 278 "\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/" |
| 279 "3\",\"breakpointNumber\":3,\"resolved\":false,\"location\":{\"type\":" | 279 "3\",\"breakpointNumber\":3,\"resolved\":false,\"location\":{\"type\":" |
| 280 "\"UnresolvedSourceLocation\",\"scriptUri\":\"not_yet_loaded_script_" | 280 "\"UnresolvedSourceLocation\",\"scriptUri\":\"not_yet_loaded_script_" |
| 281 "uri\",\"line\":4}}]", | 281 "uri\",\"line\":4}}]", |
| 282 private_key.ToCString(), private_key.ToCString()); | 282 private_key.ToCString(), private_key.ToCString()); |
| 283 } | 283 } |
| 284 } | 284 } |
| 285 | 285 |
| 286 | |
| 287 static bool saw_paused_event = false; | 286 static bool saw_paused_event = false; |
| 288 | 287 |
| 289 static void InspectPausedEvent(Dart_IsolateId isolate_id, | 288 static void InspectPausedEvent(Dart_IsolateId isolate_id, |
| 290 intptr_t bp_id, | 289 intptr_t bp_id, |
| 291 const Dart_CodeLocation& loc) { | 290 const Dart_CodeLocation& loc) { |
| 292 Isolate* isolate = Isolate::Current(); | 291 Isolate* isolate = Isolate::Current(); |
| 293 Debugger* debugger = isolate->debugger(); | 292 Debugger* debugger = isolate->debugger(); |
| 294 | 293 |
| 295 // The debugger knows that it is paused, and why. | 294 // The debugger knows that it is paused, and why. |
| 296 EXPECT(debugger->IsPaused()); | 295 EXPECT(debugger->IsPaused()); |
| 297 const ServiceEvent* event = debugger->PauseEvent(); | 296 const ServiceEvent* event = debugger->PauseEvent(); |
| 298 EXPECT(event != NULL); | 297 EXPECT(event != NULL); |
| 299 EXPECT(event->kind() == ServiceEvent::kPauseBreakpoint); | 298 EXPECT(event->kind() == ServiceEvent::kPauseBreakpoint); |
| 300 saw_paused_event = true; | 299 saw_paused_event = true; |
| 301 } | 300 } |
| 302 | 301 |
| 303 | |
| 304 TEST_CASE(Debugger_PauseEvent) { | 302 TEST_CASE(Debugger_PauseEvent) { |
| 305 const char* kScriptChars = | 303 const char* kScriptChars = |
| 306 "main() {\n" | 304 "main() {\n" |
| 307 " var x = new StringBuffer();\n" | 305 " var x = new StringBuffer();\n" |
| 308 " x.write('won');\n" | 306 " x.write('won');\n" |
| 309 " x.write('too');\n" | 307 " x.write('too');\n" |
| 310 " return x.toString();\n" | 308 " return x.toString();\n" |
| 311 "}\n"; | 309 "}\n"; |
| 312 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 310 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 313 EXPECT_VALID(lib); | 311 EXPECT_VALID(lib); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 325 // Set a breakpoint and run. | 323 // Set a breakpoint and run. |
| 326 EXPECT_VALID(Dart_SetBreakpoint(NewString(TestCase::url()), 2)); | 324 EXPECT_VALID(Dart_SetBreakpoint(NewString(TestCase::url()), 2)); |
| 327 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 325 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 328 EXPECT_VALID(result); | 326 EXPECT_VALID(result); |
| 329 EXPECT(Dart_IsString(result)); | 327 EXPECT(Dart_IsString(result)); |
| 330 | 328 |
| 331 // We ran the code in InspectPausedEvent. | 329 // We ran the code in InspectPausedEvent. |
| 332 EXPECT(saw_paused_event); | 330 EXPECT(saw_paused_event); |
| 333 } | 331 } |
| 334 | 332 |
| 335 | |
| 336 static uint8_t* malloc_allocator(uint8_t* ptr, | 333 static uint8_t* malloc_allocator(uint8_t* ptr, |
| 337 intptr_t old_size, | 334 intptr_t old_size, |
| 338 intptr_t new_size) { | 335 intptr_t new_size) { |
| 339 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); | 336 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
| 340 return reinterpret_cast<uint8_t*>(new_ptr); | 337 return reinterpret_cast<uint8_t*>(new_ptr); |
| 341 } | 338 } |
| 342 | 339 |
| 343 | |
| 344 const char* rewind_frame_index = "-1"; | 340 const char* rewind_frame_index = "-1"; |
| 345 | 341 |
| 346 | |
| 347 // Build and send a fake resume OOB message for testing purposes. | 342 // Build and send a fake resume OOB message for testing purposes. |
| 348 void SendResumeMessage(Isolate* isolate) { | 343 void SendResumeMessage(Isolate* isolate) { |
| 349 // Format is: [ oob_type, port, seq, method_name, [keys], [values] ] | 344 // Format is: [ oob_type, port, seq, method_name, [keys], [values] ] |
| 350 Dart_CObject msg; | 345 Dart_CObject msg; |
| 351 Dart_CObject* list_values[6]; | 346 Dart_CObject* list_values[6]; |
| 352 msg.type = Dart_CObject_kArray; | 347 msg.type = Dart_CObject_kArray; |
| 353 msg.value.as_array.length = 6; | 348 msg.value.as_array.length = 6; |
| 354 msg.value.as_array.values = list_values; | 349 msg.value.as_array.values = list_values; |
| 355 | 350 |
| 356 Dart_CObject oob; | 351 Dart_CObject oob; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 ASSERT(success); | 421 ASSERT(success); |
| 427 | 422 |
| 428 // Post the message at the given port. | 423 // Post the message at the given port. |
| 429 success = PortMap::PostMessage(new Message(isolate->main_port(), buffer, | 424 success = PortMap::PostMessage(new Message(isolate->main_port(), buffer, |
| 430 writer.BytesWritten(), | 425 writer.BytesWritten(), |
| 431 Message::kOOBPriority)); | 426 Message::kOOBPriority)); |
| 432 ASSERT(success); | 427 ASSERT(success); |
| 433 } | 428 } |
| 434 } | 429 } |
| 435 | 430 |
| 436 | |
| 437 static void RewindOnce(Dart_IsolateId isolate_id, | 431 static void RewindOnce(Dart_IsolateId isolate_id, |
| 438 intptr_t bp_id, | 432 intptr_t bp_id, |
| 439 const Dart_CodeLocation& loc) { | 433 const Dart_CodeLocation& loc) { |
| 440 bool first_time = !saw_paused_event; | 434 bool first_time = !saw_paused_event; |
| 441 saw_paused_event = true; | 435 saw_paused_event = true; |
| 442 if (first_time) { | 436 if (first_time) { |
| 443 Thread* T = Thread::Current(); | 437 Thread* T = Thread::Current(); |
| 444 Isolate* I = T->isolate(); | 438 Isolate* I = T->isolate(); |
| 445 // TODO(turnidge): It is weird that the isolate can get to this | 439 // TODO(turnidge): It is weird that the isolate can get to this |
| 446 // point in our tests without being marked runnable. Clear this up | 440 // point in our tests without being marked runnable. Clear this up |
| 447 // at some point. | 441 // at some point. |
| 448 I->set_is_runnable(true); | 442 I->set_is_runnable(true); |
| 449 SendResumeMessage(I); | 443 SendResumeMessage(I); |
| 450 I->PauseEventHandler(); | 444 I->PauseEventHandler(); |
| 451 } | 445 } |
| 452 } | 446 } |
| 453 | 447 |
| 454 | |
| 455 TEST_CASE(Debugger_RewindOneFrame_Unoptimized) { | 448 TEST_CASE(Debugger_RewindOneFrame_Unoptimized) { |
| 456 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); | 449 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); |
| 457 | 450 |
| 458 // These variables are global state used by RewindOnce. | 451 // These variables are global state used by RewindOnce. |
| 459 saw_paused_event = false; | 452 saw_paused_event = false; |
| 460 rewind_frame_index = "1"; | 453 rewind_frame_index = "1"; |
| 461 | 454 |
| 462 const char* kScriptChars = | 455 const char* kScriptChars = |
| 463 "import 'dart:developer';\n" | 456 "import 'dart:developer';\n" |
| 464 "\n" | 457 "\n" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 483 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 476 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
| 484 const char* result_cstr; | 477 const char* result_cstr; |
| 485 EXPECT_VALID(result); | 478 EXPECT_VALID(result); |
| 486 EXPECT(Dart_IsString(result)); | 479 EXPECT(Dart_IsString(result)); |
| 487 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); | 480 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); |
| 488 EXPECT_STREQ("enter(main) enter(foo) enter(foo) exit(foo) exit(main) ", | 481 EXPECT_STREQ("enter(main) enter(foo) enter(foo) exit(foo) exit(main) ", |
| 489 result_cstr); | 482 result_cstr); |
| 490 EXPECT(saw_paused_event); | 483 EXPECT(saw_paused_event); |
| 491 } | 484 } |
| 492 | 485 |
| 493 | |
| 494 TEST_CASE(Debugger_RewindTwoFrames_Unoptimized) { | 486 TEST_CASE(Debugger_RewindTwoFrames_Unoptimized) { |
| 495 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); | 487 SetFlagScope<bool> sfs(&FLAG_trace_rewind, true); |
| 496 | 488 |
| 497 // These variables are global state used by RewindOnce. | 489 // These variables are global state used by RewindOnce. |
| 498 saw_paused_event = false; | 490 saw_paused_event = false; |
| 499 rewind_frame_index = "2"; | 491 rewind_frame_index = "2"; |
| 500 | 492 |
| 501 const char* kScriptChars = | 493 const char* kScriptChars = |
| 502 "import 'dart:developer';\n" | 494 "import 'dart:developer';\n" |
| 503 "\n" | 495 "\n" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 530 EXPECT_VALID(result); | 522 EXPECT_VALID(result); |
| 531 EXPECT(Dart_IsString(result)); | 523 EXPECT(Dart_IsString(result)); |
| 532 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); | 524 EXPECT_VALID(Dart_StringToCString(result, &result_cstr)); |
| 533 EXPECT_STREQ( | 525 EXPECT_STREQ( |
| 534 "enter(main) enter(bar) enter(foo) enter(bar) enter(foo) " | 526 "enter(main) enter(bar) enter(foo) enter(bar) enter(foo) " |
| 535 "exit(foo) exit(bar) exit(main) ", | 527 "exit(foo) exit(bar) exit(main) ", |
| 536 result_cstr); | 528 result_cstr); |
| 537 EXPECT(saw_paused_event); | 529 EXPECT(saw_paused_event); |
| 538 } | 530 } |
| 539 | 531 |
| 540 | |
| 541 TEST_CASE(Debugger_Rewind_Optimized) { | 532 TEST_CASE(Debugger_Rewind_Optimized) { |
| 542 SetFlagScope<bool> sfs1(&FLAG_trace_rewind, true); | 533 SetFlagScope<bool> sfs1(&FLAG_trace_rewind, true); |
| 543 SetFlagScope<bool> sfs2(&FLAG_prune_dead_locals, false); | 534 SetFlagScope<bool> sfs2(&FLAG_prune_dead_locals, false); |
| 544 SetFlagScope<bool> sfs3(&FLAG_enable_inlining_annotations, true); | 535 SetFlagScope<bool> sfs3(&FLAG_enable_inlining_annotations, true); |
| 545 SetFlagScope<bool> sfs4(&FLAG_background_compilation, false); | 536 SetFlagScope<bool> sfs4(&FLAG_background_compilation, false); |
| 546 SetFlagScope<int> sfs5(&FLAG_optimization_counter_threshold, 10); | 537 SetFlagScope<int> sfs5(&FLAG_optimization_counter_threshold, 10); |
| 547 | 538 |
| 548 // These variables are global state used by RewindOnce. | 539 // These variables are global state used by RewindOnce. |
| 549 saw_paused_event = false; | 540 saw_paused_event = false; |
| 550 rewind_frame_index = "2"; | 541 rewind_frame_index = "2"; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 "enter(bar1) enter(bar2) enter(bar3) enter(foo) " | 606 "enter(bar1) enter(bar2) enter(bar3) enter(foo) " |
| 616 "enter(bar3) enter(foo) " | 607 "enter(bar3) enter(foo) " |
| 617 "exit(foo) exit(bar3) exit(bar2) exit(bar1) ", | 608 "exit(foo) exit(bar3) exit(bar2) exit(bar1) ", |
| 618 result_cstr); | 609 result_cstr); |
| 619 EXPECT(saw_paused_event); | 610 EXPECT(saw_paused_event); |
| 620 } | 611 } |
| 621 | 612 |
| 622 #endif // !PRODUCT | 613 #endif // !PRODUCT |
| 623 | 614 |
| 624 } // namespace dart | 615 } // namespace dart |
| OLD | NEW |