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

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

Issue 340443006: Add support for asynchronous event notification to the observatory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/isolate.cc » ('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"
11 #include "vm/compiler.h" 11 #include "vm/compiler.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/deopt_instructions.h" 13 #include "vm/deopt_instructions.h"
14 #include "vm/flags.h" 14 #include "vm/flags.h"
15 #include "vm/globals.h" 15 #include "vm/globals.h"
16 #include "vm/longjump.h" 16 #include "vm/longjump.h"
17 #include "vm/json_stream.h" 17 #include "vm/json_stream.h"
18 #include "vm/object.h" 18 #include "vm/object.h"
19 #include "vm/object_store.h" 19 #include "vm/object_store.h"
20 #include "vm/os.h" 20 #include "vm/os.h"
21 #include "vm/port.h" 21 #include "vm/port.h"
22 #include "vm/service.h"
22 #include "vm/stack_frame.h" 23 #include "vm/stack_frame.h"
23 #include "vm/stub_code.h" 24 #include "vm/stub_code.h"
24 #include "vm/symbols.h" 25 #include "vm/symbols.h"
25 #include "vm/visitor.h" 26 #include "vm/visitor.h"
26 27
27 28
28 namespace dart { 29 namespace dart {
29 30
30 DEFINE_FLAG(bool, enable_debugger, true, "Enables debugger step checks"); 31 DEFINE_FLAG(bool, enable_debugger, true, "Enables debugger step checks");
31 DEFINE_FLAG(bool, show_invisible_frames, false, 32 DEFINE_FLAG(bool, show_invisible_frames, false,
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 context_level_(-1), 186 context_level_(-1),
186 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 187 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
187 deopt_frame_offset_(deopt_frame_offset), 188 deopt_frame_offset_(deopt_frame_offset),
188 vars_initialized_(false), 189 vars_initialized_(false),
189 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 190 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
190 desc_indices_(8), 191 desc_indices_(8),
191 pc_desc_(PcDescriptors::ZoneHandle()) { 192 pc_desc_(PcDescriptors::ZoneHandle()) {
192 } 193 }
193 194
194 195
196 bool Debugger::HasEventHandler() {
197 return (event_handler_ != NULL) || Service::NeedsDebuggerEvents();
198 }
199
200
201 void Debugger::InvokeEventHandler(DebuggerEvent* event) {
202 ASSERT(HasEventHandler());
203
204 // Give the event to the Service first, as the debugger event handler
205 // may go into a message loop and the Service will not.
206 if (Service::NeedsDebuggerEvents()) {
207 Service::HandleDebuggerEvent(event);
208 }
209
210 if (event_handler_ != NULL) {
211 (*event_handler_)(event);
212 }
213 }
214
215
195 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) { 216 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
196 if (event_handler_ != NULL) { 217 if (HasEventHandler()) {
197 DebuggerEvent event(type); 218 DebuggerEvent event(isolate_, type);
198 event.set_isolate_id(isolate_id_);
199 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID); 219 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
200 if (type == DebuggerEvent::kIsolateInterrupted) { 220 if (type == DebuggerEvent::kIsolateInterrupted) {
201 DebuggerStackTrace* trace = CollectStackTrace(); 221 DebuggerStackTrace* trace = CollectStackTrace();
202 ASSERT(trace->Length() > 0); 222 ASSERT(trace->Length() > 0);
203 ASSERT(stack_trace_ == NULL); 223 ASSERT(stack_trace_ == NULL);
204 stack_trace_ = trace; 224 stack_trace_ = trace;
205 resume_action_ = kContinue; 225 resume_action_ = kContinue;
206 Pause(&event); 226 Pause(&event);
207 HandleSteppingRequest(trace); 227 HandleSteppingRequest(trace);
208 stack_trace_ = NULL; 228 stack_trace_ = NULL;
209 } else { 229 } else {
210 (*event_handler_)(&event); 230 InvokeEventHandler(&event);
211 } 231 }
212 } 232 }
213 } 233 }
214 234
215 235
216 void Debugger::SignalIsolateInterrupted() { 236 void Debugger::SignalIsolateInterrupted() {
217 if (event_handler_ != NULL) { 237 if (HasEventHandler()) {
218 Debugger* debugger = Isolate::Current()->debugger(); 238 Debugger* debugger = Isolate::Current()->debugger();
219 ASSERT(debugger != NULL); 239 ASSERT(debugger != NULL);
220 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted); 240 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
221 } 241 }
222 } 242 }
223 243
224 244
225 const char* Debugger::QualifiedFunctionName(const Function& func) { 245 const char* Debugger::QualifiedFunctionName(const Function& func) {
226 const String& func_name = String::Handle(func.name()); 246 const String& func_name = String::Handle(func.name());
227 Class& func_class = Class::Handle(func.Owner()); 247 Class& func_class = Class::Handle(func.Owner());
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 return "IsolateInterrupted"; 523 return "IsolateInterrupted";
504 default: 524 default:
505 UNREACHABLE(); 525 UNREACHABLE();
506 return "Unknown"; 526 return "Unknown";
507 } 527 }
508 } 528 }
509 529
510 530
511 void DebuggerEvent::PrintJSON(JSONStream* js) const { 531 void DebuggerEvent::PrintJSON(JSONStream* js) const {
512 JSONObject jsobj(js); 532 JSONObject jsobj(js);
513 jsobj.AddProperty("type", "DebuggerEvent"); 533 jsobj.AddProperty("type", "ServiceEvent");
514 // TODO(turnidge): Drop the 'id' for things like DebuggerEvent. 534 // TODO(turnidge): Drop the 'id' for things like DebuggerEvent.
515 jsobj.AddProperty("id", ""); 535 jsobj.AddProperty("id", "");
516 // TODO(turnidge): Add 'isolate'.
517 jsobj.AddProperty("eventType", EventTypeToCString(type())); 536 jsobj.AddProperty("eventType", EventTypeToCString(type()));
537 jsobj.AddProperty("isolate", isolate());
518 if (type() == kBreakpointResolved || type() == kBreakpointReached) { 538 if (type() == kBreakpointResolved || type() == kBreakpointReached) {
519 jsobj.AddProperty("breakpoint", breakpoint()); 539 jsobj.AddProperty("breakpoint", breakpoint());
520 } 540 }
521 if (type() == kExceptionThrown) { 541 if (type() == kExceptionThrown) {
522 jsobj.AddProperty("exception", *(exception())); 542 jsobj.AddProperty("exception", *(exception()));
523 } 543 }
524 } 544 }
525 545
526 546
527 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( 547 ActivationFrame* DebuggerStackTrace::GetHandlerFrame(
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 } 1225 }
1206 bpt = new CodeBreakpoint(code, i); 1226 bpt = new CodeBreakpoint(code, i);
1207 RegisterCodeBreakpoint(bpt); 1227 RegisterCodeBreakpoint(bpt);
1208 bpt->Enable(); 1228 bpt->Enable();
1209 } 1229 }
1210 } 1230 }
1211 } 1231 }
1212 1232
1213 1233
1214 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { 1234 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
1215 if (event_handler_ != NULL) { 1235 if (HasEventHandler()) {
1216 DebuggerEvent event(DebuggerEvent::kBreakpointResolved); 1236 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
1217 event.set_breakpoint(bpt); 1237 event.set_breakpoint(bpt);
1218 (*event_handler_)(&event); 1238 InvokeEventHandler(&event);
1219 } 1239 }
1220 } 1240 }
1221 1241
1222 1242
1223 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1243 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1224 uword pc, 1244 uword pc,
1225 StackFrame* frame, 1245 StackFrame* frame,
1226 const Code& code, 1246 const Code& code,
1227 const Array& deopt_frame, 1247 const Array& deopt_frame,
1228 intptr_t deopt_frame_offset, 1248 intptr_t deopt_frame_offset,
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 } 1513 }
1494 1514
1495 1515
1496 void Debugger::SignalExceptionThrown(const Instance& exc) { 1516 void Debugger::SignalExceptionThrown(const Instance& exc) {
1497 // We ignore this exception event when the VM is executing code invoked 1517 // We ignore this exception event when the VM is executing code invoked
1498 // by the debugger to evaluate variables values, when we see a nested 1518 // by the debugger to evaluate variables values, when we see a nested
1499 // breakpoint or exception event, or if the debugger is not 1519 // breakpoint or exception event, or if the debugger is not
1500 // interested in exception events. 1520 // interested in exception events.
1501 if (ignore_breakpoints_ || 1521 if (ignore_breakpoints_ ||
1502 IsPaused() || 1522 IsPaused() ||
1503 (event_handler_ == NULL) || 1523 (!HasEventHandler()) ||
1504 (exc_pause_info_ == kNoPauseOnExceptions)) { 1524 (exc_pause_info_ == kNoPauseOnExceptions)) {
1505 return; 1525 return;
1506 } 1526 }
1507 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1527 DebuggerStackTrace* stack_trace = CollectStackTrace();
1508 if (!ShouldPauseOnException(stack_trace, exc)) { 1528 if (!ShouldPauseOnException(stack_trace, exc)) {
1509 return; 1529 return;
1510 } 1530 }
1511 DebuggerEvent event(DebuggerEvent::kExceptionThrown); 1531 DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown);
1512 event.set_exception(&exc); 1532 event.set_exception(&exc);
1513 ASSERT(stack_trace_ == NULL); 1533 ASSERT(stack_trace_ == NULL);
1514 stack_trace_ = stack_trace; 1534 stack_trace_ = stack_trace;
1515 Pause(&event); 1535 Pause(&event);
1516 stack_trace_ = NULL; 1536 stack_trace_ = NULL;
1517 } 1537 }
1518 1538
1519 1539
1520 // Given a function and a token range, return the best fit 1540 // Given a function and a token range, return the best fit
1521 // token position to set a breakpoint. The best fit is the safe point 1541 // token position to set a breakpoint. The best fit is the safe point
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 prefix_name = String::Concat(prefix_name, Symbols::Dot()); 2151 prefix_name = String::Concat(prefix_name, Symbols::Dot());
2132 for (intptr_t i = 0; i < prefix.num_imports(); i++) { 2152 for (intptr_t i = 0; i < prefix.num_imports(); i++) {
2133 imported = prefix.GetLibrary(i); 2153 imported = prefix.GetLibrary(i);
2134 CollectLibraryFields(field_list, imported, prefix_name, false); 2154 CollectLibraryFields(field_list, imported, prefix_name, false);
2135 } 2155 }
2136 } 2156 }
2137 return Array::MakeArray(field_list); 2157 return Array::MakeArray(field_list);
2138 } 2158 }
2139 2159
2140 2160
2161 // static
2141 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { 2162 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
2142 ASSERT(visitor != NULL); 2163 ASSERT(visitor != NULL);
2143 SourceBreakpoint* bpt = src_breakpoints_; 2164 SourceBreakpoint* bpt = src_breakpoints_;
2144 while (bpt != NULL) { 2165 while (bpt != NULL) {
2145 bpt->VisitObjectPointers(visitor); 2166 bpt->VisitObjectPointers(visitor);
2146 bpt = bpt->next(); 2167 bpt = bpt->next();
2147 } 2168 }
2148 CodeBreakpoint* cbpt = code_breakpoints_; 2169 CodeBreakpoint* cbpt = code_breakpoints_;
2149 while (cbpt != NULL) { 2170 while (cbpt != NULL) {
2150 cbpt->VisitObjectPointers(visitor); 2171 cbpt->VisitObjectPointers(visitor);
2151 cbpt = cbpt->next(); 2172 cbpt = cbpt->next();
2152 } 2173 }
2153 } 2174 }
2154 2175
2155 2176
2177 // static
2156 void Debugger::SetEventHandler(EventHandler* handler) { 2178 void Debugger::SetEventHandler(EventHandler* handler) {
2157 event_handler_ = handler; 2179 event_handler_ = handler;
2158 } 2180 }
2159 2181
2160 2182
2161 void Debugger::Pause(DebuggerEvent* event) { 2183 void Debugger::Pause(DebuggerEvent* event) {
2162 ASSERT(!IsPaused()); // No recursive pausing. 2184 ASSERT(!IsPaused()); // No recursive pausing.
2163 ASSERT(obj_cache_ == NULL); 2185 ASSERT(obj_cache_ == NULL);
2164 2186
2165 pause_event_ = event; 2187 pause_event_ = event;
2166 obj_cache_ = new RemoteObjectCache(64); 2188 obj_cache_ = new RemoteObjectCache(64);
2167 2189
2168 (*event_handler_)(event); 2190 InvokeEventHandler(event);
2169 2191
2170 pause_event_ = NULL; 2192 pause_event_ = NULL;
2171 obj_cache_ = NULL; // Zone allocated 2193 obj_cache_ = NULL; // Zone allocated
2172 } 2194 }
2173 2195
2174 2196
2175 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) { 2197 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) {
2176 stepping_fp_ = 0; 2198 stepping_fp_ = 0;
2177 if (resume_action_ == kSingleStep) { 2199 if (resume_action_ == kSingleStep) {
2178 isolate_->set_single_step(true); 2200 isolate_->set_single_step(true);
(...skipping 26 matching lines...) Expand all
2205 } 2227 }
2206 2228
2207 2229
2208 void Debugger::SignalPausedEvent(ActivationFrame* top_frame, 2230 void Debugger::SignalPausedEvent(ActivationFrame* top_frame,
2209 SourceBreakpoint* bpt) { 2231 SourceBreakpoint* bpt) {
2210 resume_action_ = kContinue; 2232 resume_action_ = kContinue;
2211 stepping_fp_ = 0; 2233 stepping_fp_ = 0;
2212 isolate_->set_single_step(false); 2234 isolate_->set_single_step(false);
2213 ASSERT(!IsPaused()); 2235 ASSERT(!IsPaused());
2214 ASSERT(obj_cache_ == NULL); 2236 ASSERT(obj_cache_ == NULL);
2215 DebuggerEvent event(DebuggerEvent::kBreakpointReached); 2237 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached);
2216 event.set_top_frame(top_frame); 2238 event.set_top_frame(top_frame);
2217 event.set_breakpoint(bpt); 2239 event.set_breakpoint(bpt);
2218 Pause(&event); 2240 Pause(&event);
2219 } 2241 }
2220 2242
2221 2243
2222 void Debugger::DebuggerStepCallback() { 2244 void Debugger::DebuggerStepCallback() {
2223 ASSERT(isolate_->single_step()); 2245 ASSERT(isolate_->single_step());
2224 // We can't get here unless the debugger event handler enabled 2246 // We can't get here unless the debugger event handler enabled
2225 // single stepping. 2247 // single stepping.
2226 ASSERT(event_handler_ != NULL); 2248 ASSERT(HasEventHandler());
2227 // Don't pause recursively. 2249 // Don't pause recursively.
2228 if (IsPaused()) return; 2250 if (IsPaused()) return;
2229 2251
2230 // Check whether we are in a Dart function that the user is 2252 // Check whether we are in a Dart function that the user is
2231 // interested in. If we saved the frame pointer of a stack frame 2253 // interested in. If we saved the frame pointer of a stack frame
2232 // the user is interested in, we ignore the single step if we are 2254 // the user is interested in, we ignore the single step if we are
2233 // in a callee of that frame. Note that we assume that the stack 2255 // in a callee of that frame. Note that we assume that the stack
2234 // grows towards lower addresses. 2256 // grows towards lower addresses.
2235 ActivationFrame* frame = TopDartFrame(); 2257 ActivationFrame* frame = TopDartFrame();
2236 ASSERT(frame != NULL); 2258 ASSERT(frame != NULL);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 SignalPausedEvent(frame, NULL); 2298 SignalPausedEvent(frame, NULL);
2277 HandleSteppingRequest(stack_trace_); 2299 HandleSteppingRequest(stack_trace_);
2278 stack_trace_ = NULL; 2300 stack_trace_ = NULL;
2279 } 2301 }
2280 2302
2281 2303
2282 void Debugger::SignalBpReached() { 2304 void Debugger::SignalBpReached() {
2283 // We ignore this breakpoint when the VM is executing code invoked 2305 // We ignore this breakpoint when the VM is executing code invoked
2284 // by the debugger to evaluate variables values, or when we see a nested 2306 // by the debugger to evaluate variables values, or when we see a nested
2285 // breakpoint or exception event. 2307 // breakpoint or exception event.
2286 if (ignore_breakpoints_ || IsPaused() || (event_handler_ == NULL)) { 2308 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) {
2287 return; 2309 return;
2288 } 2310 }
2289 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2311 DebuggerStackTrace* stack_trace = CollectStackTrace();
2290 ASSERT(stack_trace->Length() > 0); 2312 ASSERT(stack_trace->Length() > 0);
2291 ActivationFrame* top_frame = stack_trace->FrameAt(0); 2313 ActivationFrame* top_frame = stack_trace->FrameAt(0);
2292 ASSERT(top_frame != NULL); 2314 ASSERT(top_frame != NULL);
2293 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc()); 2315 CodeBreakpoint* bpt = GetCodeBreakpoint(top_frame->pc());
2294 ASSERT(bpt != NULL); 2316 ASSERT(bpt != NULL);
2295 2317
2296 if (FLAG_verbose_debug) { 2318 if (FLAG_verbose_debug) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
2562 } 2584 }
2563 2585
2564 2586
2565 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2587 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2566 ASSERT(bpt->next() == NULL); 2588 ASSERT(bpt->next() == NULL);
2567 bpt->set_next(code_breakpoints_); 2589 bpt->set_next(code_breakpoints_);
2568 code_breakpoints_ = bpt; 2590 code_breakpoints_ = bpt;
2569 } 2591 }
2570 2592
2571 } // namespace dart 2593 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698