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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.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"
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 context_level_(-1), 256 context_level_(-1),
257 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 257 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
258 deopt_frame_offset_(deopt_frame_offset), 258 deopt_frame_offset_(deopt_frame_offset),
259 vars_initialized_(false), 259 vars_initialized_(false),
260 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 260 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
261 desc_indices_(8), 261 desc_indices_(8),
262 pc_desc_(PcDescriptors::ZoneHandle()) { 262 pc_desc_(PcDescriptors::ZoneHandle()) {
263 } 263 }
264 264
265 265
266 void DebuggerEvent::UpdateTimestamp() { 266 bool Debugger::NeedsIsolateEvents() {
267 timestamp_ = OS::GetCurrentTimeMillis(); 267 return ((isolate_ != Dart::vm_isolate()) &&
268 !ServiceIsolate::IsServiceIsolateDescendant(isolate_) &&
269 ((event_handler_ != NULL) || Service::isolate_stream.enabled()));
268 } 270 }
269 271
270 272
271 bool Debugger::HasAnyEventHandler() { 273 bool Debugger::NeedsDebugEvents() {
272 return ((event_handler_ != NULL) || 274 ASSERT(isolate_ != Dart::vm_isolate() &&
273 Service::isolate_stream.enabled() || 275 !ServiceIsolate::IsServiceIsolateDescendant(isolate_));
276 return (FLAG_warn_on_pause_with_no_debugger ||
277 (event_handler_ != NULL) ||
274 Service::debug_stream.enabled()); 278 Service::debug_stream.enabled());
275 } 279 }
276 280
277 281
278 bool Debugger::HasDebugEventHandler() { 282 void Debugger::InvokeEventHandler(ServiceEvent* event) {
279 return ((event_handler_ != NULL) || 283 ASSERT(!event->IsPause()); // For pause events, call Pause instead.
280 Service::debug_stream.enabled()); 284 Service::HandleEvent(event);
281 }
282 285
283 286 // Call the embedder's event handler, if it exists.
284 static bool ServiceNeedsDebuggerEvent(DebuggerEvent::EventType type) { 287 if (event_handler_ != NULL) {
285 switch (type) { 288 TransitionVMToNative transition(Thread::Current());
286 case DebuggerEvent::kBreakpointResolved: 289 (*event_handler_)(event);
287 // kBreakpointResolved events are handled differently in the vm
288 // service, so suppress them here.
289 return false;
290
291 case DebuggerEvent::kBreakpointReached:
292 case DebuggerEvent::kExceptionThrown:
293 case DebuggerEvent::kIsolateInterrupted:
294 return (Service::debug_stream.enabled() ||
295 FLAG_warn_on_pause_with_no_debugger);
296
297 case DebuggerEvent::kIsolateCreated:
298 case DebuggerEvent::kIsolateShutdown:
299 return Service::isolate_stream.enabled();
300
301 default:
302 UNREACHABLE();
303 return false;
304 } 290 }
305 } 291 }
306 292
307 293
308 void Debugger::InvokeEventHandler(DebuggerEvent* event) { 294 RawError* Debugger::PauseInterrupted() {
309 // Give the event to the Service first, as the debugger event handler 295 if (ignore_breakpoints_ || IsPaused()) {
310 // may go into a message loop and the Service will not. 296 // We don't let the isolate get interrupted if we are already
311 // 297 // paused or ignoring breakpoints.
312 // kBreakpointResolved events are handled differently in the vm 298 return Error::null();
313 // service, so suppress them here.
314 if (ServiceNeedsDebuggerEvent(event->type())) {
315 ServiceEvent service_event(event);
316 Service::HandleEvent(&service_event);
317 } 299 }
318 300 ServiceEvent event(isolate_, ServiceEvent::kPauseInterrupted);
319 { 301 DebuggerStackTrace* trace = CollectStackTrace();
320 TransitionVMToNative transition(Thread::Current()); 302 if (trace->Length() > 0) {
321 if ((FLAG_steal_breakpoints || (event_handler_ == NULL)) && 303 event.set_top_frame(trace->FrameAt(0));
322 event->IsPauseEvent()) {
323 // We allow the embedder's default breakpoint handler to be overridden.
324 isolate_->PauseEventHandler();
325 } else if (event_handler_ != NULL) {
326 (*event_handler_)(event);
327 }
328 } 304 }
329 305 ASSERT(stack_trace_ == NULL);
330 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { 306 stack_trace_ = trace;
331 // If we were paused, notify the service that we have resumed. 307 resume_action_ = kContinue;
332 const Error& error = 308 Pause(&event);
333 Error::Handle(Thread::Current()->sticky_error()); 309 HandleSteppingRequest(trace);
334 ASSERT(error.IsNull() || 310 stack_trace_ = NULL;
335 error.IsUnwindError() ||
336 error.IsUnhandledException());
337
338 // Only send a resume event when the isolate is not unwinding.
339 if (!error.IsUnwindError()) {
340 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume);
341 service_event.set_top_frame(event->top_frame());
342 Service::HandleEvent(&service_event);
343 }
344 }
345 }
346
347
348 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
349 if (HasAnyEventHandler()) {
350 DebuggerEvent event(isolate_, type);
351 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
352 if (type == DebuggerEvent::kIsolateInterrupted) {
353 DebuggerStackTrace* trace = CollectStackTrace();
354 if (trace->Length() > 0) {
355 event.set_top_frame(trace->FrameAt(0));
356 }
357 ASSERT(stack_trace_ == NULL);
358 stack_trace_ = trace;
359 resume_action_ = kContinue;
360 Pause(&event);
361 HandleSteppingRequest(trace);
362 stack_trace_ = NULL;
363 } else {
364 InvokeEventHandler(&event);
365 }
366 }
367 }
368
369
370 RawError* Debugger::SignalIsolateInterrupted() {
371 if (HasDebugEventHandler()) {
372 SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
373 }
374 311
375 // If any error occurred while in the debug message loop, return it here. 312 // If any error occurred while in the debug message loop, return it here.
376 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 313 const Error& error = Error::Handle(Thread::Current()->sticky_error());
377 ASSERT(error.IsNull() || error.IsUnwindError()); 314 ASSERT(error.IsNull() || error.IsUnwindError());
378 Thread::Current()->clear_sticky_error(); 315 Thread::Current()->clear_sticky_error();
379 return error.raw(); 316 return error.raw();
380 } 317 }
381 318
382 319
383 // The vm service handles breakpoint notifications in a different way 320 void Debugger::SendBreakpointEvent(ServiceEvent::EventKind kind,
384 // than the regular debugger breakpoint notifications. 321 Breakpoint* bpt) {
385 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, 322 if (NeedsDebugEvents()) {
386 Breakpoint* bpt) { 323 // TODO(turnidge): Currently we send single-shot breakpoint events
387 if (Service::debug_stream.enabled()) { 324 // to the vm service. Do we want to change this?
388 ServiceEvent service_event(Isolate::Current(), kind); 325 ServiceEvent event(isolate_, kind);
389 service_event.set_breakpoint(bpt); 326 event.set_breakpoint(bpt);
390 Service::HandleEvent(&service_event); 327 InvokeEventHandler(&event);
391 } 328 }
392 } 329 }
393 330
394 331
395 void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) { 332 void BreakpointLocation::AddBreakpoint(Breakpoint* bpt, Debugger* dbg) {
396 bpt->set_next(breakpoints()); 333 bpt->set_next(breakpoints());
397 set_breakpoints(bpt); 334 set_breakpoints(bpt);
398 335
399 dbg->SyncBreakpointLocation(this); 336 dbg->SyncBreakpointLocation(this);
400 337 dbg->SendBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
401 if (IsResolved()) {
402 dbg->SignalBpResolved(bpt);
403 }
404 SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt);
405 } 338 }
406 339
407 340
408 Breakpoint* BreakpointLocation::AddRepeated(Debugger* dbg) { 341 Breakpoint* BreakpointLocation::AddRepeated(Debugger* dbg) {
409 Breakpoint* bpt = breakpoints(); 342 Breakpoint* bpt = breakpoints();
410 while (bpt != NULL) { 343 while (bpt != NULL) {
411 if (bpt->IsRepeated()) break; 344 if (bpt->IsRepeated()) break;
412 bpt = bpt->next(); 345 bpt = bpt->next();
413 } 346 }
414 if (bpt == NULL) { 347 if (bpt == NULL) {
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const { 1196 RawObject* RemoteObjectCache::GetObj(intptr_t obj_id) const {
1264 ASSERT(IsValidId(obj_id)); 1197 ASSERT(IsValidId(obj_id));
1265 return objs_->At(obj_id); 1198 return objs_->At(obj_id);
1266 } 1199 }
1267 1200
1268 1201
1269 Debugger::Debugger() 1202 Debugger::Debugger()
1270 : isolate_(NULL), 1203 : isolate_(NULL),
1271 isolate_id_(ILLEGAL_ISOLATE_ID), 1204 isolate_id_(ILLEGAL_ISOLATE_ID),
1272 initialized_(false), 1205 initialized_(false),
1273 creation_message_sent_(false),
1274 next_id_(1), 1206 next_id_(1),
1275 latent_locations_(NULL), 1207 latent_locations_(NULL),
1276 breakpoint_locations_(NULL), 1208 breakpoint_locations_(NULL),
1277 code_breakpoints_(NULL), 1209 code_breakpoints_(NULL),
1278 resume_action_(kContinue), 1210 resume_action_(kContinue),
1279 ignore_breakpoints_(false), 1211 ignore_breakpoints_(false),
1280 pause_event_(NULL), 1212 pause_event_(NULL),
1281 obj_cache_(NULL), 1213 obj_cache_(NULL),
1282 stack_trace_(NULL), 1214 stack_trace_(NULL),
1283 stepping_fp_(0), 1215 stepping_fp_(0),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 BreakpointLocation* bpt = latent_locations_; 1247 BreakpointLocation* bpt = latent_locations_;
1316 latent_locations_ = latent_locations_->next(); 1248 latent_locations_ = latent_locations_->next();
1317 delete bpt; 1249 delete bpt;
1318 } 1250 }
1319 while (code_breakpoints_ != NULL) { 1251 while (code_breakpoints_ != NULL) {
1320 CodeBreakpoint* bpt = code_breakpoints_; 1252 CodeBreakpoint* bpt = code_breakpoints_;
1321 code_breakpoints_ = code_breakpoints_->next(); 1253 code_breakpoints_ = code_breakpoints_->next();
1322 bpt->Disable(); 1254 bpt->Disable();
1323 delete bpt; 1255 delete bpt;
1324 } 1256 }
1325 // Signal isolate shutdown event, but only if we previously sent the creation 1257 if (NeedsIsolateEvents()) {
1326 // event. 1258 ServiceEvent event(isolate_, ServiceEvent::kIsolateExit);
1327 if (creation_message_sent_) { 1259 InvokeEventHandler(&event);
1328 SignalIsolateEvent(DebuggerEvent::kIsolateShutdown);
1329 } 1260 }
1330 } 1261 }
1331 1262
1332 1263
1333 static RawFunction* ResolveLibraryFunction( 1264 static RawFunction* ResolveLibraryFunction(
1334 const Library& library, 1265 const Library& library,
1335 const String& fname) { 1266 const String& fname) {
1336 ASSERT(!library.IsNull()); 1267 ASSERT(!library.IsNull());
1337 const Object& object = Object::Handle(library.ResolveName(fname)); 1268 const Object& object = Object::Handle(library.ResolveName(fname));
1338 if (!object.IsNull() && object.IsFunction()) { 1269 if (!object.IsNull() && object.IsFunction()) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 for (intptr_t pos = 0; pos < num_closures; pos++) { 1375 for (intptr_t pos = 0; pos < num_closures; pos++) {
1445 function ^= closures.At(pos); 1376 function ^= closures.At(pos);
1446 ASSERT(!function.IsNull()); 1377 ASSERT(!function.IsNull());
1447 if (function.HasOptimizedCode()) { 1378 if (function.HasOptimizedCode()) {
1448 function.SwitchToUnoptimizedCode(); 1379 function.SwitchToUnoptimizedCode();
1449 } 1380 }
1450 } 1381 }
1451 } 1382 }
1452 1383
1453 1384
1454 void Debugger::SignalBpResolved(Breakpoint* bpt) {
1455 if (HasDebugEventHandler() && !bpt->IsSingleShot()) {
1456 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
1457 event.set_breakpoint(bpt);
1458 InvokeEventHandler(&event);
1459 }
1460 }
1461
1462
1463 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, 1385 ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate,
1464 uword pc, 1386 uword pc,
1465 StackFrame* frame, 1387 StackFrame* frame,
1466 const Code& code, 1388 const Code& code,
1467 const Array& deopt_frame, 1389 const Array& deopt_frame,
1468 intptr_t deopt_frame_offset) { 1390 intptr_t deopt_frame_offset) {
1469 ASSERT(code.ContainsInstructionAt(pc)); 1391 ASSERT(code.ContainsInstructionAt(pc));
1470 ActivationFrame* activation = 1392 ActivationFrame* activation =
1471 new ActivationFrame(pc, frame->fp(), frame->sp(), code, 1393 new ActivationFrame(pc, frame->fp(), frame->sp(), code,
1472 deopt_frame, deopt_frame_offset); 1394 deopt_frame, deopt_frame_offset);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1660 // Note that this check is not precise, since we can't check 1582 // Note that this check is not precise, since we can't check
1661 // uninstantiated types, i.e. types containing type parameters. 1583 // uninstantiated types, i.e. types containing type parameters.
1662 // Thus, we may report an exception as unhandled when in fact 1584 // Thus, we may report an exception as unhandled when in fact
1663 // it will be caught once we unwind the stack. 1585 // it will be caught once we unwind the stack.
1664 return true; 1586 return true;
1665 } 1587 }
1666 return false; 1588 return false;
1667 } 1589 }
1668 1590
1669 1591
1670 void Debugger::SignalExceptionThrown(const Instance& exc) { 1592 void Debugger::PauseException(const Instance& exc) {
1671 // We ignore this exception event when the VM is executing code invoked 1593 // We ignore this exception event when the VM is executing code invoked
1672 // by the debugger to evaluate variables values, when we see a nested 1594 // by the debugger to evaluate variables values, when we see a nested
1673 // breakpoint or exception event, or if the debugger is not 1595 // breakpoint or exception event, or if the debugger is not
1674 // interested in exception events. 1596 // interested in exception events.
1675 if (ignore_breakpoints_ || 1597 if (ignore_breakpoints_ ||
1676 IsPaused() || 1598 IsPaused() ||
1677 (exc_pause_info_ == kNoPauseOnExceptions)) { 1599 (exc_pause_info_ == kNoPauseOnExceptions)) {
1678 return; 1600 return;
1679 } 1601 }
1680 DebuggerStackTrace* stack_trace = CollectStackTrace(); 1602 DebuggerStackTrace* stack_trace = CollectStackTrace();
1681 if (!ShouldPauseOnException(stack_trace, exc)) { 1603 if (!ShouldPauseOnException(stack_trace, exc)) {
1682 return; 1604 return;
1683 } 1605 }
1684 DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown); 1606 ServiceEvent event(isolate_, ServiceEvent::kPauseException);
1685 event.set_exception(&exc); 1607 event.set_exception(&exc);
1686 if (stack_trace->Length() > 0) { 1608 if (stack_trace->Length() > 0) {
1687 event.set_top_frame(stack_trace->FrameAt(0)); 1609 event.set_top_frame(stack_trace->FrameAt(0));
1688 } 1610 }
1689 ASSERT(stack_trace_ == NULL); 1611 ASSERT(stack_trace_ == NULL);
1690 stack_trace_ = stack_trace; 1612 stack_trace_ = stack_trace;
1691 Pause(&event); 1613 Pause(&event);
1692 stack_trace_ = NULL; 1614 stack_trace_ = NULL;
1693 } 1615 }
1694 1616
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2229 } 2151 }
2230 loc = loc->next(); 2152 loc = loc->next();
2231 } 2153 }
2232 2154
2233 return NULL; 2155 return NULL;
2234 } 2156 }
2235 2157
2236 2158
2237 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url, 2159 Breakpoint* Debugger::SetBreakpointAtLine(const String& script_url,
2238 intptr_t line_number) { 2160 intptr_t line_number) {
2161 // Prevent future tests from calling this function in the wrong
2162 // execution state. If you hit this assert, consider using
2163 // Dart_SetBreakpoint instead.
2164 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2165
2239 BreakpointLocation* loc = 2166 BreakpointLocation* loc =
2240 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */); 2167 BreakpointLocationAtLineCol(script_url, line_number, -1 /* no column */);
2241 if (loc != NULL) { 2168 if (loc != NULL) {
2242 return loc->AddRepeated(this); 2169 return loc->AddRepeated(this);
2243 } 2170 }
2244 return NULL; 2171 return NULL;
2245 } 2172 }
2246 2173
2247 2174
2248 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url, 2175 Breakpoint* Debugger::SetBreakpointAtLineCol(const String& script_url,
2249 intptr_t line_number, 2176 intptr_t line_number,
2250 intptr_t column_number) { 2177 intptr_t column_number) {
2178 // Prevent future tests from calling this function in the wrong
2179 // execution state. If you hit this assert, consider using
2180 // Dart_SetBreakpoint instead.
2181 ASSERT(Thread::Current()->execution_state() == Thread::kThreadInVM);
2182
2251 BreakpointLocation* loc = BreakpointLocationAtLineCol(script_url, 2183 BreakpointLocation* loc = BreakpointLocationAtLineCol(script_url,
2252 line_number, 2184 line_number,
2253 column_number); 2185 column_number);
2254 if (loc != NULL) { 2186 if (loc != NULL) {
2255 return loc->AddRepeated(this); 2187 return loc->AddRepeated(this);
2256 } 2188 }
2257 return NULL; 2189 return NULL;
2258 } 2190 }
2259 2191
2260 2192
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
2551 } 2483 }
2552 } 2484 }
2553 2485
2554 2486
2555 // static 2487 // static
2556 void Debugger::SetEventHandler(EventHandler* handler) { 2488 void Debugger::SetEventHandler(EventHandler* handler) {
2557 event_handler_ = handler; 2489 event_handler_ = handler;
2558 } 2490 }
2559 2491
2560 2492
2561 void Debugger::Pause(DebuggerEvent* event) { 2493 void Debugger::Pause(ServiceEvent* event) {
2562 ASSERT(!IsPaused()); // No recursive pausing. 2494 ASSERT(event->IsPause()); // Should call InvokeEventHandler instead.
2495 ASSERT(!ignore_breakpoints_); // We shouldn't get here when ignoring bpts.
2496 ASSERT(!IsPaused()); // No recursive pausing.
2563 ASSERT(obj_cache_ == NULL); 2497 ASSERT(obj_cache_ == NULL);
2564 2498
2565 pause_event_ = event; 2499 pause_event_ = event;
2566 pause_event_->UpdateTimestamp(); 2500 pause_event_->UpdateTimestamp();
2567 obj_cache_ = new RemoteObjectCache(64); 2501 obj_cache_ = new RemoteObjectCache(64);
2568 2502
2569 // We are about to invoke the debuggers event handler. Disable interrupts 2503 // We are about to invoke the debugger's event handler. Disable
2570 // for this thread while waiting for debug commands over the service protocol. 2504 // interrupts for this thread while waiting for debug commands over
2505 // the service protocol.
2571 { 2506 {
2572 Thread* thread = Thread::Current(); 2507 Thread* thread = Thread::Current();
2573 DisableThreadInterruptsScope dtis(thread); 2508 DisableThreadInterruptsScope dtis(thread);
2574 TimelineDurationScope tds(thread, 2509 TimelineDurationScope tds(thread,
2575 Timeline::GetDebuggerStream(), 2510 Timeline::GetDebuggerStream(),
2576 "Debugger Pause"); 2511 "Debugger Pause");
2577 InvokeEventHandler(event); 2512
2513 // Send the pause event.
2514 Service::HandleEvent(event);
2515
2516 {
2517 TransitionVMToNative transition(Thread::Current());
2518 if (FLAG_steal_breakpoints || (event_handler_ == NULL)) {
2519 // We allow the embedder's default breakpoint handler to be overridden.
2520 isolate_->PauseEventHandler();
2521 } else if (event_handler_ != NULL) {
2522 (*event_handler_)(event);
2523 }
2524 }
2525
2526 // Notify the service that we have resumed.
2527 const Error& error =
2528 Error::Handle(Thread::Current()->sticky_error());
2529 ASSERT(error.IsNull() ||
2530 error.IsUnwindError() ||
2531 error.IsUnhandledException());
2532
2533 // Only send a resume event when the isolate is not unwinding.
2534 if (!error.IsUnwindError()) {
2535 ServiceEvent resume_event(event->isolate(), ServiceEvent::kResume);
2536 resume_event.set_top_frame(event->top_frame());
2537 Service::HandleEvent(&resume_event);
2538 }
2578 } 2539 }
2579 2540
2580 pause_event_ = NULL; 2541 pause_event_ = NULL;
2581 obj_cache_ = NULL; // Zone allocated 2542 obj_cache_ = NULL; // Zone allocated
2582 } 2543 }
2583 2544
2584 2545
2585 void Debugger::EnterSingleStepMode() { 2546 void Debugger::EnterSingleStepMode() {
2586 stepping_fp_ = 0; 2547 stepping_fp_ = 0;
2587 DeoptimizeWorld(); 2548 DeoptimizeWorld();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2650 resume_action_ = kContinue; 2611 resume_action_ = kContinue;
2651 stepping_fp_ = 0; 2612 stepping_fp_ = 0;
2652 isolate_->set_single_step(false); 2613 isolate_->set_single_step(false);
2653 ASSERT(!IsPaused()); 2614 ASSERT(!IsPaused());
2654 ASSERT(obj_cache_ == NULL); 2615 ASSERT(obj_cache_ == NULL);
2655 if ((bpt != NULL) && bpt->IsSingleShot()) { 2616 if ((bpt != NULL) && bpt->IsSingleShot()) {
2656 RemoveBreakpoint(bpt->id()); 2617 RemoveBreakpoint(bpt->id());
2657 bpt = NULL; 2618 bpt = NULL;
2658 } 2619 }
2659 2620
2660 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached); 2621 ServiceEvent event(isolate_, ServiceEvent::kPauseBreakpoint);
2661 event.set_top_frame(top_frame); 2622 event.set_top_frame(top_frame);
2662 event.set_breakpoint(bpt); 2623 event.set_breakpoint(bpt);
2663 event.set_at_async_jump(IsAtAsyncJump(top_frame)); 2624 event.set_at_async_jump(IsAtAsyncJump(top_frame));
2664 Pause(&event); 2625 Pause(&event);
2665 } 2626 }
2666 2627
2667 2628
2668 bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) { 2629 bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
2669 Zone* zone = Thread::Current()->zone(); 2630 Zone* zone = Thread::Current()->zone();
2670 Object& closure_or_null = 2631 Object& closure_or_null =
2671 Object::Handle(zone, top_frame->GetAsyncOperation()); 2632 Object::Handle(zone, top_frame->GetAsyncOperation());
2672 if (!closure_or_null.IsNull()) { 2633 if (!closure_or_null.IsNull()) {
2673 ASSERT(closure_or_null.IsInstance()); 2634 ASSERT(closure_or_null.IsInstance());
2674 ASSERT(Instance::Cast(closure_or_null).IsClosure()); 2635 ASSERT(Instance::Cast(closure_or_null).IsClosure());
2675 const Script& script = Script::Handle(zone, top_frame->SourceScript()); 2636 const Script& script = Script::Handle(zone, top_frame->SourceScript());
2676 const TokenStream& tokens = TokenStream::Handle(zone, script.tokens()); 2637 const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
2677 TokenStream::Iterator iter(zone, tokens, top_frame->TokenPos()); 2638 TokenStream::Iterator iter(zone, tokens, top_frame->TokenPos());
2678 if ((iter.CurrentTokenKind() == Token::kIDENT) && 2639 if ((iter.CurrentTokenKind() == Token::kIDENT) &&
2679 ((iter.CurrentLiteral() == Symbols::Await().raw()) || 2640 ((iter.CurrentLiteral() == Symbols::Await().raw()) ||
2680 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) { 2641 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) {
2681 return true; 2642 return true;
2682 } 2643 }
2683 } 2644 }
2684 return false; 2645 return false;
2685 } 2646 }
2686 2647
2687 RawError* Debugger::DebuggerStepCallback() { 2648 RawError* Debugger::PauseStepping() {
2688 ASSERT(isolate_->single_step()); 2649 ASSERT(isolate_->single_step());
2689 // Don't pause recursively. 2650 // Don't pause recursively.
2690 if (IsPaused()) { 2651 if (IsPaused()) {
2691 return Error::null(); 2652 return Error::null();
2692 } 2653 }
2693 if (skip_next_step_) { 2654 if (skip_next_step_) {
2694 skip_next_step_ = false; 2655 skip_next_step_ = false;
2695 return Error::null(); 2656 return Error::null();
2696 } 2657 }
2697 2658
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n", 2695 OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n",
2735 String::Handle(frame->SourceUrl()).ToCString(), 2696 String::Handle(frame->SourceUrl()).ToCString(),
2736 frame->LineNumber(), 2697 frame->LineNumber(),
2737 String::Handle(frame->QualifiedFunctionName()).ToCString(), 2698 String::Handle(frame->QualifiedFunctionName()).ToCString(),
2738 frame->TokenPos().ToCString()); 2699 frame->TokenPos().ToCString());
2739 } 2700 }
2740 2701
2741 ASSERT(stack_trace_ == NULL); 2702 ASSERT(stack_trace_ == NULL);
2742 stack_trace_ = CollectStackTrace(); 2703 stack_trace_ = CollectStackTrace();
2743 // If this step callback is part of stepping over an await statement, 2704 // If this step callback is part of stepping over an await statement,
2744 // we saved the synthetic async breakpoint in SignalBpReached. We report 2705 // we saved the synthetic async breakpoint in PauseBreakpoint. We report
2745 // that we are paused at that breakpoint and then delete it after continuing. 2706 // that we are paused at that breakpoint and then delete it after continuing.
2746 SignalPausedEvent(frame, synthetic_async_breakpoint_); 2707 SignalPausedEvent(frame, synthetic_async_breakpoint_);
2747 if (synthetic_async_breakpoint_ != NULL) { 2708 if (synthetic_async_breakpoint_ != NULL) {
2748 RemoveBreakpoint(synthetic_async_breakpoint_->id()); 2709 RemoveBreakpoint(synthetic_async_breakpoint_->id());
2749 synthetic_async_breakpoint_ = NULL; 2710 synthetic_async_breakpoint_ = NULL;
2750 } 2711 }
2751 HandleSteppingRequest(stack_trace_); 2712 HandleSteppingRequest(stack_trace_);
2752 stack_trace_ = NULL; 2713 stack_trace_ = NULL;
2753 2714
2754 // If any error occurred while in the debug message loop, return it here. 2715 // If any error occurred while in the debug message loop, return it here.
2755 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 2716 const Error& error = Error::Handle(Thread::Current()->sticky_error());
2756 Thread::Current()->clear_sticky_error(); 2717 Thread::Current()->clear_sticky_error();
2757 return error.raw(); 2718 return error.raw();
2758 } 2719 }
2759 2720
2760 2721
2761 RawError* Debugger::SignalBpReached() { 2722 RawError* Debugger::PauseBreakpoint() {
2762 // We ignore this breakpoint when the VM is executing code invoked 2723 // We ignore this breakpoint when the VM is executing code invoked
2763 // by the debugger to evaluate variables values, or when we see a nested 2724 // by the debugger to evaluate variables values, or when we see a nested
2764 // breakpoint or exception event. 2725 // breakpoint or exception event.
2765 if (ignore_breakpoints_ || IsPaused()) { 2726 if (ignore_breakpoints_ || IsPaused()) {
2766 return Error::null(); 2727 return Error::null();
2767 } 2728 }
2768 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2729 DebuggerStackTrace* stack_trace = CollectStackTrace();
2769 ASSERT(stack_trace->Length() > 0); 2730 ASSERT(stack_trace->Length() > 0);
2770 ActivationFrame* top_frame = stack_trace->FrameAt(0); 2731 ActivationFrame* top_frame = stack_trace->FrameAt(0);
2771 ASSERT(top_frame != NULL); 2732 ASSERT(top_frame != NULL);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2871 RemoveInternalBreakpoints(); 2832 RemoveInternalBreakpoints();
2872 } 2833 }
2873 2834
2874 // If any error occurred while in the debug message loop, return it here. 2835 // If any error occurred while in the debug message loop, return it here.
2875 const Error& error = Error::Handle(Thread::Current()->sticky_error()); 2836 const Error& error = Error::Handle(Thread::Current()->sticky_error());
2876 Thread::Current()->clear_sticky_error(); 2837 Thread::Current()->clear_sticky_error();
2877 return error.raw(); 2838 return error.raw();
2878 } 2839 }
2879 2840
2880 2841
2881 void Debugger::BreakHere(const String& msg) { 2842 void Debugger::PauseDeveloper(const String& msg) {
2882 // We ignore this breakpoint when the VM is executing code invoked 2843 // We ignore this breakpoint when the VM is executing code invoked
2883 // by the debugger to evaluate variables values, or when we see a nested 2844 // by the debugger to evaluate variables values, or when we see a nested
2884 // breakpoint or exception event. 2845 // breakpoint or exception event.
2885 if (ignore_breakpoints_ || IsPaused()) { 2846 if (ignore_breakpoints_ || IsPaused()) {
2886 return; 2847 return;
2887 } 2848 }
2888 2849
2889 if (!HasDebugEventHandler()) { 2850 if (!NeedsDebugEvents()) {
2890 OS::Print("Hit debugger!"); 2851 OS::Print("Hit debugger!");
2891 } 2852 }
2892 2853
2893 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2854 DebuggerStackTrace* stack_trace = CollectStackTrace();
2894 ASSERT(stack_trace->Length() > 0); 2855 ASSERT(stack_trace->Length() > 0);
2895 ASSERT(stack_trace_ == NULL); 2856 ASSERT(stack_trace_ == NULL);
2896 stack_trace_ = stack_trace; 2857 stack_trace_ = stack_trace;
2897 2858
2898 // TODO(johnmccutchan): Send |msg| to Observatory. 2859 // TODO(johnmccutchan): Send |msg| to Observatory.
2899 2860
2900 // We are in the native call to Debugger_breakHere or Debugger_breakHereIf, 2861 // We are in the native call to Developer_debugger. the developer
2901 // the developer gets a better experience by not seeing this call. To 2862 // gets a better experience by not seeing this call. To accomplish
2902 // accomplish this, we continue execution until the call exits (step out). 2863 // this, we continue execution until the call exits (step out).
2903 SetStepOut(); 2864 SetStepOut();
2904 HandleSteppingRequest(stack_trace_); 2865 HandleSteppingRequest(stack_trace_);
2905 2866
2906 stack_trace_ = NULL; 2867 stack_trace_ = NULL;
2907 } 2868 }
2908 2869
2909 2870
2910 void Debugger::Initialize(Isolate* isolate) { 2871 void Debugger::Initialize(Isolate* isolate) {
2911 if (initialized_) { 2872 if (initialized_) {
2912 return; 2873 return;
2913 } 2874 }
2914 isolate_ = isolate; 2875 isolate_ = isolate;
2915 2876
2916 // Use the isolate's control port as the isolate_id for debugging. 2877 // Use the isolate's control port as the isolate_id for debugging.
2917 // This port will be used as a unique ID to represent the isolate in the 2878 // This port will be used as a unique ID to represent the isolate in
2918 // debugger wire protocol messages. 2879 // the debugger embedder api.
2919 isolate_id_ = isolate_->main_port(); 2880 isolate_id_ = isolate_->main_port();
2920 initialized_ = true; 2881 initialized_ = true;
2921 } 2882 }
2922 2883
2923 2884
2924 void Debugger::NotifyIsolateCreated() { 2885 void Debugger::NotifyIsolateCreated() {
2925 // Signal isolate creation event. 2886 if (NeedsIsolateEvents()) {
2926 if ((isolate_ != Dart::vm_isolate()) && 2887 ServiceEvent event(isolate_, ServiceEvent::kIsolateStart);
2927 !ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { 2888 InvokeEventHandler(&event);
2928 SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
2929 creation_message_sent_ = true;
2930 } 2889 }
2931 } 2890 }
2932 2891
2933 2892
2934 // Return innermost closure contained in 'function' that contains 2893 // Return innermost closure contained in 'function' that contains
2935 // the given token position. 2894 // the given token position.
2936 RawFunction* Debugger::FindInnermostClosure(const Function& function, 2895 RawFunction* Debugger::FindInnermostClosure(const Function& function,
2937 TokenPosition token_pos) { 2896 TokenPosition token_pos) {
2938 Zone* zone = Thread::Current()->zone(); 2897 Zone* zone = Thread::Current()->zone();
2939 const Script& outer_origin = Script::Handle(zone, function.script()); 2898 const Script& outer_origin = Script::Handle(zone, function.script());
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 "requested col %" Pd ")\n", 2980 "requested col %" Pd ")\n",
3022 bpt->id(), 2981 bpt->id(),
3023 loc->token_pos().ToCString(), 2982 loc->token_pos().ToCString(),
3024 loc->LineNumber(), 2983 loc->LineNumber(),
3025 loc->ColumnNumber(), 2984 loc->ColumnNumber(),
3026 func.ToFullyQualifiedCString(), 2985 func.ToFullyQualifiedCString(),
3027 requested_pos.ToCString(), 2986 requested_pos.ToCString(),
3028 requested_end_pos.ToCString(), 2987 requested_end_pos.ToCString(),
3029 loc->requested_column_number()); 2988 loc->requested_column_number());
3030 } 2989 }
3031 SignalBpResolved(bpt); 2990 SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
3032 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt);
3033 bpt = bpt->next(); 2991 bpt = bpt->next();
3034 } 2992 }
3035 } 2993 }
3036 ASSERT(loc->IsResolved()); 2994 ASSERT(loc->IsResolved());
3037 if (FLAG_verbose_debug) { 2995 if (FLAG_verbose_debug) {
3038 Breakpoint* bpt = loc->breakpoints(); 2996 Breakpoint* bpt = loc->breakpoints();
3039 while (bpt != NULL) { 2997 while (bpt != NULL) {
3040 OS::Print("Setting breakpoint %" Pd " at line %" Pd " col %" Pd "" 2998 OS::Print("Setting breakpoint %" Pd " at line %" Pd " col %" Pd ""
3041 " for %s '%s'\n", 2999 " for %s '%s'\n",
3042 bpt->id(), 3000 bpt->id(),
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
3211 Breakpoint* prev_bpt = NULL; 3169 Breakpoint* prev_bpt = NULL;
3212 Breakpoint* curr_bpt = curr_loc->breakpoints(); 3170 Breakpoint* curr_bpt = curr_loc->breakpoints();
3213 while (curr_bpt != NULL) { 3171 while (curr_bpt != NULL) {
3214 if (curr_bpt->id() == bp_id) { 3172 if (curr_bpt->id() == bp_id) {
3215 if (prev_bpt == NULL) { 3173 if (prev_bpt == NULL) {
3216 curr_loc->set_breakpoints(curr_bpt->next()); 3174 curr_loc->set_breakpoints(curr_bpt->next());
3217 } else { 3175 } else {
3218 prev_bpt->set_next(curr_bpt->next()); 3176 prev_bpt->set_next(curr_bpt->next());
3219 } 3177 }
3220 3178
3221 SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt); 3179 SendBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt);
3222 3180
3223 // Remove references from the current debugger pause event. 3181 // Remove references from the current debugger pause event.
3224 if (pause_event_ != NULL && 3182 if (pause_event_ != NULL && pause_event_->breakpoint() == curr_bpt) {
3225 pause_event_->type() == DebuggerEvent::kBreakpointReached &&
3226 pause_event_->breakpoint() == curr_bpt) {
3227 pause_event_->set_breakpoint(NULL); 3183 pause_event_->set_breakpoint(NULL);
3228 } 3184 }
3229 break; 3185 break;
3230 } 3186 }
3231 3187
3232 prev_bpt = curr_bpt; 3188 prev_bpt = curr_bpt;
3233 curr_bpt = curr_bpt->next(); 3189 curr_bpt = curr_bpt->next();
3234 } 3190 }
3235 3191
3236 if (curr_loc->breakpoints() == NULL) { 3192 if (curr_loc->breakpoints() == NULL) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 3316
3361 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 3317 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3362 ASSERT(bpt->next() == NULL); 3318 ASSERT(bpt->next() == NULL);
3363 bpt->set_next(code_breakpoints_); 3319 bpt->set_next(code_breakpoints_);
3364 code_breakpoints_ = bpt; 3320 code_breakpoints_ = bpt;
3365 } 3321 }
3366 3322
3367 #endif // !PRODUCT 3323 #endif // !PRODUCT
3368 3324
3369 } // namespace dart 3325 } // namespace dart
OLDNEW
« 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