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

Unified Diff: runtime/vm/debugger.cc

Issue 1978603002: Remove DebuggerEvent. Refactor remaining code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: before landing Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/debugger.cc
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6d11f18cb0e70ec60874aadfde2c190163296789..64476a9afbd0f84740c3c5222f05f3801209bbe8 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -263,114 +263,51 @@ ActivationFrame::ActivationFrame(
}
-void DebuggerEvent::UpdateTimestamp() {
- timestamp_ = OS::GetCurrentTimeMillis();
+bool Debugger::NeedsIsolateEvents() {
+ return ((isolate_ != Dart::vm_isolate()) &&
+ !ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
+ ((event_handler_ != NULL) || Service::isolate_stream.enabled()));
}
-bool Debugger::HasAnyEventHandler() {
- return ((event_handler_ != NULL) ||
- Service::isolate_stream.enabled() ||
+bool Debugger::NeedsDebugEvents() {
+ ASSERT(isolate_ != Dart::vm_isolate() &&
+ !ServiceIsolate::IsServiceIsolateDescendant(isolate_));
+ return (FLAG_warn_on_pause_with_no_debugger ||
+ (event_handler_ != NULL) ||
Service::debug_stream.enabled());
}
-bool Debugger::HasDebugEventHandler() {
- return ((event_handler_ != NULL) ||
- Service::debug_stream.enabled());
-}
-
-
-static bool ServiceNeedsDebuggerEvent(DebuggerEvent::EventType type) {
- switch (type) {
- case DebuggerEvent::kBreakpointResolved:
- // kBreakpointResolved events are handled differently in the vm
- // service, so suppress them here.
- return false;
-
- case DebuggerEvent::kBreakpointReached:
- case DebuggerEvent::kExceptionThrown:
- case DebuggerEvent::kIsolateInterrupted:
- return (Service::debug_stream.enabled() ||
- FLAG_warn_on_pause_with_no_debugger);
+void Debugger::InvokeEventHandler(ServiceEvent* event) {
+ ASSERT(!event->IsPause()); // For pause events, call Pause instead.
+ Service::HandleEvent(event);
- case DebuggerEvent::kIsolateCreated:
- case DebuggerEvent::kIsolateShutdown:
- return Service::isolate_stream.enabled();
-
- default:
- UNREACHABLE();
- return false;
- }
-}
-
-
-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.
- //
- // kBreakpointResolved events are handled differently in the vm
- // service, so suppress them here.
- if (ServiceNeedsDebuggerEvent(event->type())) {
- ServiceEvent service_event(event);
- Service::HandleEvent(&service_event);
- }
-
- {
+ // Call the embedder's event handler, if it exists.
+ if (event_handler_ != NULL) {
TransitionVMToNative transition(Thread::Current());
- if ((FLAG_steal_breakpoints || (event_handler_ == NULL)) &&
- event->IsPauseEvent()) {
- // We allow the embedder's default breakpoint handler to be overridden.
- isolate_->PauseEventHandler();
- } else if (event_handler_ != NULL) {
- (*event_handler_)(event);
- }
- }
-
- if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) {
- // If we were paused, notify the service that we have resumed.
- const Error& error =
- Error::Handle(Thread::Current()->sticky_error());
- ASSERT(error.IsNull() ||
- error.IsUnwindError() ||
- error.IsUnhandledException());
-
- // Only send a resume event when the isolate is not unwinding.
- if (!error.IsUnwindError()) {
- ServiceEvent service_event(event->isolate(), ServiceEvent::kResume);
- service_event.set_top_frame(event->top_frame());
- Service::HandleEvent(&service_event);
- }
+ (*event_handler_)(event);
}
}
-void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
- if (HasAnyEventHandler()) {
- DebuggerEvent event(isolate_, type);
- ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
- if (type == DebuggerEvent::kIsolateInterrupted) {
- DebuggerStackTrace* trace = CollectStackTrace();
- if (trace->Length() > 0) {
- event.set_top_frame(trace->FrameAt(0));
- }
- ASSERT(stack_trace_ == NULL);
- stack_trace_ = trace;
- resume_action_ = kContinue;
- Pause(&event);
- HandleSteppingRequest(trace);
- stack_trace_ = NULL;
- } else {
- InvokeEventHandler(&event);
- }
+RawError* Debugger::PauseInterrupted() {
+ if (ignore_breakpoints_ || IsPaused()) {
+ // We don't let the isolate get interrupted if we are already
+ // paused or ignoring breakpoints.
+ return Error::null();
}
-}
-
-
-RawError* Debugger::SignalIsolateInterrupted() {
- if (HasDebugEventHandler()) {
- SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
+ ServiceEvent event(isolate_, ServiceEvent::kPauseInterrupted);
+ DebuggerStackTrace* trace = CollectStackTrace();
+ if (trace->Length() > 0) {
+ event.set_top_frame(trace->FrameAt(0));
}
+ ASSERT(stack_trace_ == NULL);
+ stack_trace_ = trace;
+ resume_action_ = kContinue;
+ Pause(&event);
+ HandleSteppingRequest(trace);
+ stack_trace_ = NULL;
// If any error occurred while in the debug message loop, return it here.
const Error& error = Error::Handle(Thread::Current()->sticky_error());
@@ -380,14 +317,14 @@ RawError* Debugger::SignalIsolateInterrupted() {
}
-// The vm service handles breakpoint notifications in a different way
-// than the regular debugger breakpoint notifications.
-static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind,
- Breakpoint* bpt) {
- if (Service::debug_stream.enabled()) {
- ServiceEvent service_event(Isolate::Current(), kind);
- service_event.set_breakpoint(bpt);
- Service::HandleEvent(&service_event);
+void Debugger::SendBreakpointEvent(ServiceEvent::EventKind kind,
+ Breakpoint* bpt) {
+ if (NeedsDebugEvents()) {
+ // TODO(turnidge): Currently we send single-shot breakpoint events
+ // to the vm service. Do we want to change this?
+ ServiceEvent event(isolate_, kind);
+ event.set_breakpoint(bpt);
+ InvokeEventHandler(&event);
}
}
@@ -397,11 +334,7 @@ void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) {
set_breakpoints(bpt);
dbg->SyncBreakpointLocation(this);
-
- if (IsResolved()) {
- dbg->SignalBpResolved(bpt);
- }
- SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
+ dbg->SendBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
}
@@ -1270,7 +1203,6 @@ Debugger::Debugger()
: isolate_(NULL),
isolate_id_(ILLEGAL_ISOLATE_ID),
initialized_(false),
- creation_message_sent_(false),
next_id_(1),
latent_locations_(NULL),
breakpoint_locations_(NULL),
@@ -1322,10 +1254,9 @@ void Debugger::Shutdown() {
bpt->Disable();
delete bpt;
}
- // Signal isolate shutdown event, but only if we previously sent the creation
- // event.
- if (creation_message_sent_) {
- SignalIsolateEvent(DebuggerEvent::kIsolateShutdown);
+ if (NeedsIsolateEvents()) {
+ ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
+ InvokeEventHandler(&event);
}
}
@@ -1451,15 +1382,6 @@ void Debugger::DeoptimizeWorld() {
}
-void Debugger::SignalBpResolved(Breakpoint* bpt) {
- if (HasDebugEventHandler() && !bpt->IsSingleShot()) {
- DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
- event.set_breakpoint(bpt);
- InvokeEventHandler(&event);
- }
-}
-
-
ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
uword pc,
StackFrame* frame,
@@ -1667,7 +1589,7 @@ bool Debugger::ShouldPauseOnException(DebuggerStackTrace* stack_trace,
}
-void Debugger::SignalExceptionThrown(const Instance& exc) {
+void Debugger::PauseException(const Instance& exc) {
// We ignore this exception event when the VM is executing code invoked
// by the debugger to evaluate variables values, when we see a nested
// breakpoint or exception event, or if the debugger is not
@@ -1681,7 +1603,7 @@ void Debugger::SignalExceptionThrown(const Instance& exc) {
if (!ShouldPauseOnException(stack_trace, exc)) {
return;
}
- DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown);
+ ServiceEvent event(isolate_, ServiceEvent::kPauseException);
event.set_exception(&exc);
if (stack_trace->Length() > 0) {
event.set_top_frame(stack_trace->FrameAt(0));
@@ -2236,6 +2158,11 @@ Breakpoint* Debugger::BreakpointAtActivation(const Instance& closure) {
Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
intptr_t line_number) {
+ // Prevent future tests from calling this function in the wrong
+ // execution state. If you hit this assert, consider using
+ // Dart_SetBreakpoint instead.
+ ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
+
BreakpointLocation* loc =
BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */);
if (loc != NULL) {
@@ -2248,6 +2175,11 @@ Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url,
intptr_t line_number,
intptr_t column_number) {
+ // Prevent future tests from calling this function in the wrong
+ // execution state. If you hit this assert, consider using
+ // Dart_SetBreakpoint instead.
+ ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
+
BreakpointLocation* loc = BreakpointLocationAtLineCol(script_url,
line_number,
column_number);
@@ -2558,23 +2490,52 @@ void Debugger::SetEventHandler(EventHandler* handler) {
}
-void Debugger::Pause(DebuggerEvent* event) {
- ASSERT(!IsPaused()); // No recursive pausing.
+void Debugger::Pause(ServiceEvent* event) {
+ ASSERT(event->IsPause()); // Should call InvokeEventHandler instead.
+ ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts.
+ ASSERT(!IsPaused()); // No recursive pausing.
ASSERT(obj_cache_ == NULL);
pause_event_ = event;
pause_event_->UpdateTimestamp();
obj_cache_ = new RemoteObjectCache(64);
- // We are about to invoke the debuggers event handler. Disable interrupts
- // for this thread while waiting for debug commands over the service protocol.
+ // We are about to invoke the debugger's event handler. Disable
+ // interrupts for this thread while waiting for debug commands over
+ // the service protocol.
{
Thread* thread = Thread::Current();
DisableThreadInterruptsScope dtis(thread);
TimelineDurationScope tds(thread,
Timeline::GetDebuggerStream(),
"Debugger Pause");
- InvokeEventHandler(event);
+
+ // Send the pause event.
+ Service::HandleEvent(event);
+
+ {
+ TransitionVMToNative transition(Thread::Current());
+ if (FLAG_steal_breakpoints || (event_handler_ == NULL)) {
+ // We allow the embedder's default breakpoint handler to be overridden.
+ isolate_->PauseEventHandler();
+ } else if (event_handler_ != NULL) {
+ (*event_handler_)(event);
+ }
+ }
+
+ // Notify the service that we have resumed.
+ const Error& error =
+ Error::Handle(Thread::Current()->sticky_error());
+ ASSERT(error.IsNull() ||
+ error.IsUnwindError() ||
+ error.IsUnhandledException());
+
+ // Only send a resume event when the isolate is not unwinding.
+ if (!error.IsUnwindError()) {
+ ServiceEvent resume_event(event->isolate(), ServiceEvent::kResume);
+ resume_event.set_top_frame(event->top_frame());
+ Service::HandleEvent(&resume_event);
+ }
}
pause_event_ = NULL;
@@ -2657,7 +2618,7 @@ void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
bpt = NULL;
}
- DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached);
+ ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint);
event.set_top_frame(top_frame);
event.set_breakpoint(bpt);
event.set_at_async_jump(IsAtAsyncJump(top_frame));
@@ -2684,7 +2645,7 @@ bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
return false;
}
-RawError* Debugger::DebuggerStepCallback() {
+RawError* Debugger::PauseStepping() {
ASSERT(isolate_->single_step());
// Don't pause recursively.
if (IsPaused()) {
@@ -2741,7 +2702,7 @@ RawError* Debugger::DebuggerStepCallback() {
ASSERT(stack_trace_ == NULL);
stack_trace_ = CollectStackTrace();
// If this step callback is part of stepping over an await statement,
- // we saved the synthetic async breakpoint in SignalBpReached. We report
+ // we saved the synthetic async breakpoint in PauseBreakpoint. We report
// that we are paused at that breakpoint and then delete it after continuing.
SignalPausedEvent(frame, synthetic_async_breakpoint_);
if (synthetic_async_breakpoint_ != NULL) {
@@ -2758,7 +2719,7 @@ RawError* Debugger::DebuggerStepCallback() {
}
-RawError* Debugger::SignalBpReached() {
+RawError* Debugger::PauseBreakpoint() {
// 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.
@@ -2878,7 +2839,7 @@ RawError* Debugger::SignalBpReached() {
}
-void Debugger::BreakHere(const String& msg) {
+void Debugger::PauseDeveloper(const String& msg) {
// 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.
@@ -2886,7 +2847,7 @@ void Debugger::BreakHere(const String& msg) {
return;
}
- if (!HasDebugEventHandler()) {
+ if (!NeedsDebugEvents()) {
OS::Print("Hit debugger!");
}
@@ -2897,9 +2858,9 @@ void Debugger::BreakHere(const String& msg) {
// TODO(johnmccutchan): Send |msg| to Observatory.
- // We are in the native call to Debugger_breakHere or Debugger_breakHereIf,
- // the developer gets a better experience by not seeing this call. To
- // accomplish this, we continue execution until the call exits (step out).
+ // We are in the native call to Developer_debugger. the developer
+ // gets a better experience by not seeing this call. To accomplish
+ // this, we continue execution until the call exits (step out).
SetStepOut();
HandleSteppingRequest(stack_trace_);
@@ -2914,19 +2875,17 @@ void Debugger::Initialize(Isolate* isolate) {
isolate_ = isolate;
// Use the isolate's control port as the isolate_id for debugging.
- // This port will be used as a unique ID to represent the isolate in the
- // debugger wire protocol messages.
+ // This port will be used as a unique ID to represent the isolate in
+ // the debugger embedder api.
isolate_id_ = isolate_->main_port();
initialized_ = true;
}
void Debugger::NotifyIsolateCreated() {
- // Signal isolate creation event.
- if ((isolate_ != Dart::vm_isolate()) &&
- !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) {
- SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
- creation_message_sent_ = true;
+ if (NeedsIsolateEvents()) {
+ ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
+ InvokeEventHandler(&event);
}
}
@@ -3028,8 +2987,7 @@ void Debugger::NotifyCompilation(const Function& func) {
requested_end_pos.ToCString(),
loc->requested_column_number());
}
- SignalBpResolved(bpt);
- SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
+ SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
bpt = bpt->next();
}
}
@@ -3218,12 +3176,10 @@ void Debugger::RemoveBreakpoint(intptr_t bp_id) {
prev_bpt->set_next(curr_bpt->next());
}
- SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
+ SendBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
// Remove references from the current debugger pause event.
- if (pause_event_ != NULL &&
- pause_event_->type() == DebuggerEvent::kBreakpointReached &&
- pause_event_->breakpoint() == curr_bpt) {
+ if (pause_event_ != NULL && pause_event_->breakpoint() == curr_bpt) {
pause_event_->set_breakpoint(NULL);
}
break;
« no previous file with comments | « 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