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

Side by Side Diff: src/debug/debug.cc

Issue 1527593002: [debugger] flood function for stepping on throw. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: one more item for the black list Created 5 years 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 | « src/debug/debug.h ('k') | src/execution.cc » ('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 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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698