Make VM debugger stop at every safe point

Debugger front-end can decide to ignore some steps and only halt
when the next line is reached.

R=iposva@google.com

Review URL: https://codereview.chromium.org//15359010

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22972 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
hausner@google.com 2013-05-21 23:07:22 +00:00
parent d7f7604cf0
commit b466bceb20
3 changed files with 15 additions and 37 deletions

View file

@ -779,7 +779,6 @@ Debugger::Debugger()
src_breakpoints_(NULL),
code_breakpoints_(NULL),
resume_action_(kContinue),
last_bpt_line_(-1),
ignore_breakpoints_(false),
exc_pause_info_(kNoPauseOnExceptions) {
}
@ -1024,8 +1023,6 @@ void Debugger::SignalExceptionThrown(const Instance& exc) {
if (!ShouldPauseOnException(stack_trace, exc)) {
return;
}
// No single-stepping possible after this pause event.
last_bpt_line_ = -1;
ASSERT(stack_trace_ == NULL);
stack_trace_ = stack_trace;
ASSERT(obj_cache_ == NULL);
@ -1532,31 +1529,19 @@ void Debugger::SignalBpReached() {
top_frame->pc());
}
if (!bpt->IsInternal()) {
// This is a user-defined breakpoint so we call the breakpoint
// callback even if it is on the same line as the previous breakpoint.
last_bpt_line_ = -1;
}
bool notify_frontend =
(last_bpt_line_ < 0) || (last_bpt_line_ != bpt->LineNumber());
if (notify_frontend) {
resume_action_ = kContinue;
if (event_handler_ != NULL) {
ASSERT(stack_trace_ == NULL);
ASSERT(obj_cache_ == NULL);
obj_cache_ = new RemoteObjectCache(64);
stack_trace_ = stack_trace;
DebuggerEvent event;
event.type = kBreakpointReached;
ASSERT(stack_trace->Length() > 0);
event.top_frame = stack_trace->ActivationFrameAt(0);
(*event_handler_)(&event);
stack_trace_ = NULL;
obj_cache_ = NULL; // Remote object cache is zone allocated.
last_bpt_line_ = bpt->LineNumber();
}
resume_action_ = kContinue;
if (event_handler_ != NULL) {
ASSERT(stack_trace_ == NULL);
ASSERT(obj_cache_ == NULL);
obj_cache_ = new RemoteObjectCache(64);
stack_trace_ = stack_trace;
DebuggerEvent event;
event.type = kBreakpointReached;
ASSERT(stack_trace->Length() > 0);
event.top_frame = stack_trace->ActivationFrameAt(0);
(*event_handler_)(&event);
stack_trace_ = NULL;
obj_cache_ = NULL; // Remote object cache is zone allocated.
}
Function& currently_instrumented_func = Function::Handle();
@ -1656,7 +1641,6 @@ void Debugger::SignalBpReached() {
if (func_to_instrument.IsNull() ||
(func_to_instrument.raw() != currently_instrumented_func.raw())) {
last_bpt_line_ = -1;
RemoveInternalBreakpoints(); // *bpt is now invalid.
if (!func_to_instrument.IsNull()) {
InstrumentForStepping(func_to_instrument);

View file

@ -373,10 +373,6 @@ class Debugger {
// Tells debugger what to do when resuming execution after a breakpoint.
ResumeAction resume_action_;
// If >= 0, last_bpt_line contains the line number of the last breakpoint
// location for which the breakpoint callback function was called.
intptr_t last_bpt_line_;
// Do not call back to breakpoint handler if this flag is set.
// Effectively this means ignoring breakpoints. Set when Dart code may
// be run as a side effect of getting values of fields.

View file

@ -361,10 +361,12 @@ void TestStepIntoHandler(Dart_IsolateId isolate_id,
"f1",
"foo",
"X.X.",
"X.X.",
"foo",
"X.kvmk",
"f2",
"X.kvmk",
"X.kvmk",
"foo",
"main"
};
@ -418,11 +420,7 @@ TEST_CASE(Debug_StepInto) {
LoadScript(kScriptChars);
Dart_SetPausedEventHandler(&TestStepIntoHandler);
// Set a breakpoint in function f1, then repeatedly step out until
// we get to main. We should see one breakpoint each in f1,
// foo, main, but not in f2.
SetBreakpointAtEntry("", "main");
breakpoint_hit = false;
breakpoint_hit_counter = 0;
Dart_Handle retval = Invoke("main");