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

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

Issue 1641793002: Fix a bug where breakpoints where not getting properly deleted. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: reorder line Created 4 years, 10 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
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 next_id_(1), 1251 next_id_(1),
1252 latent_locations_(NULL), 1252 latent_locations_(NULL),
1253 breakpoint_locations_(NULL), 1253 breakpoint_locations_(NULL),
1254 code_breakpoints_(NULL), 1254 code_breakpoints_(NULL),
1255 resume_action_(kContinue), 1255 resume_action_(kContinue),
1256 ignore_breakpoints_(false), 1256 ignore_breakpoints_(false),
1257 pause_event_(NULL), 1257 pause_event_(NULL),
1258 obj_cache_(NULL), 1258 obj_cache_(NULL),
1259 stack_trace_(NULL), 1259 stack_trace_(NULL),
1260 stepping_fp_(0), 1260 stepping_fp_(0),
1261 skip_next_step_(false),
1261 exc_pause_info_(kNoPauseOnExceptions) { 1262 exc_pause_info_(kNoPauseOnExceptions) {
1262 } 1263 }
1263 1264
1264 1265
1265 Debugger::~Debugger() { 1266 Debugger::~Debugger() {
1266 isolate_id_ = ILLEGAL_ISOLATE_ID; 1267 isolate_id_ = ILLEGAL_ISOLATE_ID;
1267 ASSERT(!IsPaused()); 1268 ASSERT(!IsPaused());
1268 ASSERT(latent_locations_ == NULL); 1269 ASSERT(latent_locations_ == NULL);
1269 ASSERT(breakpoint_locations_ == NULL); 1270 ASSERT(breakpoint_locations_ == NULL);
1270 ASSERT(code_breakpoints_ == NULL); 1271 ASSERT(code_breakpoints_ == NULL);
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after
2525 } 2526 }
2526 2527
2527 2528
2528 void Debugger::EnterSingleStepMode() { 2529 void Debugger::EnterSingleStepMode() {
2529 stepping_fp_ = 0; 2530 stepping_fp_ = 0;
2530 DeoptimizeWorld(); 2531 DeoptimizeWorld();
2531 isolate_->set_single_step(true); 2532 isolate_->set_single_step(true);
2532 } 2533 }
2533 2534
2534 2535
2535 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) { 2536 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
2537 bool skip_next_step) {
2536 stepping_fp_ = 0; 2538 stepping_fp_ = 0;
2537 if (resume_action_ == kSingleStep) { 2539 if (resume_action_ == kSingleStep) {
2538 // When single stepping, we need to deoptimize because we might be 2540 // When single stepping, we need to deoptimize because we might be
2539 // stepping into optimized code. This happens in particular if 2541 // stepping into optimized code. This happens in particular if
2540 // the isolate has been interrupted, but can happen in other cases 2542 // the isolate has been interrupted, but can happen in other cases
2541 // as well. We need to deoptimize the world in case we are about 2543 // as well. We need to deoptimize the world in case we are about
2542 // to call an optimized function. 2544 // to call an optimized function.
2543 DeoptimizeWorld(); 2545 DeoptimizeWorld();
2544 isolate_->set_single_step(true); 2546 isolate_->set_single_step(true);
2547 skip_next_step_ = skip_next_step;
2545 if (FLAG_verbose_debug) { 2548 if (FLAG_verbose_debug) {
2546 OS::Print("HandleSteppingRequest- kSingleStep\n"); 2549 OS::Print("HandleSteppingRequest- kSingleStep\n");
2547 } 2550 }
2548 } else if (resume_action_ == kStepOver) { 2551 } else if (resume_action_ == kStepOver) {
2549 DeoptimizeWorld(); 2552 DeoptimizeWorld();
2550 isolate_->set_single_step(true); 2553 isolate_->set_single_step(true);
2554 skip_next_step_ = skip_next_step;
2551 ASSERT(stack_trace->Length() > 0); 2555 ASSERT(stack_trace->Length() > 0);
2552 stepping_fp_ = stack_trace->FrameAt(0)->fp(); 2556 stepping_fp_ = stack_trace->FrameAt(0)->fp();
2553 if (FLAG_verbose_debug) { 2557 if (FLAG_verbose_debug) {
2554 OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_); 2558 OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
2555 } 2559 }
2556 } else if (resume_action_ == kStepOut) { 2560 } else if (resume_action_ == kStepOut) {
2557 DeoptimizeWorld(); 2561 DeoptimizeWorld();
2558 isolate_->set_single_step(true); 2562 isolate_->set_single_step(true);
2559 // Find topmost caller that is debuggable. 2563 // Find topmost caller that is debuggable.
2560 for (intptr_t i = 1; i < stack_trace->Length(); i++) { 2564 for (intptr_t i = 1; i < stack_trace->Length(); i++) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 Pause(&event); 2621 Pause(&event);
2618 } 2622 }
2619 2623
2620 2624
2621 RawError* Debugger::DebuggerStepCallback() { 2625 RawError* Debugger::DebuggerStepCallback() {
2622 ASSERT(isolate_->single_step()); 2626 ASSERT(isolate_->single_step());
2623 // Don't pause recursively. 2627 // Don't pause recursively.
2624 if (IsPaused()) { 2628 if (IsPaused()) {
2625 return Error::null(); 2629 return Error::null();
2626 } 2630 }
2631 if (skip_next_step_) {
2632 skip_next_step_ = false;
2633 return Error::null();
2634 }
2627 2635
2628 // Check whether we are in a Dart function that the user is 2636 // Check whether we are in a Dart function that the user is
2629 // interested in. If we saved the frame pointer of a stack frame 2637 // interested in. If we saved the frame pointer of a stack frame
2630 // the user is interested in, we ignore the single step if we are 2638 // the user is interested in, we ignore the single step if we are
2631 // in a callee of that frame. Note that we assume that the stack 2639 // in a callee of that frame. Note that we assume that the stack
2632 // grows towards lower addresses. 2640 // grows towards lower addresses.
2633 ActivationFrame* frame = TopDartFrame(); 2641 ActivationFrame* frame = TopDartFrame();
2634 ASSERT(frame != NULL); 2642 ASSERT(frame != NULL);
2635 2643
2636 if (stepping_fp_ != 0) { 2644 if (stepping_fp_ != 0) {
(...skipping 11 matching lines...) Expand all
2648 } 2656 }
2649 } 2657 }
2650 2658
2651 if (!frame->IsDebuggable()) { 2659 if (!frame->IsDebuggable()) {
2652 return Error::null(); 2660 return Error::null();
2653 } 2661 }
2654 if (!Token::IsDebugPause(frame->TokenPos())) { 2662 if (!Token::IsDebugPause(frame->TokenPos())) {
2655 return Error::null(); 2663 return Error::null();
2656 } 2664 }
2657 2665
2658 // Don't pause for a single step if there is a breakpoint set 2666 // If there is an active breakpoint at this pc, then we should have
2659 // at this location. 2667 // already bailed out of this function in the skip_next_step_ test
2660 if (HasActiveBreakpoint(frame->pc())) { 2668 // above.
2661 return Error::null(); 2669 ASSERT(!HasActiveBreakpoint(frame->pc()));
2662 }
2663 2670
2664 if (FLAG_verbose_debug) { 2671 if (FLAG_verbose_debug) {
2665 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", 2672 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
2666 String::Handle(frame->SourceUrl()).ToCString(), 2673 String::Handle(frame->SourceUrl()).ToCString(),
2667 frame->LineNumber(), 2674 frame->LineNumber(),
2668 String::Handle(frame->QualifiedFunctionName()).ToCString(), 2675 String::Handle(frame->QualifiedFunctionName()).ToCString(),
2669 frame->TokenPos()); 2676 frame->TokenPos());
2670 } 2677 }
2671 2678
2672 ASSERT(stack_trace_ == NULL); 2679 ASSERT(stack_trace_ == NULL);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 cbpt->IsInternal() ? "internal" : "user", 2758 cbpt->IsInternal() ? "internal" : "user",
2752 String::Handle(cbpt->SourceUrl()).ToCString(), 2759 String::Handle(cbpt->SourceUrl()).ToCString(),
2753 cbpt->LineNumber(), 2760 cbpt->LineNumber(),
2754 cbpt->token_pos(), 2761 cbpt->token_pos(),
2755 top_frame->pc()); 2762 top_frame->pc());
2756 } 2763 }
2757 2764
2758 ASSERT(stack_trace_ == NULL); 2765 ASSERT(stack_trace_ == NULL);
2759 stack_trace_ = stack_trace; 2766 stack_trace_ = stack_trace;
2760 SignalPausedEvent(top_frame, bpt_hit); 2767 SignalPausedEvent(top_frame, bpt_hit);
2761 HandleSteppingRequest(stack_trace_); 2768 // When we single step from a user breakpoint, our next stepping
2769 // point will be at the exact same pc. Skip it.
2770 HandleSteppingRequest(stack_trace_, true /* skip next step */);
2762 stack_trace_ = NULL; 2771 stack_trace_ = NULL;
2763 if (cbpt->IsInternal()) { 2772 if (cbpt->IsInternal()) {
2764 RemoveInternalBreakpoints(); 2773 RemoveInternalBreakpoints();
2765 } 2774 }
2766 2775
2767 // If any error occurred while in the debug message loop, return it here. 2776 // If any error occurred while in the debug message loop, return it here.
2768 const Error& error = 2777 const Error& error =
2769 Error::Handle(isolate_->object_store()->sticky_error()); 2778 Error::Handle(isolate_->object_store()->sticky_error());
2770 isolate_->object_store()->clear_sticky_error(); 2779 isolate_->object_store()->clear_sticky_error();
2771 return error.raw(); 2780 return error.raw();
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
3114 } 3123 }
3115 3124
3116 SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt); 3125 SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
3117 3126
3118 // Remove references from the current debugger pause event. 3127 // Remove references from the current debugger pause event.
3119 if (pause_event_ != NULL && 3128 if (pause_event_ != NULL &&
3120 pause_event_->type() == DebuggerEvent::kBreakpointReached && 3129 pause_event_->type() == DebuggerEvent::kBreakpointReached &&
3121 pause_event_->breakpoint() == curr_bpt) { 3130 pause_event_->breakpoint() == curr_bpt) {
3122 pause_event_->set_breakpoint(NULL); 3131 pause_event_->set_breakpoint(NULL);
3123 } 3132 }
3124 return; 3133 break;
3125 } 3134 }
3126 3135
3127 prev_bpt = curr_bpt; 3136 prev_bpt = curr_bpt;
3128 curr_bpt = curr_bpt->next(); 3137 curr_bpt = curr_bpt->next();
3129 } 3138 }
3130 3139
3131 if (curr_loc->breakpoints() == NULL) { 3140 if (curr_loc->breakpoints() == NULL) {
3132 if (prev_loc == NULL) { 3141 if (prev_loc == NULL) {
3133 breakpoint_locations_ = curr_loc->next(); 3142 breakpoint_locations_ = curr_loc->next();
3134 } else { 3143 } else {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3253 } 3262 }
3254 3263
3255 3264
3256 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 3265 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3257 ASSERT(bpt->next() == NULL); 3266 ASSERT(bpt->next() == NULL);
3258 bpt->set_next(code_breakpoints_); 3267 bpt->set_next(code_breakpoints_);
3259 code_breakpoints_ = bpt; 3268 code_breakpoints_ = bpt;
3260 } 3269 }
3261 3270
3262 } // namespace dart 3271 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698