| Index: runtime/vm/debugger.cc
|
| diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
|
| index d9a8d97139f66af3d32b93302b0df2b98327694d..15289c79a1f92277c63ac46f2302feb35a5915ae 100644
|
| --- a/runtime/vm/debugger.cc
|
| +++ b/runtime/vm/debugger.cc
|
| @@ -19,6 +19,7 @@
|
| #include "vm/object_store.h"
|
| #include "vm/os.h"
|
| #include "vm/port.h"
|
| +#include "vm/service_event.h"
|
| #include "vm/service_isolate.h"
|
| #include "vm/service.h"
|
| #include "vm/stack_frame.h"
|
| @@ -116,7 +117,7 @@ void SourceBreakpoint::SetResolved(const Function& func, intptr_t token_pos) {
|
| function_ = func.raw();
|
| token_pos_ = token_pos;
|
| end_token_pos_ = token_pos;
|
| - line_number_ = -1; // Recalcualte lazily.
|
| + line_number_ = -1; // Recalculate lazily.
|
| is_resolved_ = true;
|
| }
|
|
|
| @@ -173,7 +174,6 @@ void SourceBreakpoint::PrintJSON(JSONStream* stream) {
|
|
|
| jsobj.AddPropertyF("id", "breakpoints/%" Pd "", id());
|
| jsobj.AddProperty("breakpointNumber", id());
|
| - jsobj.AddProperty("enabled", IsEnabled());
|
| jsobj.AddProperty("resolved", IsResolved());
|
|
|
| Library& library = Library::Handle(isolate);
|
| @@ -230,13 +230,25 @@ void Debugger::InvokeEventHandler(DebuggerEvent* event) {
|
|
|
| // Give the event to the Service first, as the debugger event handler
|
| // may go into a message loop and the Service will not.
|
| - if (Service::NeedsDebuggerEvents()) {
|
| - Service::HandleDebuggerEvent(event);
|
| + //
|
| + // kBreakpointResolved events are handled differently in the vm
|
| + // service, so suppress them here.
|
| + if (Service::NeedsDebuggerEvents() &&
|
| + (event->type() != DebuggerEvent::kBreakpointResolved)) {
|
| + ServiceEvent service_event(event);
|
| + Service::HandleEvent(&service_event);
|
| }
|
|
|
| if (event_handler_ != NULL) {
|
| (*event_handler_)(event);
|
| }
|
| +
|
| + if (Service::NeedsDebuggerEvents() && event->IsPauseEvent()) {
|
| + // If we were paused, notify the service that we have resumed.
|
| + ServiceEvent service_event(event->isolate(), ServiceEvent::kResume);
|
| + service_event.set_top_frame(event->top_frame());
|
| + Service::HandleEvent(&service_event);
|
| + }
|
| }
|
|
|
|
|
| @@ -247,6 +259,7 @@ void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
|
| if (type == DebuggerEvent::kIsolateInterrupted) {
|
| DebuggerStackTrace* trace = CollectStackTrace();
|
| ASSERT(trace->Length() > 0);
|
| + event.set_top_frame(trace->FrameAt(0));
|
| ASSERT(stack_trace_ == NULL);
|
| stack_trace_ = trace;
|
| resume_action_ = kContinue;
|
| @@ -269,6 +282,18 @@ void Debugger::SignalIsolateInterrupted() {
|
| }
|
|
|
|
|
| +// The vm service handles breakpoint notifications in a different way
|
| +// than the regular debugger breakpoint notifications.
|
| +static void SendServiceBreakpointEvent(ServiceEvent::EventType type,
|
| + SourceBreakpoint* bpt) {
|
| + if (Service::NeedsDebuggerEvents() /*&& !bpt->IsOneShot()*/) {
|
| + ServiceEvent service_event(Isolate::Current(), type);
|
| + service_event.set_breakpoint(bpt);
|
| + Service::HandleEvent(&service_event);
|
| + }
|
| +}
|
| +
|
| +
|
| const char* Debugger::QualifiedFunctionName(const Function& func) {
|
| const String& func_name = String::Handle(func.name());
|
| Class& func_class = Class::Handle(func.Owner());
|
| @@ -509,47 +534,6 @@ RawContext* ActivationFrame::GetSavedCurrentContext() {
|
| }
|
|
|
|
|
| -const char* DebuggerEvent::EventTypeToCString(EventType type) {
|
| - switch (type) {
|
| - case kBreakpointReached:
|
| - return "BreakpointReached";
|
| - case kBreakpointResolved:
|
| - return "BreakpointResolved";
|
| - case kExceptionThrown:
|
| - return "ExceptionThrown";
|
| - case kIsolateCreated:
|
| - return "IsolateCreated";
|
| - case kIsolateShutdown:
|
| - return "IsolateShutdown";
|
| - case kIsolateInterrupted:
|
| - return "IsolateInterrupted";
|
| - case kIsolateResumed:
|
| - return "IsolateResumed";
|
| - default:
|
| - UNREACHABLE();
|
| - return "Unknown";
|
| - }
|
| -}
|
| -
|
| -
|
| -void DebuggerEvent::PrintJSON(JSONStream* js) const {
|
| - JSONObject jsobj(js);
|
| - jsobj.AddProperty("type", "ServiceEvent");
|
| - // TODO(turnidge): Drop the 'id' for things like DebuggerEvent.
|
| - jsobj.AddProperty("id", "");
|
| - jsobj.AddProperty("eventType", EventTypeToCString(type()));
|
| - jsobj.AddProperty("isolate", isolate());
|
| - if ((type() == kBreakpointResolved || type() == kBreakpointReached) &&
|
| - breakpoint() != NULL) {
|
| - // TODO(turnidge): Make this a breakpoint ref.
|
| - jsobj.AddProperty("breakpoint", breakpoint());
|
| - }
|
| - if (type() == kExceptionThrown) {
|
| - jsobj.AddProperty("exception", *(exception()));
|
| - }
|
| -}
|
| -
|
| -
|
| ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
|
| const Instance& exc_obj) const {
|
| ExceptionHandlers& handlers = ExceptionHandlers::Handle();
|
| @@ -888,6 +872,7 @@ const char* ActivationFrame::ToCString() {
|
|
|
| void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) {
|
| const Script& script = Script::Handle(SourceScript());
|
| + jsobj->AddProperty("type", "Frame");
|
| jsobj->AddProperty("script", script);
|
| jsobj->AddProperty("tokenPos", TokenPos());
|
| jsobj->AddProperty("function", function());
|
| @@ -1411,6 +1396,8 @@ void Debugger::SignalExceptionThrown(const Instance& exc) {
|
| }
|
| DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown);
|
| event.set_exception(&exc);
|
| + ASSERT(stack_trace->Length() > 0);
|
| + event.set_top_frame(stack_trace->FrameAt(0));
|
| ASSERT(stack_trace_ == NULL);
|
| stack_trace_ = stack_trace;
|
| Pause(&event);
|
| @@ -1732,6 +1719,7 @@ SourceBreakpoint* Debugger::SetBreakpoint(const Script& script,
|
| line_number);
|
| }
|
| SignalBpResolved(bpt);
|
| + SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
|
| return bpt;
|
| }
|
| }
|
| @@ -1749,6 +1737,7 @@ SourceBreakpoint* Debugger::SetBreakpoint(const Script& script,
|
| if (bpt == NULL) {
|
| bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos);
|
| RegisterSourceBreakpoint(bpt);
|
| + SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
|
| }
|
| bpt->Enable();
|
| return bpt;
|
| @@ -2373,6 +2362,7 @@ void Debugger::NotifyCompilation(const Function& func) {
|
| requested_end_pos);
|
| }
|
| SignalBpResolved(bpt);
|
| + SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
|
| }
|
| ASSERT(bpt->IsResolved());
|
| if (FLAG_verbose_debug) {
|
| @@ -2530,6 +2520,7 @@ void Debugger::RemoveBreakpoint(intptr_t bp_id) {
|
| } else {
|
| prev_bpt->set_next(curr_bpt->next());
|
| }
|
| + SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
|
|
|
| // Remove references from code breakpoints to this source breakpoint,
|
| // and disable the code breakpoints.
|
|
|