Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: runtime/vm/debugger.cc

Issue 10383164: Debugger wire protocol: setting breakpoints (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "vm/flags.h" 11 #include "vm/flags.h"
12 #include "vm/globals.h" 12 #include "vm/globals.h"
13 #include "vm/longjump.h" 13 #include "vm/longjump.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/os.h" 16 #include "vm/os.h"
17 #include "vm/stack_frame.h" 17 #include "vm/stack_frame.h"
18 #include "vm/stub_code.h" 18 #include "vm/stub_code.h"
19 #include "vm/visitor.h" 19 #include "vm/visitor.h"
20 20
21 21
22 namespace dart { 22 namespace dart {
23 23
24 static const bool verbose = false; 24 static const bool verbose = false;
25 25
26 26
27 SourceBreakpoint::SourceBreakpoint(const Function& func, intptr_t token_index) 27 SourceBreakpoint::SourceBreakpoint(intptr_t id,
28 : function_(func.raw()), 28 const Function& func,
29 intptr_t token_index)
30 : id_(id),
31 function_(func.raw()),
29 token_index_(token_index), 32 token_index_(token_index),
30 line_number_(-1), 33 line_number_(-1),
31 is_enabled_(false), 34 is_enabled_(false),
32 next_(NULL) { 35 next_(NULL) {
33 ASSERT(!func.IsNull()); 36 ASSERT(!func.IsNull());
34 ASSERT((func.token_index() <= token_index_) && 37 ASSERT((func.token_index() <= token_index_) &&
35 (token_index_ < func.end_token_index())); 38 (token_index_ < func.end_token_index()));
36 } 39 }
37 40
38 41
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 RestoreCode(); 423 RestoreCode();
421 } 424 }
422 ASSERT(!is_enabled_); 425 ASSERT(!is_enabled_);
423 } 426 }
424 427
425 428
426 Debugger::Debugger() 429 Debugger::Debugger()
427 : isolate_(NULL), 430 : isolate_(NULL),
428 initialized_(false), 431 initialized_(false),
429 bp_handler_(NULL), 432 bp_handler_(NULL),
433 event_handler_(NULL),
434 next_id_(1),
435 stack_trace_(NULL),
430 src_breakpoints_(NULL), 436 src_breakpoints_(NULL),
431 code_breakpoints_(NULL), 437 code_breakpoints_(NULL),
432 resume_action_(kContinue), 438 resume_action_(kContinue),
433 ignore_breakpoints_(false) { 439 ignore_breakpoints_(false) {
434 } 440 }
435 441
436 442
437 Debugger::~Debugger() { 443 Debugger::~Debugger() {
438 ASSERT(src_breakpoints_ == NULL); 444 ASSERT(src_breakpoints_ == NULL);
439 ASSERT(code_breakpoints_ == NULL); 445 ASSERT(code_breakpoints_ == NULL);
446 ASSERT(stack_trace_ == NULL);
440 } 447 }
441 448
442 449
443 void Debugger::Shutdown() { 450 void Debugger::Shutdown() {
444 while (src_breakpoints_ != NULL) { 451 while (src_breakpoints_ != NULL) {
445 SourceBreakpoint* bpt = src_breakpoints_; 452 SourceBreakpoint* bpt = src_breakpoints_;
446 src_breakpoints_ = src_breakpoints_->next(); 453 src_breakpoints_ = src_breakpoints_->next();
447 delete bpt; 454 delete bpt;
448 } 455 }
449 while (code_breakpoints_ != NULL) { 456 while (code_breakpoints_ != NULL) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 (kind == PcDescriptors::kFuncCall) || 548 (kind == PcDescriptors::kFuncCall) ||
542 (kind == PcDescriptors::kReturn)) { 549 (kind == PcDescriptors::kReturn)) {
543 bpt = new CodeBreakpoint(target_function, i); 550 bpt = new CodeBreakpoint(target_function, i);
544 RegisterCodeBreakpoint(bpt); 551 RegisterCodeBreakpoint(bpt);
545 bpt->Enable(); 552 bpt->Enable();
546 } 553 }
547 } 554 }
548 } 555 }
549 556
550 557
558 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
559 if (event_handler_ != NULL) {
560 DebuggerEvent event;
561 event.type = kBreakpointResolved;
562 event.breakpoint = bpt;
563 (*event_handler_)(&event);
564 }
565 }
566
567
551 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func, 568 CodeBreakpoint* Debugger::MakeCodeBreakpoint(const Function& func,
552 intptr_t token_index) { 569 intptr_t token_index) {
553 ASSERT(func.HasCode()); 570 ASSERT(func.HasCode());
554 ASSERT(!func.HasOptimizedCode()); 571 ASSERT(!func.HasOptimizedCode());
555 Code& code = Code::Handle(func.unoptimized_code()); 572 Code& code = Code::Handle(func.unoptimized_code());
556 ASSERT(!code.IsNull()); 573 ASSERT(!code.IsNull());
557 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 574 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
558 intptr_t best_fit_index = -1; 575 intptr_t best_fit_index = -1;
559 intptr_t best_fit = INT_MAX; 576 intptr_t best_fit = INT_MAX;
560 for (int i = 0; i < desc.Length(); i++) { 577 for (int i = 0; i < desc.Length(); i++) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 (target_function.end_token_index() <= token_index)) { 621 (target_function.end_token_index() <= token_index)) {
605 // The given token position is not within the target function. 622 // The given token position is not within the target function.
606 return NULL; 623 return NULL;
607 } 624 }
608 EnsureFunctionIsDeoptimized(target_function); 625 EnsureFunctionIsDeoptimized(target_function);
609 SourceBreakpoint* bpt = GetSourceBreakpoint(target_function, token_index); 626 SourceBreakpoint* bpt = GetSourceBreakpoint(target_function, token_index);
610 if (bpt != NULL) { 627 if (bpt != NULL) {
611 // A breakpoint for this location already exists, return it. 628 // A breakpoint for this location already exists, return it.
612 return bpt; 629 return bpt;
613 } 630 }
614 bpt = new SourceBreakpoint(target_function, token_index); 631 bpt = new SourceBreakpoint(nextId(), target_function, token_index);
615 RegisterSourceBreakpoint(bpt); 632 RegisterSourceBreakpoint(bpt);
616 if (verbose && !target_function.HasCode()) { 633 if (verbose && !target_function.HasCode()) {
617 OS::Print("Registering breakpoint for uncompiled function '%s'" 634 OS::Print("Registering breakpoint for uncompiled function '%s'"
618 " (%s:%d)\n", 635 " (%s:%d)\n",
619 String::Handle(target_function.name()).ToCString(), 636 String::Handle(target_function.name()).ToCString(),
620 String::Handle(bpt->SourceUrl()).ToCString(), 637 String::Handle(bpt->SourceUrl()).ToCString(),
621 bpt->LineNumber()); 638 bpt->LineNumber());
622 } 639 }
623 640
624 if (target_function.HasCode()) { 641 if (target_function.HasCode()) {
625 CodeBreakpoint* cbpt = MakeCodeBreakpoint(target_function, token_index); 642 CodeBreakpoint* cbpt = MakeCodeBreakpoint(target_function, token_index);
626 if (cbpt != NULL) { 643 if (cbpt != NULL) {
627 ASSERT(cbpt->src_bpt() == NULL); 644 ASSERT(cbpt->src_bpt() == NULL);
628 cbpt->set_src_bpt(bpt); 645 cbpt->set_src_bpt(bpt);
646 SignalBpResolved(bpt);
629 } else { 647 } else {
630 if (verbose) { 648 if (verbose) {
631 OS::Print("Failed to set breakpoint at '%s' line %d\n", 649 OS::Print("Failed to set breakpoint at '%s' line %d\n",
632 String::Handle(bpt->SourceUrl()).ToCString(), 650 String::Handle(bpt->SourceUrl()).ToCString(),
633 bpt->LineNumber()); 651 bpt->LineNumber());
634 } 652 }
635 } 653 }
636 } 654 }
637 bpt->Enable(); 655 bpt->Enable();
638 return bpt; 656 return bpt;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 871
854 872
855 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) { 873 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) {
856 bp_handler_ = handler; 874 bp_handler_ = handler;
857 if (bp_handler_ == NULL) { 875 if (bp_handler_ == NULL) {
858 bp_handler_ = &DefaultBreakpointHandler; 876 bp_handler_ = &DefaultBreakpointHandler;
859 } 877 }
860 } 878 }
861 879
862 880
881 void Debugger::SetEventHandler(EventHandler* handler) {
882 event_handler_ = handler;
883 }
884
885
863 void Debugger::BreakpointCallback() { 886 void Debugger::BreakpointCallback() {
864 ASSERT(initialized_); 887 ASSERT(initialized_);
865 888
866 if (ignore_breakpoints_) { 889 if (ignore_breakpoints_) {
867 return; 890 return;
868 } 891 }
869 DartFrameIterator iterator; 892 DartFrameIterator iterator;
870 StackFrame* frame = iterator.NextFrame(); 893 StackFrame* frame = iterator.NextFrame();
871 ASSERT(frame != NULL && frame->IsDartFrame()); 894 ASSERT(frame != NULL && frame->IsDartFrame());
872 CodeBreakpoint* bpt = GetCodeBreakpoint(frame->pc()); 895 CodeBreakpoint* bpt = GetCodeBreakpoint(frame->pc());
873 ASSERT(bpt != NULL); 896 ASSERT(bpt != NULL);
874 if (verbose) { 897 if (verbose) {
875 OS::Print(">>> %s breakpoint at %s:%d (Address %p)\n", 898 OS::Print(">>> %s breakpoint at %s:%d (Address %p)\n",
876 bpt->IsInternal() ? "hit internal" : "hit user", 899 bpt->IsInternal() ? "hit internal" : "hit user",
877 bpt ? String::Handle(bpt->SourceUrl()).ToCString() : "?", 900 bpt ? String::Handle(bpt->SourceUrl()).ToCString() : "?",
878 bpt ? bpt->LineNumber() : 0, 901 bpt ? bpt->LineNumber() : 0,
879 frame->pc()); 902 frame->pc());
880 } 903 }
904
881 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8); 905 DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
882 while (frame != NULL) { 906 while (frame != NULL) {
883 ASSERT(frame->IsValid()); 907 ASSERT(frame->IsValid());
884 ASSERT(frame->IsDartFrame()); 908 ASSERT(frame->IsDartFrame());
885 ActivationFrame* activation = 909 ActivationFrame* activation =
886 new ActivationFrame(frame->pc(), frame->fp(), frame->sp()); 910 new ActivationFrame(frame->pc(), frame->fp(), frame->sp());
887 stack_trace->AddActivation(activation); 911 stack_trace->AddActivation(activation);
888 frame = iterator.NextFrame(); 912 frame = iterator.NextFrame();
889 } 913 }
890 914
891 resume_action_ = kContinue; 915 resume_action_ = kContinue;
892 if (bp_handler_ != NULL) { 916 if (bp_handler_ != NULL) {
893 SourceBreakpoint* src_bpt = bpt->src_bpt(); 917 SourceBreakpoint* src_bpt = bpt->src_bpt();
918 ASSERT(stack_trace_ == NULL);
919 stack_trace_ = stack_trace;
894 (*bp_handler_)(src_bpt, stack_trace); 920 (*bp_handler_)(src_bpt, stack_trace);
921 stack_trace_ = NULL;
895 } 922 }
896 923
897 if (resume_action_ == kContinue) { 924 if (resume_action_ == kContinue) {
898 RemoveInternalBreakpoints(); 925 RemoveInternalBreakpoints();
899 } else if (resume_action_ == kStepOver) { 926 } else if (resume_action_ == kStepOver) {
900 Function& func = Function::Handle(bpt->function()); 927 Function& func = Function::Handle(bpt->function());
901 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) { 928 if (bpt->breakpoint_kind_ == PcDescriptors::kReturn) {
902 // If we are at the function return, do a StepOut action. 929 // If we are at the function return, do a StepOut action.
903 if (stack_trace->Length() > 1) { 930 if (stack_trace->Length() > 1) {
904 ActivationFrame* caller = stack_trace->ActivationFrameAt(1); 931 ActivationFrame* caller = stack_trace->ActivationFrameAt(1);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 bpt->set_function(closure); 1018 bpt->set_function(closure);
992 } else { 1019 } else {
993 if (verbose) { 1020 if (verbose) {
994 OS::Print("Enable pending breakpoint for function '%s'\n", 1021 OS::Print("Enable pending breakpoint for function '%s'\n",
995 String::Handle(lookup_function.name()).ToCString()); 1022 String::Handle(lookup_function.name()).ToCString());
996 } 1023 }
997 // Set breakpoint in newly compiled code of function func. 1024 // Set breakpoint in newly compiled code of function func.
998 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_index()); 1025 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_index());
999 if (cbpt != NULL) { 1026 if (cbpt != NULL) {
1000 cbpt->set_src_bpt(bpt); 1027 cbpt->set_src_bpt(bpt);
1028 SignalBpResolved(bpt);
1001 } 1029 }
1002 } 1030 }
1003 bpt->Enable(); // Enables the code breakpoint as well. 1031 bpt->Enable(); // Enables the code breakpoint as well.
1004 } 1032 }
1005 bpt = bpt->next(); 1033 bpt = bpt->next();
1006 } 1034 }
1007 } 1035 }
1008 1036
1009 1037
1010 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) { 1038 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) {
1011 CodeBreakpoint* bpt = code_breakpoints_; 1039 CodeBreakpoint* bpt = code_breakpoints_;
1012 while (bpt != NULL) { 1040 while (bpt != NULL) {
1013 if (bpt->pc() == breakpoint_address) { 1041 if (bpt->pc() == breakpoint_address) {
1014 return bpt; 1042 return bpt;
1015 } 1043 }
1016 bpt = bpt->next(); 1044 bpt = bpt->next();
1017 } 1045 }
1018 return NULL; 1046 return NULL;
1019 } 1047 }
1020 1048
1021 1049
1022 // Remove and delete the source breakpoint bpt and its associated 1050 // Remove and delete the source breakpoint bpt and its associated
1023 // code breakpoints. 1051 // code breakpoints.
1024 void Debugger::RemoveBreakpoint(SourceBreakpoint* bpt) { 1052 void Debugger::RemoveBreakpoint(intptr_t bp_id) {
1025 ASSERT(src_breakpoints_ != NULL); 1053 ASSERT(src_breakpoints_ != NULL);
1026 SourceBreakpoint* prev_bpt = NULL; 1054 SourceBreakpoint* prev_bpt = NULL;
1027 SourceBreakpoint* curr_bpt = src_breakpoints_; 1055 SourceBreakpoint* curr_bpt = src_breakpoints_;
1028 while (curr_bpt != NULL) { 1056 while (curr_bpt != NULL) {
1029 if (bpt == curr_bpt) { 1057 if (curr_bpt->id() == bp_id) {
1030 if (prev_bpt == NULL) { 1058 if (prev_bpt == NULL) {
1031 src_breakpoints_ = src_breakpoints_->next(); 1059 src_breakpoints_ = src_breakpoints_->next();
1032 } else { 1060 } else {
1033 prev_bpt->set_next(curr_bpt->next()); 1061 prev_bpt->set_next(curr_bpt->next());
1034 } 1062 }
1035 // Remove the code breakpoints associated with the source breakpoint. 1063 // Remove the code breakpoints associated with the source breakpoint.
1036 RemoveCodeBreakpoints(bpt); 1064 RemoveCodeBreakpoints(curr_bpt);
1037 delete bpt; 1065 delete curr_bpt;
1038 return; 1066 return;
1039 } 1067 }
1040 prev_bpt = curr_bpt; 1068 prev_bpt = curr_bpt;
1041 curr_bpt = curr_bpt->next(); 1069 curr_bpt = curr_bpt->next();
1042 } 1070 }
1043 // bpt is not a registered breakpoint, nothing to do. 1071 // bpt is not a registered breakpoint, nothing to do.
1044 } 1072 }
1045 1073
1046 1074
1047 // Remove and delete the code breakpoints that are associated with given 1075 // Remove and delete the code breakpoints that are associated with given
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 if ((bpt->function() == func.raw()) && 1110 if ((bpt->function() == func.raw()) &&
1083 (bpt->token_index() == token_index)) { 1111 (bpt->token_index() == token_index)) {
1084 return bpt; 1112 return bpt;
1085 } 1113 }
1086 bpt = bpt->next(); 1114 bpt = bpt->next();
1087 } 1115 }
1088 return NULL; 1116 return NULL;
1089 } 1117 }
1090 1118
1091 1119
1120 SourceBreakpoint* Debugger::GetBreakpointById(intptr_t id) {
1121 SourceBreakpoint* bpt = src_breakpoints_;
1122 while (bpt != NULL) {
1123 if (bpt->id() == id) {
1124 return bpt;
1125 }
1126 bpt = bpt->next();
1127 }
1128 return NULL;
1129 }
1130
1131
1092 void Debugger::RegisterSourceBreakpoint(SourceBreakpoint* bpt) { 1132 void Debugger::RegisterSourceBreakpoint(SourceBreakpoint* bpt) {
1093 ASSERT(bpt->next() == NULL); 1133 ASSERT(bpt->next() == NULL);
1094 bpt->set_next(src_breakpoints_); 1134 bpt->set_next(src_breakpoints_);
1095 src_breakpoints_ = bpt; 1135 src_breakpoints_ = bpt;
1096 } 1136 }
1097 1137
1098 1138
1099 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 1139 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
1100 ASSERT(bpt->next() == NULL); 1140 ASSERT(bpt->next() == NULL);
1101 bpt->set_next(code_breakpoints_); 1141 bpt->set_next(code_breakpoints_);
1102 code_breakpoints_ = bpt; 1142 code_breakpoints_ = bpt;
1103 } 1143 }
1104 1144
1105 } // namespace dart 1145 } // namespace dart
OLDNEW
« lib/json/json.dart ('K') | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698