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

Unified Diff: runtime/vm/debugger.cc

Issue 149123003: Handle all debugger stepping with the isolate single step flag (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/debugger.cc
===================================================================
--- runtime/vm/debugger.cc (revision 32072)
+++ runtime/vm/debugger.cc (working copy)
@@ -833,6 +833,7 @@
pause_event_(NULL),
obj_cache_(NULL),
stack_trace_(NULL),
+ stepping_fp_(0),
exc_pause_info_(kNoPauseOnExceptions) {
}
@@ -875,18 +876,18 @@
return Function::null();
}
+
void Debugger::SetSingleStep() {
- isolate_->set_single_step(true);
resume_action_ = kSingleStep;
}
+
void Debugger::SetStepOver() {
- isolate_->set_single_step(false);
resume_action_ = kStepOver;
}
+
void Debugger::SetStepOut() {
- isolate_->set_single_step(false);
resume_action_ = kStepOut;
}
@@ -967,7 +968,7 @@
}
-void Debugger::InstrumentForStepping(const Function& target_function) {
+void Debugger::SetInternalBreakpoints(const Function& target_function) {
if (target_function.is_native()) {
// Can't instrument native functions.
return;
@@ -1565,11 +1566,11 @@
void Debugger::OneTimeBreakAtEntry(const Function& target_function) {
- InstrumentForStepping(target_function);
+ SetInternalBreakpoints(target_function);
if (target_function.HasImplicitClosureFunction()) {
const Function& closure_func =
Function::Handle(target_function.ImplicitClosureFunction());
- InstrumentForStepping(closure_func);
+ SetInternalBreakpoints(closure_func);
}
}
@@ -1885,6 +1886,7 @@
void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
SourceBreakpoint* bpt) {
resume_action_ = kContinue;
+ stepping_fp_ = 0;
isolate_->set_single_step(false);
ASSERT(!IsPaused());
ASSERT(obj_cache_ == NULL);
@@ -1895,8 +1897,18 @@
}
-void Debugger::SingleStepCallback() {
- ASSERT(resume_action_ == kSingleStep);
+static uword DebuggableCallerFP(DebuggerStackTrace* stack_trace) {
+ for (intptr_t i = 1; i < stack_trace->Length(); i++) {
+ ActivationFrame* frame = stack_trace->FrameAt(i);
+ if (frame->IsDebuggable()) {
+ return frame->fp();
+ }
+ }
+ return 0;
+}
+
+
+void Debugger::DebuggerStepCallback() {
ASSERT(isolate_->single_step());
// We can't get here unless the debugger event handler enabled
// single stepping.
@@ -1905,16 +1917,27 @@
if (IsPaused()) return;
// Check whether we are in a Dart function that the user is
- // interested in.
+ // interested in. If we saved the frame pointer of a stack frame
+ // the user is interested in, we ignore the single step if we are
+ // in a callee of that frame. Note that we assume that the stack
+ // grows towards lower addresses.
ActivationFrame* frame = TopDartFrame();
ASSERT(frame != NULL);
- const Function& func = frame->function();
- if (!IsDebuggable(func)) {
+ if ((stepping_fp_ != 0) && (stepping_fp_ > frame->fp())) {
return;
}
+ // If an "interesting" frame is set, we are either in that frame
+ // or the program has returned from that frame. Let the user set
+ // the "interesting" frame again next time we pause.
+ stepping_fp_ = 0;
+
+ if (!frame->IsDebuggable()) {
+ return;
+ }
if (frame->TokenPos() == Scanner::kNoSourcePos) {
return;
}
+
// Don't pause for a single step if there is a breakpoint set
// at this location.
if (HasActiveBreakpoint(frame->pc())) {
@@ -1933,14 +1956,15 @@
stack_trace_ = CollectStackTrace();
SignalPausedEvent(frame, NULL);
- RemoveInternalBreakpoints();
- if (resume_action_ == kStepOver) {
- InstrumentForStepping(func);
+ if (resume_action_ == kSingleStep) {
+ isolate_->set_single_step(true);
+ stepping_fp_ = 0;
+ } else if (resume_action_ == kStepOver) {
+ isolate_->set_single_step(true);
+ stepping_fp_ = frame->fp();
} else if (resume_action_ == kStepOut) {
- if (stack_trace_->Length() > 1) {
- ActivationFrame* caller_frame = stack_trace_->FrameAt(1);
- InstrumentForStepping(caller_frame->function());
- }
+ isolate_->set_single_step(true);
+ stepping_fp_ = DebuggableCallerFP(stack_trace_);
}
stack_trace_ = NULL;
}
@@ -1950,7 +1974,7 @@
// We ignore this breakpoint when the VM is executing code invoked
// by the debugger to evaluate variables values, or when we see a nested
// breakpoint or exception event.
- if (ignore_breakpoints_ || IsPaused()) {
+ if (ignore_breakpoints_ || IsPaused() || (event_handler_ == NULL)) {
return;
}
DebuggerStackTrace* stack_trace = CollectStackTrace();
@@ -1960,14 +1984,9 @@
CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
ASSERT(bpt != NULL);
- bool report_bp = true;
- if (bpt->IsInternal() && !IsDebuggable(top_frame->function())) {
- report_bp = false;
- }
if (FLAG_verbose_debug) {
- OS::Print(">>> %s %s breakpoint at %s:%" Pd " "
+ OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
"(token %" Pd ") (address %#" Px ")\n",
- report_bp ? "hit" : "ignore",
bpt->IsInternal() ? "internal" : "user",
String::Handle(bpt->SourceUrl()).ToCString(),
bpt->LineNumber(),
@@ -1975,39 +1994,24 @@
top_frame->pc());
}
- if (report_bp && (event_handler_ != NULL)) {
- ASSERT(stack_trace_ == NULL);
- stack_trace_ = stack_trace;
- SignalPausedEvent(top_frame, bpt->src_bpt_);
- stack_trace_ = NULL;
- }
+ ASSERT(stack_trace_ == NULL);
+ stack_trace_ = stack_trace;
+ SignalPausedEvent(top_frame, bpt->src_bpt_);
+ stack_trace_ = NULL;
- Function& func_to_instrument = Function::Handle();
- if ((resume_action_ == kStepOver) &&
- (bpt->breakpoint_kind_ == PcDescriptors::kReturn)) {
- resume_action_ = kStepOut;
- }
- if (resume_action_ == kStepOver) {
- ASSERT(bpt->breakpoint_kind_ != PcDescriptors::kReturn);
- func_to_instrument = bpt->function();
+ if (resume_action_ == kSingleStep) {
+ isolate_->set_single_step(true);
+ stepping_fp_ = 0;
+ } else if (resume_action_ == kStepOver) {
+ isolate_->set_single_step(true);
+ stepping_fp_ = top_frame->fp();
} else if (resume_action_ == kStepOut) {
- if (stack_trace->Length() > 1) {
- ActivationFrame* caller_frame = stack_trace->FrameAt(1);
- func_to_instrument = caller_frame->function().raw();
- }
- } else {
- ASSERT((resume_action_ == kContinue) || (resume_action_ == kSingleStep));
- // Nothing to do here. Any potential instrumentation will be removed
- // below. Single stepping is handled by the single step callback.
+ isolate_->set_single_step(true);
+ stepping_fp_ = DebuggableCallerFP(stack_trace);
}
-
- if (func_to_instrument.IsNull() ||
- (func_to_instrument.raw() != bpt->function())) {
- RemoveInternalBreakpoints(); // *bpt is now invalid.
+ if (bpt->IsInternal()) {
+ RemoveInternalBreakpoints();
}
- if (!func_to_instrument.IsNull()) {
- InstrumentForStepping(func_to_instrument);
- }
}
« no previous file with comments | « runtime/vm/debugger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698