| OLD | NEW |
| 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_event.h" |
| 22 #include "vm/service_isolate.h" | 23 #include "vm/service_isolate.h" |
| 23 #include "vm/service.h" | 24 #include "vm/service.h" |
| 24 #include "vm/stack_frame.h" | 25 #include "vm/stack_frame.h" |
| 25 #include "vm/stub_code.h" | 26 #include "vm/stub_code.h" |
| 26 #include "vm/symbols.h" | 27 #include "vm/symbols.h" |
| 27 #include "vm/visitor.h" | 28 #include "vm/visitor.h" |
| 28 | 29 |
| 29 | 30 |
| 30 namespace dart { | 31 namespace dart { |
| 31 | 32 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 | 110 |
| 110 void SourceBreakpoint::SetResolved(const Function& func, intptr_t token_pos) { | 111 void SourceBreakpoint::SetResolved(const Function& func, intptr_t token_pos) { |
| 111 ASSERT(!IsLatent()); | 112 ASSERT(!IsLatent()); |
| 112 ASSERT(func.script() == script_); | 113 ASSERT(func.script() == script_); |
| 113 ASSERT((func.token_pos() <= token_pos) && | 114 ASSERT((func.token_pos() <= token_pos) && |
| 114 (token_pos <= func.end_token_pos())); | 115 (token_pos <= func.end_token_pos())); |
| 115 ASSERT(func.is_debuggable()); | 116 ASSERT(func.is_debuggable()); |
| 116 function_ = func.raw(); | 117 function_ = func.raw(); |
| 117 token_pos_ = token_pos; | 118 token_pos_ = token_pos; |
| 118 end_token_pos_ = token_pos; | 119 end_token_pos_ = token_pos; |
| 119 line_number_ = -1; // Recalcualte lazily. | 120 line_number_ = -1; // Recalculate lazily. |
| 120 is_resolved_ = true; | 121 is_resolved_ = true; |
| 121 } | 122 } |
| 122 | 123 |
| 123 | 124 |
| 124 // TODO(hausner): Get rid of library parameter. A source breakpoint location | 125 // TODO(hausner): Get rid of library parameter. A source breakpoint location |
| 125 // does not imply a library, since the same source code can be included | 126 // does not imply a library, since the same source code can be included |
| 126 // in more than one library, e.g. the text location of mixin functions. | 127 // in more than one library, e.g. the text location of mixin functions. |
| 127 void SourceBreakpoint::GetCodeLocation(Library* lib, | 128 void SourceBreakpoint::GetCodeLocation(Library* lib, |
| 128 Script* script, | 129 Script* script, |
| 129 intptr_t* pos) { | 130 intptr_t* pos) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 | 167 |
| 167 | 168 |
| 168 void SourceBreakpoint::PrintJSON(JSONStream* stream) { | 169 void SourceBreakpoint::PrintJSON(JSONStream* stream) { |
| 169 Isolate* isolate = Isolate::Current(); | 170 Isolate* isolate = Isolate::Current(); |
| 170 | 171 |
| 171 JSONObject jsobj(stream); | 172 JSONObject jsobj(stream); |
| 172 jsobj.AddProperty("type", "Breakpoint"); | 173 jsobj.AddProperty("type", "Breakpoint"); |
| 173 | 174 |
| 174 jsobj.AddPropertyF("id", "breakpoints/%" Pd "", id()); | 175 jsobj.AddPropertyF("id", "breakpoints/%" Pd "", id()); |
| 175 jsobj.AddProperty("breakpointNumber", id()); | 176 jsobj.AddProperty("breakpointNumber", id()); |
| 176 jsobj.AddProperty("enabled", IsEnabled()); | |
| 177 jsobj.AddProperty("resolved", IsResolved()); | 177 jsobj.AddProperty("resolved", IsResolved()); |
| 178 | 178 |
| 179 Library& library = Library::Handle(isolate); | 179 Library& library = Library::Handle(isolate); |
| 180 Script& script = Script::Handle(isolate); | 180 Script& script = Script::Handle(isolate); |
| 181 intptr_t token_pos; | 181 intptr_t token_pos; |
| 182 GetCodeLocation(&library, &script, &token_pos); | 182 GetCodeLocation(&library, &script, &token_pos); |
| 183 { | 183 { |
| 184 JSONObject location(&jsobj, "location"); | 184 JSONObject location(&jsobj, "location"); |
| 185 location.AddProperty("type", "Location"); | 185 location.AddProperty("type", "Location"); |
| 186 location.AddProperty("script", script); | 186 location.AddProperty("script", script); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 bool Debugger::HasEventHandler() { | 223 bool Debugger::HasEventHandler() { |
| 224 return (event_handler_ != NULL) || Service::NeedsDebuggerEvents(); | 224 return (event_handler_ != NULL) || Service::NeedsDebuggerEvents(); |
| 225 } | 225 } |
| 226 | 226 |
| 227 | 227 |
| 228 void Debugger::InvokeEventHandler(DebuggerEvent* event) { | 228 void Debugger::InvokeEventHandler(DebuggerEvent* event) { |
| 229 ASSERT(HasEventHandler()); | 229 ASSERT(HasEventHandler()); |
| 230 | 230 |
| 231 // Give the event to the Service first, as the debugger event handler | 231 // Give the event to the Service first, as the debugger event handler |
| 232 // may go into a message loop and the Service will not. | 232 // may go into a message loop and the Service will not. |
| 233 if (Service::NeedsDebuggerEvents()) { | 233 // |
| 234 Service::HandleDebuggerEvent(event); | 234 // kBreakpointResolved events are handled differently in the vm |
| 235 // service, so suppress them here. |
| 236 if (Service::NeedsDebuggerEvents() && |
| 237 (event->type() != DebuggerEvent::kBreakpointResolved)) { |
| 238 ServiceEvent service_event(event); |
| 239 Service::HandleEvent(&service_event); |
| 235 } | 240 } |
| 236 | 241 |
| 237 if (event_handler_ != NULL) { | 242 if (event_handler_ != NULL) { |
| 238 (*event_handler_)(event); | 243 (*event_handler_)(event); |
| 239 } | 244 } |
| 245 |
| 246 if (Service::NeedsDebuggerEvents() && event->IsPauseEvent()) { |
| 247 // If we were paused, notify the service that we have resumed. |
| 248 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); |
| 249 service_event.set_top_frame(event->top_frame()); |
| 250 Service::HandleEvent(&service_event); |
| 251 } |
| 240 } | 252 } |
| 241 | 253 |
| 242 | 254 |
| 243 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) { | 255 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) { |
| 244 if (HasEventHandler()) { | 256 if (HasEventHandler()) { |
| 245 DebuggerEvent event(isolate_, type); | 257 DebuggerEvent event(isolate_, type); |
| 246 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID); | 258 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID); |
| 247 if (type == DebuggerEvent::kIsolateInterrupted) { | 259 if (type == DebuggerEvent::kIsolateInterrupted) { |
| 248 DebuggerStackTrace* trace = CollectStackTrace(); | 260 DebuggerStackTrace* trace = CollectStackTrace(); |
| 249 ASSERT(trace->Length() > 0); | 261 ASSERT(trace->Length() > 0); |
| 262 event.set_top_frame(trace->FrameAt(0)); |
| 250 ASSERT(stack_trace_ == NULL); | 263 ASSERT(stack_trace_ == NULL); |
| 251 stack_trace_ = trace; | 264 stack_trace_ = trace; |
| 252 resume_action_ = kContinue; | 265 resume_action_ = kContinue; |
| 253 Pause(&event); | 266 Pause(&event); |
| 254 HandleSteppingRequest(trace); | 267 HandleSteppingRequest(trace); |
| 255 stack_trace_ = NULL; | 268 stack_trace_ = NULL; |
| 256 } else { | 269 } else { |
| 257 InvokeEventHandler(&event); | 270 InvokeEventHandler(&event); |
| 258 } | 271 } |
| 259 } | 272 } |
| 260 } | 273 } |
| 261 | 274 |
| 262 | 275 |
| 263 void Debugger::SignalIsolateInterrupted() { | 276 void Debugger::SignalIsolateInterrupted() { |
| 264 if (HasEventHandler()) { | 277 if (HasEventHandler()) { |
| 265 Debugger* debugger = Isolate::Current()->debugger(); | 278 Debugger* debugger = Isolate::Current()->debugger(); |
| 266 ASSERT(debugger != NULL); | 279 ASSERT(debugger != NULL); |
| 267 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted); | 280 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted); |
| 268 } | 281 } |
| 269 } | 282 } |
| 270 | 283 |
| 271 | 284 |
| 285 // The vm service handles breakpoint notifications in a different way |
| 286 // than the regular debugger breakpoint notifications. |
| 287 static void SendServiceBreakpointEvent(ServiceEvent::EventType type, |
| 288 SourceBreakpoint* bpt) { |
| 289 if (Service::NeedsDebuggerEvents() /*&& !bpt->IsOneShot()*/) { |
| 290 ServiceEvent service_event(Isolate::Current(), type); |
| 291 service_event.set_breakpoint(bpt); |
| 292 Service::HandleEvent(&service_event); |
| 293 } |
| 294 } |
| 295 |
| 296 |
| 272 const char* Debugger::QualifiedFunctionName(const Function& func) { | 297 const char* Debugger::QualifiedFunctionName(const Function& func) { |
| 273 const String& func_name = String::Handle(func.name()); | 298 const String& func_name = String::Handle(func.name()); |
| 274 Class& func_class = Class::Handle(func.Owner()); | 299 Class& func_class = Class::Handle(func.Owner()); |
| 275 String& class_name = String::Handle(func_class.Name()); | 300 String& class_name = String::Handle(func_class.Name()); |
| 276 | 301 |
| 277 const char* kFormat = "%s%s%s"; | 302 const char* kFormat = "%s%s%s"; |
| 278 intptr_t len = OS::SNPrint(NULL, 0, kFormat, | 303 intptr_t len = OS::SNPrint(NULL, 0, kFormat, |
| 279 func_class.IsTopLevel() ? "" : class_name.ToCString(), | 304 func_class.IsTopLevel() ? "" : class_name.ToCString(), |
| 280 func_class.IsTopLevel() ? "" : ".", | 305 func_class.IsTopLevel() ? "" : ".", |
| 281 func_name.ToCString()); | 306 func_name.ToCString()); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 } | 527 } |
| 503 ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext()); | 528 ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext()); |
| 504 return Context::RawCast(GetLocalVar(var_info.index())); | 529 return Context::RawCast(GetLocalVar(var_info.index())); |
| 505 } | 530 } |
| 506 } | 531 } |
| 507 UNREACHABLE(); | 532 UNREACHABLE(); |
| 508 return Context::null(); | 533 return Context::null(); |
| 509 } | 534 } |
| 510 | 535 |
| 511 | 536 |
| 512 const char* DebuggerEvent::EventTypeToCString(EventType type) { | |
| 513 switch (type) { | |
| 514 case kBreakpointReached: | |
| 515 return "BreakpointReached"; | |
| 516 case kBreakpointResolved: | |
| 517 return "BreakpointResolved"; | |
| 518 case kExceptionThrown: | |
| 519 return "ExceptionThrown"; | |
| 520 case kIsolateCreated: | |
| 521 return "IsolateCreated"; | |
| 522 case kIsolateShutdown: | |
| 523 return "IsolateShutdown"; | |
| 524 case kIsolateInterrupted: | |
| 525 return "IsolateInterrupted"; | |
| 526 case kIsolateResumed: | |
| 527 return "IsolateResumed"; | |
| 528 default: | |
| 529 UNREACHABLE(); | |
| 530 return "Unknown"; | |
| 531 } | |
| 532 } | |
| 533 | |
| 534 | |
| 535 void DebuggerEvent::PrintJSON(JSONStream* js) const { | |
| 536 JSONObject jsobj(js); | |
| 537 jsobj.AddProperty("type", "ServiceEvent"); | |
| 538 // TODO(turnidge): Drop the 'id' for things like DebuggerEvent. | |
| 539 jsobj.AddProperty("id", ""); | |
| 540 jsobj.AddProperty("eventType", EventTypeToCString(type())); | |
| 541 jsobj.AddProperty("isolate", isolate()); | |
| 542 if ((type() == kBreakpointResolved || type() == kBreakpointReached) && | |
| 543 breakpoint() != NULL) { | |
| 544 // TODO(turnidge): Make this a breakpoint ref. | |
| 545 jsobj.AddProperty("breakpoint", breakpoint()); | |
| 546 } | |
| 547 if (type() == kExceptionThrown) { | |
| 548 jsobj.AddProperty("exception", *(exception())); | |
| 549 } | |
| 550 } | |
| 551 | |
| 552 | |
| 553 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( | 537 ActivationFrame* DebuggerStackTrace::GetHandlerFrame( |
| 554 const Instance& exc_obj) const { | 538 const Instance& exc_obj) const { |
| 555 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); | 539 ExceptionHandlers& handlers = ExceptionHandlers::Handle(); |
| 556 Array& handled_types = Array::Handle(); | 540 Array& handled_types = Array::Handle(); |
| 557 AbstractType& type = Type::Handle(); | 541 AbstractType& type = Type::Handle(); |
| 558 const TypeArguments& no_instantiator = TypeArguments::Handle(); | 542 const TypeArguments& no_instantiator = TypeArguments::Handle(); |
| 559 for (intptr_t frame_index = 0; | 543 for (intptr_t frame_index = 0; |
| 560 frame_index < Length(); | 544 frame_index < Length(); |
| 561 frame_index++) { | 545 frame_index++) { |
| 562 ActivationFrame* frame = FrameAt(frame_index); | 546 ActivationFrame* frame = FrameAt(frame_index); |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 func_name, | 865 func_name, |
| 882 url.ToCString(), | 866 url.ToCString(), |
| 883 line, | 867 line, |
| 884 ctx_.ToCString(), | 868 ctx_.ToCString(), |
| 885 ContextLevel()); | 869 ContextLevel()); |
| 886 } | 870 } |
| 887 | 871 |
| 888 | 872 |
| 889 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) { | 873 void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) { |
| 890 const Script& script = Script::Handle(SourceScript()); | 874 const Script& script = Script::Handle(SourceScript()); |
| 875 jsobj->AddProperty("type", "Frame"); |
| 891 jsobj->AddProperty("script", script); | 876 jsobj->AddProperty("script", script); |
| 892 jsobj->AddProperty("tokenPos", TokenPos()); | 877 jsobj->AddProperty("tokenPos", TokenPos()); |
| 893 jsobj->AddProperty("function", function()); | 878 jsobj->AddProperty("function", function()); |
| 894 jsobj->AddProperty("code", code()); | 879 jsobj->AddProperty("code", code()); |
| 895 { | 880 { |
| 896 JSONArray jsvars(jsobj, "vars"); | 881 JSONArray jsvars(jsobj, "vars"); |
| 897 const int num_vars = NumLocalVariables(); | 882 const int num_vars = NumLocalVariables(); |
| 898 for (intptr_t v = 0; v < num_vars; v++) { | 883 for (intptr_t v = 0; v < num_vars; v++) { |
| 899 JSONObject jsvar(&jsvars); | 884 JSONObject jsvar(&jsvars); |
| 900 String& var_name = String::Handle(); | 885 String& var_name = String::Handle(); |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 (!HasEventHandler()) || | 1389 (!HasEventHandler()) || |
| 1405 (exc_pause_info_ == kNoPauseOnExceptions)) { | 1390 (exc_pause_info_ == kNoPauseOnExceptions)) { |
| 1406 return; | 1391 return; |
| 1407 } | 1392 } |
| 1408 DebuggerStackTrace* stack_trace = CollectStackTrace(); | 1393 DebuggerStackTrace* stack_trace = CollectStackTrace(); |
| 1409 if (!ShouldPauseOnException(stack_trace, exc)) { | 1394 if (!ShouldPauseOnException(stack_trace, exc)) { |
| 1410 return; | 1395 return; |
| 1411 } | 1396 } |
| 1412 DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown); | 1397 DebuggerEvent event(isolate_, DebuggerEvent::kExceptionThrown); |
| 1413 event.set_exception(&exc); | 1398 event.set_exception(&exc); |
| 1399 ASSERT(stack_trace->Length() > 0); |
| 1400 event.set_top_frame(stack_trace->FrameAt(0)); |
| 1414 ASSERT(stack_trace_ == NULL); | 1401 ASSERT(stack_trace_ == NULL); |
| 1415 stack_trace_ = stack_trace; | 1402 stack_trace_ = stack_trace; |
| 1416 Pause(&event); | 1403 Pause(&event); |
| 1417 stack_trace_ = NULL; | 1404 stack_trace_ = NULL; |
| 1418 } | 1405 } |
| 1419 | 1406 |
| 1420 | 1407 |
| 1421 static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { | 1408 static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) { |
| 1422 TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens); | 1409 TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens); |
| 1423 ASSERT(iter.IsValid()); | 1410 ASSERT(iter.IsValid()); |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1725 bpt->Enable(); | 1712 bpt->Enable(); |
| 1726 if (FLAG_verbose_debug) { | 1713 if (FLAG_verbose_debug) { |
| 1727 intptr_t line_number; | 1714 intptr_t line_number; |
| 1728 script.GetTokenLocation(breakpoint_pos, &line_number, NULL); | 1715 script.GetTokenLocation(breakpoint_pos, &line_number, NULL); |
| 1729 OS::Print("Resolved BP for " | 1716 OS::Print("Resolved BP for " |
| 1730 "function '%s' at line %" Pd "\n", | 1717 "function '%s' at line %" Pd "\n", |
| 1731 func.ToFullyQualifiedCString(), | 1718 func.ToFullyQualifiedCString(), |
| 1732 line_number); | 1719 line_number); |
| 1733 } | 1720 } |
| 1734 SignalBpResolved(bpt); | 1721 SignalBpResolved(bpt); |
| 1722 SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt); |
| 1735 return bpt; | 1723 return bpt; |
| 1736 } | 1724 } |
| 1737 } | 1725 } |
| 1738 // There is no compiled function at this token position. | 1726 // There is no compiled function at this token position. |
| 1739 // Register an unresolved breakpoint. | 1727 // Register an unresolved breakpoint. |
| 1740 if (FLAG_verbose_debug && !func.IsNull()) { | 1728 if (FLAG_verbose_debug && !func.IsNull()) { |
| 1741 intptr_t line_number; | 1729 intptr_t line_number; |
| 1742 script.GetTokenLocation(token_pos, &line_number, NULL); | 1730 script.GetTokenLocation(token_pos, &line_number, NULL); |
| 1743 OS::Print("Registering pending breakpoint for " | 1731 OS::Print("Registering pending breakpoint for " |
| 1744 "uncompiled function '%s' at line %" Pd "\n", | 1732 "uncompiled function '%s' at line %" Pd "\n", |
| 1745 func.ToFullyQualifiedCString(), | 1733 func.ToFullyQualifiedCString(), |
| 1746 line_number); | 1734 line_number); |
| 1747 } | 1735 } |
| 1748 SourceBreakpoint* bpt = GetSourceBreakpoint(script, token_pos); | 1736 SourceBreakpoint* bpt = GetSourceBreakpoint(script, token_pos); |
| 1749 if (bpt == NULL) { | 1737 if (bpt == NULL) { |
| 1750 bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos); | 1738 bpt = new SourceBreakpoint(nextId(), script, token_pos, last_token_pos); |
| 1751 RegisterSourceBreakpoint(bpt); | 1739 RegisterSourceBreakpoint(bpt); |
| 1740 SendServiceBreakpointEvent(ServiceEvent::kBreakpointAdded, bpt); |
| 1752 } | 1741 } |
| 1753 bpt->Enable(); | 1742 bpt->Enable(); |
| 1754 return bpt; | 1743 return bpt; |
| 1755 } | 1744 } |
| 1756 | 1745 |
| 1757 | 1746 |
| 1758 // Synchronize the enabled/disabled state of all code breakpoints | 1747 // Synchronize the enabled/disabled state of all code breakpoints |
| 1759 // associated with the source breakpoint bpt. | 1748 // associated with the source breakpoint bpt. |
| 1760 void Debugger::SyncBreakpoint(SourceBreakpoint* bpt) { | 1749 void Debugger::SyncBreakpoint(SourceBreakpoint* bpt) { |
| 1761 CodeBreakpoint* cbpt = code_breakpoints_; | 1750 CodeBreakpoint* cbpt = code_breakpoints_; |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 OS::Print("Resolved BP %" Pd " to pos %" Pd ", line %" Pd ", " | 2355 OS::Print("Resolved BP %" Pd " to pos %" Pd ", line %" Pd ", " |
| 2367 "function '%s' (requested range %" Pd "-%" Pd ")\n", | 2356 "function '%s' (requested range %" Pd "-%" Pd ")\n", |
| 2368 bpt->id(), | 2357 bpt->id(), |
| 2369 bpt->token_pos(), | 2358 bpt->token_pos(), |
| 2370 bpt->LineNumber(), | 2359 bpt->LineNumber(), |
| 2371 func.ToFullyQualifiedCString(), | 2360 func.ToFullyQualifiedCString(), |
| 2372 requested_pos, | 2361 requested_pos, |
| 2373 requested_end_pos); | 2362 requested_end_pos); |
| 2374 } | 2363 } |
| 2375 SignalBpResolved(bpt); | 2364 SignalBpResolved(bpt); |
| 2365 SendServiceBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); |
| 2376 } | 2366 } |
| 2377 ASSERT(bpt->IsResolved()); | 2367 ASSERT(bpt->IsResolved()); |
| 2378 if (FLAG_verbose_debug) { | 2368 if (FLAG_verbose_debug) { |
| 2379 OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n", | 2369 OS::Print("Setting breakpoint %" Pd " at line %" Pd " for %s '%s'\n", |
| 2380 bpt->id(), | 2370 bpt->id(), |
| 2381 bpt->LineNumber(), | 2371 bpt->LineNumber(), |
| 2382 func.IsClosureFunction() ? "closure" : "function", | 2372 func.IsClosureFunction() ? "closure" : "function", |
| 2383 String::Handle(func.name()).ToCString()); | 2373 String::Handle(func.name()).ToCString()); |
| 2384 } | 2374 } |
| 2385 MakeCodeBreakpointAt(func, bpt); | 2375 MakeCodeBreakpointAt(func, bpt); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2523 void Debugger::RemoveBreakpoint(intptr_t bp_id) { | 2513 void Debugger::RemoveBreakpoint(intptr_t bp_id) { |
| 2524 SourceBreakpoint* prev_bpt = NULL; | 2514 SourceBreakpoint* prev_bpt = NULL; |
| 2525 SourceBreakpoint* curr_bpt = src_breakpoints_; | 2515 SourceBreakpoint* curr_bpt = src_breakpoints_; |
| 2526 while (curr_bpt != NULL) { | 2516 while (curr_bpt != NULL) { |
| 2527 if (curr_bpt->id() == bp_id) { | 2517 if (curr_bpt->id() == bp_id) { |
| 2528 if (prev_bpt == NULL) { | 2518 if (prev_bpt == NULL) { |
| 2529 src_breakpoints_ = src_breakpoints_->next(); | 2519 src_breakpoints_ = src_breakpoints_->next(); |
| 2530 } else { | 2520 } else { |
| 2531 prev_bpt->set_next(curr_bpt->next()); | 2521 prev_bpt->set_next(curr_bpt->next()); |
| 2532 } | 2522 } |
| 2523 SendServiceBreakpointEvent(ServiceEvent::kBreakpointRemoved, curr_bpt); |
| 2533 | 2524 |
| 2534 // Remove references from code breakpoints to this source breakpoint, | 2525 // Remove references from code breakpoints to this source breakpoint, |
| 2535 // and disable the code breakpoints. | 2526 // and disable the code breakpoints. |
| 2536 UnlinkCodeBreakpoints(curr_bpt); | 2527 UnlinkCodeBreakpoints(curr_bpt); |
| 2537 delete curr_bpt; | 2528 delete curr_bpt; |
| 2538 | 2529 |
| 2539 // Remove references from the current debugger pause event. | 2530 // Remove references from the current debugger pause event. |
| 2540 if (pause_event_ != NULL && | 2531 if (pause_event_ != NULL && |
| 2541 pause_event_->type() == DebuggerEvent::kBreakpointReached && | 2532 pause_event_->type() == DebuggerEvent::kBreakpointReached && |
| 2542 pause_event_->breakpoint() == curr_bpt) { | 2533 pause_event_->breakpoint() == curr_bpt) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2644 } | 2635 } |
| 2645 | 2636 |
| 2646 | 2637 |
| 2647 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2638 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2648 ASSERT(bpt->next() == NULL); | 2639 ASSERT(bpt->next() == NULL); |
| 2649 bpt->set_next(code_breakpoints_); | 2640 bpt->set_next(code_breakpoints_); |
| 2650 code_breakpoints_ = bpt; | 2641 code_breakpoints_ = bpt; |
| 2651 } | 2642 } |
| 2652 | 2643 |
| 2653 } // namespace dart | 2644 } // namespace dart |
| OLD | NEW |