| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/debugger.h" |
| 6 | 6 |
| 7 #include "vm/code_generator.h" | 7 #include "vm/code_generator.h" |
| 8 #include "vm/code_patcher.h" | 8 #include "vm/code_patcher.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 initialized_(false), | 469 initialized_(false), |
| 470 bp_handler_(NULL), | 470 bp_handler_(NULL), |
| 471 event_handler_(NULL), | 471 event_handler_(NULL), |
| 472 next_id_(1), | 472 next_id_(1), |
| 473 stack_trace_(NULL), | 473 stack_trace_(NULL), |
| 474 obj_cache_(NULL), | 474 obj_cache_(NULL), |
| 475 src_breakpoints_(NULL), | 475 src_breakpoints_(NULL), |
| 476 code_breakpoints_(NULL), | 476 code_breakpoints_(NULL), |
| 477 resume_action_(kContinue), | 477 resume_action_(kContinue), |
| 478 last_bpt_line_(-1), | 478 last_bpt_line_(-1), |
| 479 ignore_breakpoints_(false) { | 479 ignore_breakpoints_(false), |
| 480 pause_on_exception_(false), |
| 481 pause_on_unhandled_exception_(false) { |
| 480 } | 482 } |
| 481 | 483 |
| 482 | 484 |
| 483 Debugger::~Debugger() { | 485 Debugger::~Debugger() { |
| 484 ASSERT(src_breakpoints_ == NULL); | 486 ASSERT(src_breakpoints_ == NULL); |
| 485 ASSERT(code_breakpoints_ == NULL); | 487 ASSERT(code_breakpoints_ == NULL); |
| 486 ASSERT(stack_trace_ == NULL); | 488 ASSERT(stack_trace_ == NULL); |
| 487 ASSERT(obj_cache_ == NULL); | 489 ASSERT(obj_cache_ == NULL); |
| 488 } | 490 } |
| 489 | 491 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 601 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |
| 600 if (event_handler_ != NULL) { | 602 if (event_handler_ != NULL) { |
| 601 DebuggerEvent event; | 603 DebuggerEvent event; |
| 602 event.type = kBreakpointResolved; | 604 event.type = kBreakpointResolved; |
| 603 event.breakpoint = bpt; | 605 event.breakpoint = bpt; |
| 604 (*event_handler_)(&event); | 606 (*event_handler_)(&event); |
| 605 } | 607 } |
| 606 } | 608 } |
| 607 | 609 |
| 608 | 610 |
| 611 DebuggerStackTrace* Debugger::CollectStackTrace() { |
| 612 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); |
| 613 DartFrameIterator iterator; |
| 614 StackFrame* frame = iterator.NextFrame(); |
| 615 while (frame != NULL) { |
| 616 ASSERT(frame->IsValid()); |
| 617 ASSERT(frame->IsDartFrame()); |
| 618 ActivationFrame* activation = |
| 619 new ActivationFrame(frame->pc(), frame->fp(), frame->sp()); |
| 620 stack_trace->AddActivation(activation); |
| 621 frame = iterator.NextFrame(); |
| 622 } |
| 623 return stack_trace; |
| 624 } |
| 625 |
| 626 |
| 627 // TODO(hausner): Determine whether the exception is handled or not, and |
| 628 // check with the settings the user specified to determine whether the |
| 629 // debugger should pause or not. |
| 630 // For now, we just pause on TypeError and AssertionError exceptions. |
| 631 bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
| 632 const Object& exc) { |
| 633 const Class& exc_class = Class::Handle(exc.clazz()); |
| 634 const String& class_name = String::Handle(exc_class.Name()); |
| 635 // TODO(hausner): Note the poor man's type test. Replace with check for |
| 636 // actual class object or class id. |
| 637 return class_name.Equals("TypeError") || class_name.Equals("AssertionError"); |
| 638 } |
| 639 |
| 640 |
| 641 void Debugger::SignalExceptionThrown(const Object& exc) { |
| 642 if (ignore_breakpoints_) { |
| 643 return; |
| 644 } |
| 645 DebuggerStackTrace* stack_trace = CollectStackTrace(); |
| 646 if (!ShouldPauseOnException(stack_trace, exc)) { |
| 647 return; |
| 648 } |
| 649 // No single-stepping possible after this pause event. |
| 650 last_bpt_line_ = -1; |
| 651 if (event_handler_ != NULL) { |
| 652 ASSERT(stack_trace_ == NULL); |
| 653 stack_trace_ = stack_trace; |
| 654 ASSERT(obj_cache_ == NULL); |
| 655 obj_cache_ = new RemoteObjectCache(64); |
| 656 DebuggerEvent event; |
| 657 event.type = kExceptionThrown; |
| 658 event.exception = &exc; |
| 659 (*event_handler_)(&event); |
| 660 stack_trace_ = NULL; |
| 661 obj_cache_ = NULL; // Remote object cache is zone allocated. |
| 662 } |
| 663 } |
| 664 |
| 665 |
| 609 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func, | 666 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func, |
| 610 intptr_t token_index) { | 667 intptr_t token_index) { |
| 611 ASSERT(func.HasCode()); | 668 ASSERT(func.HasCode()); |
| 612 ASSERT(!func.HasOptimizedCode()); | 669 ASSERT(!func.HasOptimizedCode()); |
| 613 Code& code = Code::Handle(func.unoptimized_code()); | 670 Code& code = Code::Handle(func.unoptimized_code()); |
| 614 ASSERT(!code.IsNull()); | 671 ASSERT(!code.IsNull()); |
| 615 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 672 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| 616 intptr_t best_fit_index = -1; | 673 intptr_t best_fit_index = -1; |
| 617 intptr_t best_fit = INT_MAX; | 674 intptr_t best_fit = INT_MAX; |
| 618 for (int i = 0; i < desc.Length(); i++) { | 675 for (int i = 0; i < desc.Length(); i++) { |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 (fkind == RawFunction::kImplicitSetter) || | 1030 (fkind == RawFunction::kImplicitSetter) || |
| 974 (fkind == RawFunction::kConstImplicitGetter)) { | 1031 (fkind == RawFunction::kConstImplicitGetter)) { |
| 975 return false; | 1032 return false; |
| 976 } | 1033 } |
| 977 const Class& cls = Class::Handle(func.owner()); | 1034 const Class& cls = Class::Handle(func.owner()); |
| 978 const Library& lib = Library::Handle(cls.library()); | 1035 const Library& lib = Library::Handle(cls.library()); |
| 979 return lib.IsDebuggable(); | 1036 return lib.IsDebuggable(); |
| 980 } | 1037 } |
| 981 | 1038 |
| 982 | 1039 |
| 983 void Debugger::BreakpointCallback() { | 1040 void Debugger::SignalBpReached() { |
| 984 ASSERT(initialized_); | |
| 985 | |
| 986 if (ignore_breakpoints_) { | 1041 if (ignore_breakpoints_) { |
| 987 return; | 1042 return; |
| 988 } | 1043 } |
| 989 DartFrameIterator iterator; | 1044 DebuggerStackTrace* stack_trace = CollectStackTrace(); |
| 990 StackFrame* frame = iterator.NextFrame(); | 1045 ASSERT(stack_trace->Length() > 0); |
| 991 ASSERT(frame != NULL && frame->IsDartFrame()); | 1046 ActivationFrame* top_frame = stack_trace->ActivationFrameAt(0); |
| 992 CodeBreakpoint* bpt = GetCodeBreakpoint(frame->pc()); | 1047 ASSERT(top_frame != NULL); |
| 1048 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc()); |
| 993 ASSERT(bpt != NULL); | 1049 ASSERT(bpt != NULL); |
| 994 if (verbose) { | 1050 if (verbose) { |
| 995 OS::Print(">>> %s breakpoint at %s:%d (Address %p)\n", | 1051 OS::Print(">>> hit %s breakpoint at %s:%d (Address %p)\n", |
| 996 bpt->IsInternal() ? "hit internal" : "hit user", | 1052 bpt->IsInternal() ? "internal" : "user", |
| 997 bpt ? String::Handle(bpt->SourceUrl()).ToCString() : "?", | 1053 String::Handle(bpt->SourceUrl()).ToCString(), |
| 998 bpt ? bpt->LineNumber() : 0, | 1054 bpt->LineNumber(), |
| 999 frame->pc()); | 1055 top_frame->pc()); |
| 1000 } | 1056 } |
| 1001 | 1057 |
| 1002 if (!bpt->IsInternal()) { | 1058 if (!bpt->IsInternal()) { |
| 1003 // This is a user-defined breakpoint, so we call the breakpoint callback | 1059 // This is a user-defined breakpoint so we call the breakpoint |
| 1004 // even if it is on the same line as the previous breakpoint. | 1060 // callback even if it is on the same line as the previous breakpoint. |
| 1005 last_bpt_line_ = -1; | 1061 last_bpt_line_ = -1; |
| 1006 } | 1062 } |
| 1007 | 1063 |
| 1008 bool notify_frontend = | 1064 bool notify_frontend = |
| 1009 (last_bpt_line_ < 0) || (last_bpt_line_ != bpt->LineNumber()); | 1065 (last_bpt_line_ < 0) || (last_bpt_line_ != bpt->LineNumber()); |
| 1010 | 1066 |
| 1011 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); | |
| 1012 while (frame != NULL) { | |
| 1013 ASSERT(frame->IsValid()); | |
| 1014 ASSERT(frame->IsDartFrame()); | |
| 1015 ActivationFrame* activation = | |
| 1016 new ActivationFrame(frame->pc(), frame->fp(), frame->sp()); | |
| 1017 stack_trace->AddActivation(activation); | |
| 1018 frame = iterator.NextFrame(); | |
| 1019 } | |
| 1020 | |
| 1021 if (notify_frontend) { | 1067 if (notify_frontend) { |
| 1022 resume_action_ = kContinue; | 1068 resume_action_ = kContinue; |
| 1023 if (bp_handler_ != NULL) { | 1069 if (bp_handler_ != NULL) { |
| 1024 SourceBreakpoint* src_bpt = bpt->src_bpt(); | 1070 SourceBreakpoint* src_bpt = bpt->src_bpt(); |
| 1025 ASSERT(stack_trace_ == NULL); | 1071 ASSERT(stack_trace_ == NULL); |
| 1026 ASSERT(obj_cache_ == NULL); | 1072 ASSERT(obj_cache_ == NULL); |
| 1027 obj_cache_ = new RemoteObjectCache(64); | 1073 obj_cache_ = new RemoteObjectCache(64); |
| 1028 stack_trace_ = stack_trace; | 1074 stack_trace_ = stack_trace; |
| 1029 (*bp_handler_)(src_bpt, stack_trace); | 1075 (*bp_handler_)(src_bpt, stack_trace); |
| 1030 stack_trace_ = NULL; | 1076 stack_trace_ = NULL; |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 } | 1321 } |
| 1276 | 1322 |
| 1277 | 1323 |
| 1278 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1324 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1279 ASSERT(bpt->next() == NULL); | 1325 ASSERT(bpt->next() == NULL); |
| 1280 bpt->set_next(code_breakpoints_); | 1326 bpt->set_next(code_breakpoints_); |
| 1281 code_breakpoints_ = bpt; | 1327 code_breakpoints_ = bpt; |
| 1282 } | 1328 } |
| 1283 | 1329 |
| 1284 } // namespace dart | 1330 } // namespace dart |
| OLD | NEW |