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

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

Issue 1344993002: Refactor isolate interrupts to use OOB messages instead of interrupt bits. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code review 2 Created 5 years, 3 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/isolate.h » ('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 24 matching lines...) Expand all
35 "Show invisible frames in debugger stack traces"); 35 "Show invisible frames in debugger stack traces");
36 DEFINE_FLAG(bool, trace_debugger_stacktrace, false, 36 DEFINE_FLAG(bool, trace_debugger_stacktrace, false,
37 "Trace debugger stacktrace collection"); 37 "Trace debugger stacktrace collection");
38 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); 38 DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages");
39 DEFINE_FLAG(bool, steal_breakpoints, false, 39 DEFINE_FLAG(bool, steal_breakpoints, false,
40 "Intercept breakpoints and other pause events before they " 40 "Intercept breakpoints and other pause events before they "
41 "are sent to the embedder and use a generic VM breakpoint " 41 "are sent to the embedder and use a generic VM breakpoint "
42 "handler instead. This handler dispatches breakpoints to " 42 "handler instead. This handler dispatches breakpoints to "
43 "the VM service."); 43 "the VM service.");
44 44
45 DECLARE_FLAG(bool, trace_isolates);
46
45 47
46 Debugger::EventHandler* Debugger::event_handler_ = NULL; 48 Debugger::EventHandler* Debugger::event_handler_ = NULL;
47 49
48 50
49 class RemoteObjectCache : public ZoneAllocated { 51 class RemoteObjectCache : public ZoneAllocated {
50 public: 52 public:
51 explicit RemoteObjectCache(intptr_t initial_size); 53 explicit RemoteObjectCache(intptr_t initial_size);
52 intptr_t AddObject(const Object& obj); 54 intptr_t AddObject(const Object& obj);
53 RawObject* GetObj(intptr_t obj_id) const; 55 RawObject* GetObj(intptr_t obj_id) const;
54 bool IsValidId(intptr_t obj_id) const { 56 bool IsValidId(intptr_t obj_id) const {
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 } 315 }
314 } 316 }
315 317
316 318
317 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) { 319 void Debugger::SignalIsolateEvent(DebuggerEvent::EventType type) {
318 if (HasEventHandler()) { 320 if (HasEventHandler()) {
319 DebuggerEvent event(isolate_, type); 321 DebuggerEvent event(isolate_, type);
320 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID); 322 ASSERT(event.isolate_id() != ILLEGAL_ISOLATE_ID);
321 if (type == DebuggerEvent::kIsolateInterrupted) { 323 if (type == DebuggerEvent::kIsolateInterrupted) {
322 DebuggerStackTrace* trace = CollectStackTrace(); 324 DebuggerStackTrace* trace = CollectStackTrace();
323 ASSERT(trace->Length() > 0); 325 if (trace->Length() > 0) {
324 event.set_top_frame(trace->FrameAt(0)); 326 event.set_top_frame(trace->FrameAt(0));
327 }
325 ASSERT(stack_trace_ == NULL); 328 ASSERT(stack_trace_ == NULL);
326 stack_trace_ = trace; 329 stack_trace_ = trace;
327 resume_action_ = kContinue; 330 resume_action_ = kContinue;
328 Pause(&event); 331 Pause(&event);
329 HandleSteppingRequest(trace); 332 HandleSteppingRequest(trace);
330 stack_trace_ = NULL; 333 stack_trace_ = NULL;
331 } else { 334 } else {
332 InvokeEventHandler(&event); 335 InvokeEventHandler(&event);
333 } 336 }
334 } 337 }
335 } 338 }
336 339
337 340
338 void Debugger::SignalIsolateInterrupted() { 341 RawError* Debugger::SignalIsolateInterrupted() {
339 if (HasEventHandler()) { 342 if (HasEventHandler()) {
340 Debugger* debugger = Isolate::Current()->debugger(); 343 SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
341 debugger->SignalIsolateEvent(DebuggerEvent::kIsolateInterrupted);
342 } 344 }
345 Dart_IsolateInterruptCallback callback = isolate_->InterruptCallback();
346 if (callback != NULL) {
347 if (!(*callback)()) {
348 if (FLAG_trace_isolates) {
349 OS::Print("[!] Embedder api: terminating isolate:\n"
350 "\tisolate: %s\n", isolate_->name());
351 }
352 const String& msg = String::Handle(String::New("isolate terminated"));
353 return UnwindError::New(msg);
354 }
355 }
356
357 // If any error occurred while in the debug message loop, return it here.
358 const Error& error =
359 Error::Handle(isolate_, isolate_->object_store()->sticky_error());
360 isolate_->object_store()->clear_sticky_error();
361 return error.raw();
343 } 362 }
344 363
345 364
346 // The vm service handles breakpoint notifications in a different way 365 // The vm service handles breakpoint notifications in a different way
347 // than the regular debugger breakpoint notifications. 366 // than the regular debugger breakpoint notifications.
348 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, 367 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind,
349 Breakpoint* bpt) { 368 Breakpoint* bpt) {
350 if (Service::debug_stream.enabled()) { 369 if (Service::debug_stream.enabled()) {
351 ServiceEvent service_event(Isolate::Current(), kind); 370 ServiceEvent service_event(Isolate::Current(), kind);
352 service_event.set_breakpoint(bpt); 371 service_event.set_breakpoint(bpt);
(...skipping 2193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 if ((iter.CurrentTokenKind() == Token::kIDENT) && 2565 if ((iter.CurrentTokenKind() == Token::kIDENT) &&
2547 ((iter.CurrentLiteral() == Symbols::Await().raw()) || 2566 ((iter.CurrentLiteral() == Symbols::Await().raw()) ||
2548 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) { 2567 (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) {
2549 event.set_at_async_jump(true); 2568 event.set_at_async_jump(true);
2550 } 2569 }
2551 } 2570 }
2552 Pause(&event); 2571 Pause(&event);
2553 } 2572 }
2554 2573
2555 2574
2556 void Debugger::DebuggerStepCallback() { 2575 RawError* Debugger::DebuggerStepCallback() {
2557 ASSERT(isolate_->single_step()); 2576 ASSERT(isolate_->single_step());
2558 // We can't get here unless the debugger event handler enabled 2577 // We can't get here unless the debugger event handler enabled
2559 // single stepping. 2578 // single stepping.
2560 ASSERT(HasEventHandler()); 2579 ASSERT(HasEventHandler());
2561 // Don't pause recursively. 2580 // Don't pause recursively.
2562 if (IsPaused()) return; 2581 if (IsPaused()) {
2582 return Error::null();
2583 }
2563 2584
2564 // Check whether we are in a Dart function that the user is 2585 // Check whether we are in a Dart function that the user is
2565 // interested in. If we saved the frame pointer of a stack frame 2586 // interested in. If we saved the frame pointer of a stack frame
2566 // the user is interested in, we ignore the single step if we are 2587 // the user is interested in, we ignore the single step if we are
2567 // in a callee of that frame. Note that we assume that the stack 2588 // in a callee of that frame. Note that we assume that the stack
2568 // grows towards lower addresses. 2589 // grows towards lower addresses.
2569 ActivationFrame* frame = TopDartFrame(); 2590 ActivationFrame* frame = TopDartFrame();
2570 ASSERT(frame != NULL); 2591 ASSERT(frame != NULL);
2571 2592
2572 if (stepping_fp_ != 0) { 2593 if (stepping_fp_ != 0) {
2573 // There is an "interesting frame" set. Only pause at appropriate 2594 // There is an "interesting frame" set. Only pause at appropriate
2574 // locations in this frame. 2595 // locations in this frame.
2575 if (stepping_fp_ > frame->fp()) { 2596 if (stepping_fp_ > frame->fp()) {
2576 // We are in a callee of the frame we're interested in. 2597 // We are in a callee of the frame we're interested in.
2577 // Ignore this stepping break. 2598 // Ignore this stepping break.
2578 return; 2599 return Error::null();
2579 } else if (frame->fp() > stepping_fp_) { 2600 } else if (frame->fp() > stepping_fp_) {
2580 // We returned from the "interesting frame", there can be no more 2601 // We returned from the "interesting frame", there can be no more
2581 // stepping breaks for it. Pause at the next appropriate location 2602 // stepping breaks for it. Pause at the next appropriate location
2582 // and let the user set the "interesting" frame again. 2603 // and let the user set the "interesting" frame again.
2583 stepping_fp_ = 0; 2604 stepping_fp_ = 0;
2584 } 2605 }
2585 } 2606 }
2586 2607
2587 if (!frame->IsDebuggable()) { 2608 if (!frame->IsDebuggable()) {
2588 return; 2609 return Error::null();
2589 } 2610 }
2590 if (frame->TokenPos() == Scanner::kNoSourcePos) { 2611 if (frame->TokenPos() == Scanner::kNoSourcePos) {
2591 return; 2612 return Error::null();
2592 } 2613 }
2593 2614
2594 // Don't pause for a single step if there is a breakpoint set 2615 // Don't pause for a single step if there is a breakpoint set
2595 // at this location. 2616 // at this location.
2596 if (HasActiveBreakpoint(frame->pc())) { 2617 if (HasActiveBreakpoint(frame->pc())) {
2597 return; 2618 return Error::null();
2598 } 2619 }
2599 2620
2600 if (FLAG_verbose_debug) { 2621 if (FLAG_verbose_debug) {
2601 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n", 2622 OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
2602 String::Handle(frame->SourceUrl()).ToCString(), 2623 String::Handle(frame->SourceUrl()).ToCString(),
2603 frame->LineNumber(), 2624 frame->LineNumber(),
2604 String::Handle(frame->QualifiedFunctionName()).ToCString(), 2625 String::Handle(frame->QualifiedFunctionName()).ToCString(),
2605 frame->TokenPos()); 2626 frame->TokenPos());
2606 } 2627 }
2607 2628
2608 ASSERT(stack_trace_ == NULL); 2629 ASSERT(stack_trace_ == NULL);
2609 stack_trace_ = CollectStackTrace(); 2630 stack_trace_ = CollectStackTrace();
2610 SignalPausedEvent(frame, NULL); 2631 SignalPausedEvent(frame, NULL);
2611 HandleSteppingRequest(stack_trace_); 2632 HandleSteppingRequest(stack_trace_);
2612 stack_trace_ = NULL; 2633 stack_trace_ = NULL;
2634
2635 // If any error occurred while in the debug message loop, return it here.
2636 const Error& error =
2637 Error::Handle(isolate_, isolate_->object_store()->sticky_error());
2638 isolate_->object_store()->clear_sticky_error();
2639 return error.raw();
2613 } 2640 }
2614 2641
2615 2642
2616 void Debugger::SignalBpReached() { 2643 RawError* Debugger::SignalBpReached() {
2617 // We ignore this breakpoint when the VM is executing code invoked 2644 // We ignore this breakpoint when the VM is executing code invoked
2618 // by the debugger to evaluate variables values, or when we see a nested 2645 // by the debugger to evaluate variables values, or when we see a nested
2619 // breakpoint or exception event. 2646 // breakpoint or exception event.
2620 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { 2647 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) {
2621 return; 2648 return Error::null();
2622 } 2649 }
2623 DebuggerStackTrace* stack_trace = CollectStackTrace(); 2650 DebuggerStackTrace* stack_trace = CollectStackTrace();
2624 ASSERT(stack_trace->Length() > 0); 2651 ASSERT(stack_trace->Length() > 0);
2625 ActivationFrame* top_frame = stack_trace->FrameAt(0); 2652 ActivationFrame* top_frame = stack_trace->FrameAt(0);
2626 ASSERT(top_frame != NULL); 2653 ASSERT(top_frame != NULL);
2627 CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc()); 2654 CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc());
2628 ASSERT(cbpt != NULL); 2655 ASSERT(cbpt != NULL);
2629 2656
2630 BreakpointLocation* bpt_location = cbpt->bpt_location_; 2657 BreakpointLocation* bpt_location = cbpt->bpt_location_;
2631 Breakpoint* bpt_hit = NULL; 2658 Breakpoint* bpt_hit = NULL;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 if (bpt->IsRepeated()) { 2692 if (bpt->IsRepeated()) {
2666 bpt_hit = bpt; 2693 bpt_hit = bpt;
2667 break; 2694 break;
2668 } 2695 }
2669 bpt = bpt->next(); 2696 bpt = bpt->next();
2670 } 2697 }
2671 } 2698 }
2672 } 2699 }
2673 2700
2674 if (bpt_hit == NULL) { 2701 if (bpt_hit == NULL) {
2675 return; 2702 return Error::null();
2676 } 2703 }
2677 2704
2678 if (FLAG_verbose_debug) { 2705 if (FLAG_verbose_debug) {
2679 OS::Print(">>> hit %s breakpoint at %s:%" Pd " " 2706 OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
2680 "(token %" Pd ") (address %#" Px ")\n", 2707 "(token %" Pd ") (address %#" Px ")\n",
2681 cbpt->IsInternal() ? "internal" : "user", 2708 cbpt->IsInternal() ? "internal" : "user",
2682 String::Handle(cbpt->SourceUrl()).ToCString(), 2709 String::Handle(cbpt->SourceUrl()).ToCString(),
2683 cbpt->LineNumber(), 2710 cbpt->LineNumber(),
2684 cbpt->token_pos(), 2711 cbpt->token_pos(),
2685 top_frame->pc()); 2712 top_frame->pc());
2686 } 2713 }
2687 2714
2688 ASSERT(stack_trace_ == NULL); 2715 ASSERT(stack_trace_ == NULL);
2689 stack_trace_ = stack_trace; 2716 stack_trace_ = stack_trace;
2690 SignalPausedEvent(top_frame, bpt_hit); 2717 SignalPausedEvent(top_frame, bpt_hit);
2691 HandleSteppingRequest(stack_trace_); 2718 HandleSteppingRequest(stack_trace_);
2692 stack_trace_ = NULL; 2719 stack_trace_ = NULL;
2693 if (cbpt->IsInternal()) { 2720 if (cbpt->IsInternal()) {
2694 RemoveInternalBreakpoints(); 2721 RemoveInternalBreakpoints();
2695 } 2722 }
2723
2724 // If any error occurred while in the debug message loop, return it here.
2725 const Error& error =
2726 Error::Handle(isolate_, isolate_->object_store()->sticky_error());
2727 isolate_->object_store()->clear_sticky_error();
2728 return error.raw();
2696 } 2729 }
2697 2730
2698 2731
2699 void Debugger::BreakHere(const String& msg) { 2732 void Debugger::BreakHere(const String& msg) {
2700 // We ignore this breakpoint when the VM is executing code invoked 2733 // We ignore this breakpoint when the VM is executing code invoked
2701 // by the debugger to evaluate variables values, or when we see a nested 2734 // by the debugger to evaluate variables values, or when we see a nested
2702 // breakpoint or exception event. 2735 // breakpoint or exception event.
2703 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { 2736 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) {
2704 return; 2737 return;
2705 } 2738 }
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
3175 } 3208 }
3176 3209
3177 3210
3178 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 3211 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
3179 ASSERT(bpt->next() == NULL); 3212 ASSERT(bpt->next() == NULL);
3180 bpt->set_next(code_breakpoints_); 3213 bpt->set_next(code_breakpoints_);
3181 code_breakpoints_ = bpt; 3214 code_breakpoints_ = bpt;
3182 } 3215 }
3183 3216
3184 } // namespace dart 3217 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698