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 |