| 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" |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 // We allow the embedder's default breakpoint handler to be overridden. | 319 // We allow the embedder's default breakpoint handler to be overridden. |
| 320 isolate_->PauseEventHandler(); | 320 isolate_->PauseEventHandler(); |
| 321 } else if (event_handler_ != NULL) { | 321 } else if (event_handler_ != NULL) { |
| 322 (*event_handler_)(event); | 322 (*event_handler_)(event); |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 | 325 |
| 326 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { | 326 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { |
| 327 // If we were paused, notify the service that we have resumed. | 327 // If we were paused, notify the service that we have resumed. |
| 328 const Error& error = | 328 const Error& error = |
| 329 Error::Handle(isolate_->object_store()->sticky_error()); | 329 Error::Handle(Thread::Current()->sticky_error()); |
| 330 ASSERT(error.IsNull() || error.IsUnwindError()); | 330 ASSERT(error.IsNull() || error.IsUnwindError()); |
| 331 | 331 |
| 332 // Only send a resume event when the isolate is not unwinding. | 332 // Only send a resume event when the isolate is not unwinding. |
| 333 if (!error.IsUnwindError()) { | 333 if (!error.IsUnwindError()) { |
| 334 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); | 334 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); |
| 335 service_event.set_top_frame(event->top_frame()); | 335 service_event.set_top_frame(event->top_frame()); |
| 336 Service::HandleEvent(&service_event); | 336 Service::HandleEvent(&service_event); |
| 337 } | 337 } |
| 338 } | 338 } |
| 339 } | 339 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 360 } | 360 } |
| 361 } | 361 } |
| 362 | 362 |
| 363 | 363 |
| 364 RawError* Debugger::SignalIsolateInterrupted() { | 364 RawError* Debugger::SignalIsolateInterrupted() { |
| 365 if (HasDebugEventHandler()) { | 365 if (HasDebugEventHandler()) { |
| 366 SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted); | 366 SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted); |
| 367 } | 367 } |
| 368 | 368 |
| 369 // If any error occurred while in the debug message loop, return it here. | 369 // If any error occurred while in the debug message loop, return it here. |
| 370 const Error& error = | 370 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 371 Error::Handle(isolate_->object_store()->sticky_error()); | |
| 372 ASSERT(error.IsNull() || error.IsUnwindError()); | 371 ASSERT(error.IsNull() || error.IsUnwindError()); |
| 373 isolate_->object_store()->clear_sticky_error(); | 372 Thread::Current()->clear_sticky_error(); |
| 374 return error.raw(); | 373 return error.raw(); |
| 375 } | 374 } |
| 376 | 375 |
| 377 | 376 |
| 378 // The vm service handles breakpoint notifications in a different way | 377 // The vm service handles breakpoint notifications in a different way |
| 379 // than the regular debugger breakpoint notifications. | 378 // than the regular debugger breakpoint notifications. |
| 380 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, | 379 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, |
| 381 Breakpoint* bpt) { | 380 Breakpoint* bpt) { |
| 382 if (Service::debug_stream.enabled()) { | 381 if (Service::debug_stream.enabled()) { |
| 383 ServiceEvent service_event(Isolate::Current(), kind); | 382 ServiceEvent service_event(Isolate::Current(), kind); |
| (...skipping 1740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 } | 2123 } |
| 2125 } | 2124 } |
| 2126 | 2125 |
| 2127 | 2126 |
| 2128 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) { | 2127 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) { |
| 2129 LongJumpScope jump; | 2128 LongJumpScope jump; |
| 2130 if (setjmp(*jump.Set()) == 0) { | 2129 if (setjmp(*jump.Set()) == 0) { |
| 2131 SetBreakpointAtEntry(target_function, true); | 2130 SetBreakpointAtEntry(target_function, true); |
| 2132 return Error::null(); | 2131 return Error::null(); |
| 2133 } else { | 2132 } else { |
| 2134 return isolate_->object_store()->sticky_error(); | 2133 return Thread::Current()->sticky_error(); |
| 2135 } | 2134 } |
| 2136 } | 2135 } |
| 2137 | 2136 |
| 2138 | 2137 |
| 2139 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function, | 2138 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function, |
| 2140 bool single_shot) { | 2139 bool single_shot) { |
| 2141 ASSERT(!target_function.IsNull()); | 2140 ASSERT(!target_function.IsNull()); |
| 2142 if (!target_function.is_debuggable()) { | 2141 if (!target_function.is_debuggable()) { |
| 2143 return NULL; | 2142 return NULL; |
| 2144 } | 2143 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 PassiveObject& result = PassiveObject::Handle(); | 2317 PassiveObject& result = PassiveObject::Handle(); |
| 2319 bool saved_ignore_flag = ignore_breakpoints_; | 2318 bool saved_ignore_flag = ignore_breakpoints_; |
| 2320 ignore_breakpoints_ = true; | 2319 ignore_breakpoints_ = true; |
| 2321 | 2320 |
| 2322 LongJumpScope jump; | 2321 LongJumpScope jump; |
| 2323 if (setjmp(*jump.Set()) == 0) { | 2322 if (setjmp(*jump.Set()) == 0) { |
| 2324 const Array& args = Array::Handle(Array::New(1)); | 2323 const Array& args = Array::Handle(Array::New(1)); |
| 2325 args.SetAt(0, object); | 2324 args.SetAt(0, object); |
| 2326 result = DartEntry::InvokeFunction(getter_func, args); | 2325 result = DartEntry::InvokeFunction(getter_func, args); |
| 2327 } else { | 2326 } else { |
| 2328 result = isolate_->object_store()->sticky_error(); | 2327 result = Thread::Current()->sticky_error(); |
| 2329 } | 2328 } |
| 2330 ignore_breakpoints_ = saved_ignore_flag; | 2329 ignore_breakpoints_ = saved_ignore_flag; |
| 2331 return result.raw(); | 2330 return result.raw(); |
| 2332 } | 2331 } |
| 2333 | 2332 |
| 2334 | 2333 |
| 2335 RawObject* Debugger::GetStaticField(const Class& cls, | 2334 RawObject* Debugger::GetStaticField(const Class& cls, |
| 2336 const String& field_name) { | 2335 const String& field_name) { |
| 2337 const Field& fld = Field::Handle(cls.LookupStaticField(field_name)); | 2336 const Field& fld = Field::Handle(cls.LookupStaticField(field_name)); |
| 2338 if (!fld.IsNull()) { | 2337 if (!fld.IsNull()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2352 return Object::null(); | 2351 return Object::null(); |
| 2353 } | 2352 } |
| 2354 | 2353 |
| 2355 PassiveObject& result = PassiveObject::Handle(); | 2354 PassiveObject& result = PassiveObject::Handle(); |
| 2356 bool saved_ignore_flag = ignore_breakpoints_; | 2355 bool saved_ignore_flag = ignore_breakpoints_; |
| 2357 ignore_breakpoints_ = true; | 2356 ignore_breakpoints_ = true; |
| 2358 LongJumpScope jump; | 2357 LongJumpScope jump; |
| 2359 if (setjmp(*jump.Set()) == 0) { | 2358 if (setjmp(*jump.Set()) == 0) { |
| 2360 result = DartEntry::InvokeFunction(getter_func, Object::empty_array()); | 2359 result = DartEntry::InvokeFunction(getter_func, Object::empty_array()); |
| 2361 } else { | 2360 } else { |
| 2362 result = isolate_->object_store()->sticky_error(); | 2361 result = Thread::Current()->sticky_error(); |
| 2363 } | 2362 } |
| 2364 ignore_breakpoints_ = saved_ignore_flag; | 2363 ignore_breakpoints_ = saved_ignore_flag; |
| 2365 return result.raw(); | 2364 return result.raw(); |
| 2366 } | 2365 } |
| 2367 | 2366 |
| 2368 | 2367 |
| 2369 RawArray* Debugger::GetInstanceFields(const Instance& obj) { | 2368 RawArray* Debugger::GetInstanceFields(const Instance& obj) { |
| 2370 Class& cls = Class::Handle(obj.clazz()); | 2369 Class& cls = Class::Handle(obj.clazz()); |
| 2371 Array& fields = Array::Handle(); | 2370 Array& fields = Array::Handle(); |
| 2372 Field& field = Field::Handle(); | 2371 Field& field = Field::Handle(); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2690 frame->TokenPos().ToCString()); | 2689 frame->TokenPos().ToCString()); |
| 2691 } | 2690 } |
| 2692 | 2691 |
| 2693 ASSERT(stack_trace_ == NULL); | 2692 ASSERT(stack_trace_ == NULL); |
| 2694 stack_trace_ = CollectStackTrace(); | 2693 stack_trace_ = CollectStackTrace(); |
| 2695 SignalPausedEvent(frame, NULL); | 2694 SignalPausedEvent(frame, NULL); |
| 2696 HandleSteppingRequest(stack_trace_); | 2695 HandleSteppingRequest(stack_trace_); |
| 2697 stack_trace_ = NULL; | 2696 stack_trace_ = NULL; |
| 2698 | 2697 |
| 2699 // If any error occurred while in the debug message loop, return it here. | 2698 // If any error occurred while in the debug message loop, return it here. |
| 2700 const Error& error = | 2699 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 2701 Error::Handle(isolate_->object_store()->sticky_error()); | 2700 Thread::Current()->clear_sticky_error(); |
| 2702 isolate_->object_store()->clear_sticky_error(); | |
| 2703 return error.raw(); | 2701 return error.raw(); |
| 2704 } | 2702 } |
| 2705 | 2703 |
| 2706 | 2704 |
| 2707 RawError* Debugger::SignalBpReached() { | 2705 RawError* Debugger::SignalBpReached() { |
| 2708 // We ignore this breakpoint when the VM is executing code invoked | 2706 // We ignore this breakpoint when the VM is executing code invoked |
| 2709 // by the debugger to evaluate variables values, or when we see a nested | 2707 // by the debugger to evaluate variables values, or when we see a nested |
| 2710 // breakpoint or exception event. | 2708 // breakpoint or exception event. |
| 2711 if (ignore_breakpoints_ || IsPaused()) { | 2709 if (ignore_breakpoints_ || IsPaused()) { |
| 2712 return Error::null(); | 2710 return Error::null(); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2781 SignalPausedEvent(top_frame, bpt_hit); | 2779 SignalPausedEvent(top_frame, bpt_hit); |
| 2782 // When we single step from a user breakpoint, our next stepping | 2780 // When we single step from a user breakpoint, our next stepping |
| 2783 // point will be at the exact same pc. Skip it. | 2781 // point will be at the exact same pc. Skip it. |
| 2784 HandleSteppingRequest(stack_trace_, true /* skip next step */); | 2782 HandleSteppingRequest(stack_trace_, true /* skip next step */); |
| 2785 stack_trace_ = NULL; | 2783 stack_trace_ = NULL; |
| 2786 if (cbpt->IsInternal()) { | 2784 if (cbpt->IsInternal()) { |
| 2787 RemoveInternalBreakpoints(); | 2785 RemoveInternalBreakpoints(); |
| 2788 } | 2786 } |
| 2789 | 2787 |
| 2790 // If any error occurred while in the debug message loop, return it here. | 2788 // If any error occurred while in the debug message loop, return it here. |
| 2791 const Error& error = | 2789 const Error& error = Error::Handle(Thread::Current()->sticky_error()); |
| 2792 Error::Handle(isolate_->object_store()->sticky_error()); | 2790 Thread::Current()->clear_sticky_error(); |
| 2793 isolate_->object_store()->clear_sticky_error(); | |
| 2794 return error.raw(); | 2791 return error.raw(); |
| 2795 } | 2792 } |
| 2796 | 2793 |
| 2797 | 2794 |
| 2798 void Debugger::BreakHere(const String& msg) { | 2795 void Debugger::BreakHere(const String& msg) { |
| 2799 // We ignore this breakpoint when the VM is executing code invoked | 2796 // We ignore this breakpoint when the VM is executing code invoked |
| 2800 // by the debugger to evaluate variables values, or when we see a nested | 2797 // by the debugger to evaluate variables values, or when we see a nested |
| 2801 // breakpoint or exception event. | 2798 // breakpoint or exception event. |
| 2802 if (ignore_breakpoints_ || IsPaused()) { | 2799 if (ignore_breakpoints_ || IsPaused()) { |
| 2803 return; | 2800 return; |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3277 | 3274 |
| 3278 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3275 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 3279 ASSERT(bpt->next() == NULL); | 3276 ASSERT(bpt->next() == NULL); |
| 3280 bpt->set_next(code_breakpoints_); | 3277 bpt->set_next(code_breakpoints_); |
| 3281 code_breakpoints_ = bpt; | 3278 code_breakpoints_ = bpt; |
| 3282 } | 3279 } |
| 3283 | 3280 |
| 3284 #endif // !PRODUCT | 3281 #endif // !PRODUCT |
| 3285 | 3282 |
| 3286 } // namespace dart | 3283 } // namespace dart |
| OLD | NEW |