| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 } | 760 } |
| 761 | 761 |
| 762 // Flood the function with break points. | 762 // Flood the function with break points. |
| 763 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 763 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 764 for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) { | 764 for (BreakLocation::Iterator it(debug_info, type); !it.Done(); it.Next()) { |
| 765 it.GetBreakLocation().SetOneShot(); | 765 it.GetBreakLocation().SetOneShot(); |
| 766 } | 766 } |
| 767 } | 767 } |
| 768 | 768 |
| 769 | 769 |
| 770 void Debug::FloodHandlerWithOneShot() { | |
| 771 // Iterate through the JavaScript stack looking for handlers. | |
| 772 DCHECK_NE(StackFrame::NO_ID, break_frame_id()); | |
| 773 for (JavaScriptFrameIterator it(isolate_, break_frame_id()); !it.done(); | |
| 774 it.Advance()) { | |
| 775 JavaScriptFrame* frame = it.frame(); | |
| 776 int stack_slots = 0; // The computed stack slot count is not used. | |
| 777 if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) { | |
| 778 // Flood the function with the catch/finally block with break points. | |
| 779 FloodWithOneShot(Handle<JSFunction>(frame->function())); | |
| 780 return; | |
| 781 } | |
| 782 } | |
| 783 } | |
| 784 | |
| 785 | |
| 786 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { | 770 void Debug::ChangeBreakOnException(ExceptionBreakType type, bool enable) { |
| 787 if (type == BreakUncaughtException) { | 771 if (type == BreakUncaughtException) { |
| 788 break_on_uncaught_exception_ = enable; | 772 break_on_uncaught_exception_ = enable; |
| 789 } else { | 773 } else { |
| 790 break_on_exception_ = enable; | 774 break_on_exception_ = enable; |
| 791 } | 775 } |
| 792 } | 776 } |
| 793 | 777 |
| 794 | 778 |
| 795 bool Debug::IsBreakOnException(ExceptionBreakType type) { | 779 bool Debug::IsBreakOnException(ExceptionBreakType type) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 813 if (!IsStepping()) return; | 797 if (!IsStepping()) return; |
| 814 if (last_step_action() < StepIn) return; | 798 if (last_step_action() < StepIn) return; |
| 815 if (in_debug_scope()) return; | 799 if (in_debug_scope()) return; |
| 816 if (thread_local_.step_in_enabled_) { | 800 if (thread_local_.step_in_enabled_) { |
| 817 ClearStepOut(); | 801 ClearStepOut(); |
| 818 FloodWithOneShot(function); | 802 FloodWithOneShot(function); |
| 819 } | 803 } |
| 820 } | 804 } |
| 821 | 805 |
| 822 | 806 |
| 807 void Debug::PrepareStepOnThrow() { |
| 808 if (!is_active()) return; |
| 809 if (!IsStepping()) return; |
| 810 if (last_step_action() == StepNone) return; |
| 811 if (in_debug_scope()) return; |
| 812 |
| 813 ClearOneShot(); |
| 814 |
| 815 // Iterate through the JavaScript stack looking for handlers. |
| 816 JavaScriptFrameIterator it(isolate_); |
| 817 while (!it.done()) { |
| 818 JavaScriptFrame* frame = it.frame(); |
| 819 int stack_slots = 0; // The computed stack slot count is not used. |
| 820 if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) break; |
| 821 it.Advance(); |
| 822 } |
| 823 |
| 824 // Find the closest Javascript frame we can flood with one-shots. |
| 825 while (!it.done() && |
| 826 !it.frame()->function()->shared()->IsSubjectToDebugging()) { |
| 827 it.Advance(); |
| 828 } |
| 829 |
| 830 if (it.done()) return; // No suitable Javascript catch handler. |
| 831 |
| 832 FloodWithOneShot(Handle<JSFunction>(it.frame()->function())); |
| 833 } |
| 834 |
| 835 |
| 823 void Debug::PrepareStep(StepAction step_action, | 836 void Debug::PrepareStep(StepAction step_action, |
| 824 int step_count, | 837 int step_count, |
| 825 StackFrame::Id frame_id) { | 838 StackFrame::Id frame_id) { |
| 826 HandleScope scope(isolate_); | 839 HandleScope scope(isolate_); |
| 827 | 840 |
| 828 DCHECK(in_debug_scope()); | 841 DCHECK(in_debug_scope()); |
| 829 | 842 |
| 830 // Get the frame where the execution has stopped and skip the debug frame if | 843 // Get the frame where the execution has stopped and skip the debug frame if |
| 831 // any. The debug frame will only be present if execution was stopped due to | 844 // any. The debug frame will only be present if execution was stopped due to |
| 832 // hitting a break point. In other situations (e.g. unhandled exception) the | 845 // hitting a break point. In other situations (e.g. unhandled exception) the |
| (...skipping 16 matching lines...) Expand all Loading... |
| 849 STATIC_ASSERT(StepFrame > StepIn); | 862 STATIC_ASSERT(StepFrame > StepIn); |
| 850 thread_local_.step_in_enabled_ = (step_action >= StepIn); | 863 thread_local_.step_in_enabled_ = (step_action >= StepIn); |
| 851 if (step_action == StepOut) { | 864 if (step_action == StepOut) { |
| 852 // For step out target frame will be found on the stack so there is no need | 865 // For step out target frame will be found on the stack so there is no need |
| 853 // to set step counter for it. It's expected to always be 0 for StepOut. | 866 // to set step counter for it. It's expected to always be 0 for StepOut. |
| 854 thread_local_.step_count_ = 0; | 867 thread_local_.step_count_ = 0; |
| 855 } else { | 868 } else { |
| 856 thread_local_.step_count_ = step_count; | 869 thread_local_.step_count_ = step_count; |
| 857 } | 870 } |
| 858 | 871 |
| 859 // First of all ensure there is one-shot break points in the top handler | |
| 860 // if any. | |
| 861 FloodHandlerWithOneShot(); | |
| 862 | |
| 863 // If the function on the top frame is unresolved perform step out. This will | 872 // If the function on the top frame is unresolved perform step out. This will |
| 864 // be the case when calling unknown function and having the debugger stopped | 873 // be the case when calling unknown function and having the debugger stopped |
| 865 // in an unhandled exception. | 874 // in an unhandled exception. |
| 866 if (!frame->function()->IsJSFunction()) { | 875 if (!frame->function()->IsJSFunction()) { |
| 867 // Step out: Find the calling JavaScript frame and flood it with | 876 // Step out: Find the calling JavaScript frame and flood it with |
| 868 // breakpoints. | 877 // breakpoints. |
| 869 frames_it.Advance(); | 878 frames_it.Advance(); |
| 870 // Fill the function to return to with one-shot break points. | 879 // Fill the function to return to with one-shot break points. |
| 871 JSFunction* function = frames_it.frame()->function(); | 880 JSFunction* function = frames_it.frame()->function(); |
| 872 FloodWithOneShot(Handle<JSFunction>(function)); | 881 FloodWithOneShot(Handle<JSFunction>(function)); |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1652 | 1661 |
| 1653 MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) { | 1662 MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) { |
| 1654 // Create the async task event object. | 1663 // Create the async task event object. |
| 1655 Handle<Object> argv[] = { task_event }; | 1664 Handle<Object> argv[] = { task_event }; |
| 1656 return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv); | 1665 return CallFunction("MakeAsyncTaskEvent", arraysize(argv), argv); |
| 1657 } | 1666 } |
| 1658 | 1667 |
| 1659 | 1668 |
| 1660 void Debug::OnThrow(Handle<Object> exception) { | 1669 void Debug::OnThrow(Handle<Object> exception) { |
| 1661 if (in_debug_scope() || ignore_events()) return; | 1670 if (in_debug_scope() || ignore_events()) return; |
| 1671 PrepareStepOnThrow(); |
| 1662 // Temporarily clear any scheduled_exception to allow evaluating | 1672 // Temporarily clear any scheduled_exception to allow evaluating |
| 1663 // JavaScript from the debug event handler. | 1673 // JavaScript from the debug event handler. |
| 1664 HandleScope scope(isolate_); | 1674 HandleScope scope(isolate_); |
| 1665 Handle<Object> scheduled_exception; | 1675 Handle<Object> scheduled_exception; |
| 1666 if (isolate_->has_scheduled_exception()) { | 1676 if (isolate_->has_scheduled_exception()) { |
| 1667 scheduled_exception = handle(isolate_->scheduled_exception(), isolate_); | 1677 scheduled_exception = handle(isolate_->scheduled_exception(), isolate_); |
| 1668 isolate_->clear_scheduled_exception(); | 1678 isolate_->clear_scheduled_exception(); |
| 1669 } | 1679 } |
| 1670 OnException(exception, isolate_->GetPromiseOnStackOnThrow()); | 1680 OnException(exception, isolate_->GetPromiseOnStackOnThrow()); |
| 1671 if (!scheduled_exception.is_null()) { | 1681 if (!scheduled_exception.is_null()) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 // Uncaught exceptions are reported by either flags. | 1723 // Uncaught exceptions are reported by either flags. |
| 1714 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; | 1724 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; |
| 1715 } else { | 1725 } else { |
| 1716 // Caught exceptions are reported is activated. | 1726 // Caught exceptions are reported is activated. |
| 1717 if (!break_on_exception_) return; | 1727 if (!break_on_exception_) return; |
| 1718 } | 1728 } |
| 1719 | 1729 |
| 1720 DebugScope debug_scope(this); | 1730 DebugScope debug_scope(this); |
| 1721 if (debug_scope.failed()) return; | 1731 if (debug_scope.failed()) return; |
| 1722 | 1732 |
| 1723 // Clear all current stepping setup. | |
| 1724 ClearStepping(); | |
| 1725 | |
| 1726 // Create the event data object. | 1733 // Create the event data object. |
| 1727 Handle<Object> event_data; | 1734 Handle<Object> event_data; |
| 1728 // Bail out and don't call debugger if exception. | 1735 // Bail out and don't call debugger if exception. |
| 1729 if (!MakeExceptionEvent( | 1736 if (!MakeExceptionEvent( |
| 1730 exception, uncaught, promise).ToHandle(&event_data)) { | 1737 exception, uncaught, promise).ToHandle(&event_data)) { |
| 1731 return; | 1738 return; |
| 1732 } | 1739 } |
| 1733 | 1740 |
| 1734 // Process debug event. | 1741 // Process debug event. |
| 1735 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); | 1742 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2506 } | 2513 } |
| 2507 | 2514 |
| 2508 | 2515 |
| 2509 void LockingCommandMessageQueue::Clear() { | 2516 void LockingCommandMessageQueue::Clear() { |
| 2510 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2517 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 2511 queue_.Clear(); | 2518 queue_.Clear(); |
| 2512 } | 2519 } |
| 2513 | 2520 |
| 2514 } // namespace internal | 2521 } // namespace internal |
| 2515 } // namespace v8 | 2522 } // namespace v8 |
| OLD | NEW |