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 <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 node = node->next()) { | 808 node = node->next()) { |
809 ClearBreakPoints(node->debug_info()); | 809 ClearBreakPoints(node->debug_info()); |
810 } | 810 } |
811 // Remove all debug info. | 811 // Remove all debug info. |
812 while (debug_info_list_ != NULL) { | 812 while (debug_info_list_ != NULL) { |
813 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); | 813 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); |
814 } | 814 } |
815 } | 815 } |
816 | 816 |
817 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { | 817 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { |
818 if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) return; | 818 if (IsBlackboxed(shared)) return; |
819 // Make sure the function is compiled and has set up the debug info. | 819 // Make sure the function is compiled and has set up the debug info. |
820 if (!EnsureDebugInfo(shared)) return; | 820 if (!EnsureDebugInfo(shared)) return; |
821 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 821 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
822 // Flood the function with break points. | 822 // Flood the function with break points. |
823 if (debug_info->HasDebugCode()) { | 823 if (debug_info->HasDebugCode()) { |
824 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) { | 824 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) { |
825 it.SetDebugBreak(); | 825 it.SetDebugBreak(); |
826 } | 826 } |
827 } | 827 } |
828 if (debug_info->HasDebugBytecodeArray()) { | 828 if (debug_info->HasDebugBytecodeArray()) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 | 953 |
954 if (found_handler) { | 954 if (found_handler) { |
955 // We found the handler. If we are stepping next or out, we need to | 955 // We found the handler. If we are stepping next or out, we need to |
956 // iterate until we found the suitable target frame to break in. | 956 // iterate until we found the suitable target frame to break in. |
957 if ((last_step_action() == StepNext || last_step_action() == StepOut) && | 957 if ((last_step_action() == StepNext || last_step_action() == StepOut) && |
958 current_frame_count > thread_local_.target_frame_count_) { | 958 current_frame_count > thread_local_.target_frame_count_) { |
959 continue; | 959 continue; |
960 } | 960 } |
961 Handle<SharedFunctionInfo> info( | 961 Handle<SharedFunctionInfo> info( |
962 summaries[i].AsJavaScript().function()->shared()); | 962 summaries[i].AsJavaScript().function()->shared()); |
963 if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; | 963 if (IsBlackboxed(info)) continue; |
964 FloodWithOneShot(info); | 964 FloodWithOneShot(info); |
965 return; | 965 return; |
966 } | 966 } |
967 } | 967 } |
968 } | 968 } |
969 } | 969 } |
970 | 970 |
971 | 971 |
972 void Debug::PrepareStep(StepAction step_action) { | 972 void Debug::PrepareStep(StepAction step_action) { |
973 HandleScope scope(isolate_); | 973 HandleScope scope(isolate_); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 HandleScope scope(isolate_); | 1048 HandleScope scope(isolate_); |
1049 List<Handle<SharedFunctionInfo>> infos; | 1049 List<Handle<SharedFunctionInfo>> infos; |
1050 frame->GetFunctions(&infos); | 1050 frame->GetFunctions(&infos); |
1051 for (; !infos.is_empty(); current_frame_count--) { | 1051 for (; !infos.is_empty(); current_frame_count--) { |
1052 Handle<SharedFunctionInfo> info = infos.RemoveLast(); | 1052 Handle<SharedFunctionInfo> info = infos.RemoveLast(); |
1053 if (in_current_frame) { | 1053 if (in_current_frame) { |
1054 // We want to skip out, so skip the current frame. | 1054 // We want to skip out, so skip the current frame. |
1055 in_current_frame = false; | 1055 in_current_frame = false; |
1056 continue; | 1056 continue; |
1057 } | 1057 } |
1058 if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; | 1058 if (IsBlackboxed(info)) continue; |
1059 FloodWithOneShot(info); | 1059 FloodWithOneShot(info); |
1060 thread_local_.target_frame_count_ = current_frame_count; | 1060 thread_local_.target_frame_count_ = current_frame_count; |
1061 return; | 1061 return; |
1062 } | 1062 } |
1063 } | 1063 } |
1064 break; | 1064 break; |
1065 } | 1065 } |
1066 case StepNext: | 1066 case StepNext: |
1067 thread_local_.target_frame_count_ = current_frame_count; | 1067 thread_local_.target_frame_count_ = current_frame_count; |
1068 // Fall through. | 1068 // Fall through. |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); | 1725 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
1726 // Isolate::context() may have been NULL when "script collected" event | 1726 // Isolate::context() may have been NULL when "script collected" event |
1727 // occured. | 1727 // occured. |
1728 if (context.is_null()) return v8::Local<v8::Context>(); | 1728 if (context.is_null()) return v8::Local<v8::Context>(); |
1729 Handle<Context> native_context(context->native_context()); | 1729 Handle<Context> native_context(context->native_context()); |
1730 return v8::Utils::ToLocal(native_context); | 1730 return v8::Utils::ToLocal(native_context); |
1731 } | 1731 } |
1732 } // anonymous namespace | 1732 } // anonymous namespace |
1733 | 1733 |
1734 bool Debug::IsExceptionBlackboxed(bool uncaught) { | 1734 bool Debug::IsExceptionBlackboxed(bool uncaught) { |
1735 JavaScriptFrameIterator it(isolate_); | |
1736 if (it.done()) return false; | |
1737 // Uncaught exception is blackboxed if all current frames are blackboxed, | 1735 // Uncaught exception is blackboxed if all current frames are blackboxed, |
1738 // caught exception if top frame is blackboxed. | 1736 // caught exception if top frame is blackboxed. |
1739 bool is_top_frame_blackboxed = IsFrameBlackboxed(it.frame()); | 1737 StackTraceFrameIterator it(isolate_); |
| 1738 while (!it.done() && it.is_wasm()) it.Advance(); |
| 1739 bool is_top_frame_blackboxed = |
| 1740 !it.done() ? IsFrameBlackboxed(it.javascript_frame()) : true; |
1740 if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed; | 1741 if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed; |
1741 return AllFramesOnStackAreBlackboxed(); | 1742 return AllFramesOnStackAreBlackboxed(); |
1742 } | 1743 } |
1743 | 1744 |
1744 bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { | 1745 bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { |
1745 HandleScope scope(isolate_); | 1746 HandleScope scope(isolate_); |
1746 if (!frame->HasInlinedFrames()) { | |
1747 Handle<SharedFunctionInfo> shared(frame->function()->shared(), isolate_); | |
1748 return IsBlackboxed(shared); | |
1749 } | |
1750 List<Handle<SharedFunctionInfo>> infos; | 1747 List<Handle<SharedFunctionInfo>> infos; |
1751 frame->GetFunctions(&infos); | 1748 frame->GetFunctions(&infos); |
1752 for (const auto& info : infos) | 1749 for (const auto& info : infos) { |
1753 if (!IsBlackboxed(info)) return false; | 1750 if (!IsBlackboxed(info)) return false; |
| 1751 } |
1754 return true; | 1752 return true; |
1755 } | 1753 } |
1756 | 1754 |
1757 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { | 1755 void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { |
1758 // We cannot generate debug events when JS execution is disallowed. | 1756 // We cannot generate debug events when JS execution is disallowed. |
1759 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant | 1757 // TODO(5530): Reenable debug events within DisallowJSScopes once relevant |
1760 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++. | 1758 // code (MakeExceptionEvent and ProcessDebugEvent) have been moved to C++. |
1761 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return; | 1759 if (!AllowJavascriptExecution::IsAllowed(isolate_)) return; |
1762 | 1760 |
1763 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher(); | 1761 Isolate::CatchType catch_type = isolate_->PredictExceptionCatcher(); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 | 1961 |
1964 namespace { | 1962 namespace { |
1965 debug::Location GetDebugLocation(Handle<Script> script, int source_position) { | 1963 debug::Location GetDebugLocation(Handle<Script> script, int source_position) { |
1966 Script::PositionInfo info; | 1964 Script::PositionInfo info; |
1967 Script::GetPositionInfo(script, source_position, &info, Script::WITH_OFFSET); | 1965 Script::GetPositionInfo(script, source_position, &info, Script::WITH_OFFSET); |
1968 return debug::Location(info.line, info.column); | 1966 return debug::Location(info.line, info.column); |
1969 } | 1967 } |
1970 } // namespace | 1968 } // namespace |
1971 | 1969 |
1972 bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { | 1970 bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { |
1973 if (!debug_delegate_) return false; | 1971 if (!debug_delegate_) return !shared->IsSubjectToDebugging(); |
1974 if (!shared->computed_debug_is_blackboxed()) { | 1972 if (!shared->computed_debug_is_blackboxed()) { |
1975 bool is_blackboxed = false; | 1973 bool is_blackboxed = |
1976 if (shared->script()->IsScript()) { | 1974 !shared->IsSubjectToDebugging() || !shared->script()->IsScript(); |
| 1975 if (!is_blackboxed) { |
1977 SuppressDebug while_processing(this); | 1976 SuppressDebug while_processing(this); |
1978 HandleScope handle_scope(isolate_); | 1977 HandleScope handle_scope(isolate_); |
1979 PostponeInterruptsScope no_interrupts(isolate_); | 1978 PostponeInterruptsScope no_interrupts(isolate_); |
1980 DisableBreak no_recursive_break(this); | 1979 DisableBreak no_recursive_break(this); |
| 1980 DCHECK(shared->script()->IsScript()); |
1981 Handle<Script> script(Script::cast(shared->script())); | 1981 Handle<Script> script(Script::cast(shared->script())); |
1982 if (script->type() == i::Script::TYPE_NORMAL) { | 1982 DCHECK(script->type() == i::Script::TYPE_NORMAL); |
1983 debug::Location start = | 1983 debug::Location start = |
1984 GetDebugLocation(script, shared->start_position()); | 1984 GetDebugLocation(script, shared->start_position()); |
1985 debug::Location end = GetDebugLocation(script, shared->end_position()); | 1985 debug::Location end = GetDebugLocation(script, shared->end_position()); |
1986 is_blackboxed = debug_delegate_->IsFunctionBlackboxed( | 1986 is_blackboxed = debug_delegate_->IsFunctionBlackboxed( |
1987 ToApiHandle<debug::Script>(script), start, end); | 1987 ToApiHandle<debug::Script>(script), start, end); |
1988 } | |
1989 } | 1988 } |
1990 shared->set_debug_is_blackboxed(is_blackboxed); | 1989 shared->set_debug_is_blackboxed(is_blackboxed); |
1991 shared->set_computed_debug_is_blackboxed(true); | 1990 shared->set_computed_debug_is_blackboxed(true); |
1992 } | 1991 } |
1993 return shared->debug_is_blackboxed(); | 1992 return shared->debug_is_blackboxed(); |
1994 } | 1993 } |
1995 | 1994 |
1996 bool Debug::AllFramesOnStackAreBlackboxed() { | 1995 bool Debug::AllFramesOnStackAreBlackboxed() { |
1997 HandleScope scope(isolate_); | 1996 HandleScope scope(isolate_); |
1998 for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) { | 1997 for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) { |
1999 if (!it.is_javascript()) continue; | |
2000 if (!IsFrameBlackboxed(it.javascript_frame())) return false; | 1998 if (!IsFrameBlackboxed(it.javascript_frame())) return false; |
2001 } | 1999 } |
2002 return true; | 2000 return true; |
2003 } | 2001 } |
2004 | 2002 |
2005 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, | 2003 void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, |
2006 int parent_id) { | 2004 int parent_id) { |
2007 if (in_debug_scope() || ignore_events()) return; | 2005 if (in_debug_scope() || ignore_events()) return; |
2008 if (!debug_delegate_) return; | 2006 if (!debug_delegate_) return; |
2009 SuppressDebug while_processing(this); | 2007 SuppressDebug while_processing(this); |
2010 DebugScope debug_scope(isolate_->debug()); | 2008 DebugScope debug_scope(isolate_->debug()); |
2011 if (debug_scope.failed()) return; | 2009 if (debug_scope.failed()) return; |
2012 HandleScope scope(isolate_); | 2010 HandleScope scope(isolate_); |
2013 PostponeInterruptsScope no_interrupts(isolate_); | 2011 PostponeInterruptsScope no_interrupts(isolate_); |
2014 DisableBreak no_recursive_break(this); | 2012 DisableBreak no_recursive_break(this); |
2015 bool created_by_user = false; | 2013 bool created_by_user = false; |
2016 if (type == debug::kDebugPromiseCreated) { | 2014 if (type == debug::kDebugPromiseCreated) { |
2017 JavaScriptFrameIterator it(isolate_); | 2015 JavaScriptFrameIterator it(isolate_); |
2018 // We need to skip top frame which contains instrumentation. | 2016 // We need to skip top frame which contains instrumentation. |
2019 it.Advance(); | 2017 it.Advance(); |
2020 created_by_user = | 2018 created_by_user = |
2021 !it.done() && | 2019 !it.done() && |
2022 it.frame()->function()->shared()->IsSubjectToDebugging() && | |
2023 !IsFrameBlackboxed(it.frame()); | 2020 !IsFrameBlackboxed(it.frame()); |
2024 } | 2021 } |
2025 debug_delegate_->PromiseEventOccurred( | 2022 debug_delegate_->PromiseEventOccurred( |
2026 Utils::ToLocal(debug_scope.GetContext()), type, id, parent_id, | 2023 Utils::ToLocal(debug_scope.GetContext()), type, id, parent_id, |
2027 created_by_user); | 2024 created_by_user); |
2028 } | 2025 } |
2029 | 2026 |
2030 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) { | 2027 void Debug::ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script) { |
2031 if (ignore_events()) return; | 2028 if (ignore_events()) return; |
2032 if (script->type() != i::Script::TYPE_NORMAL && | 2029 if (script->type() != i::Script::TYPE_NORMAL && |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2146 if (check.HasOverflowed()) return; | 2143 if (check.HasOverflowed()) return; |
2147 | 2144 |
2148 { JavaScriptFrameIterator it(isolate_); | 2145 { JavaScriptFrameIterator it(isolate_); |
2149 DCHECK(!it.done()); | 2146 DCHECK(!it.done()); |
2150 Object* fun = it.frame()->function(); | 2147 Object* fun = it.frame()->function(); |
2151 if (fun && fun->IsJSFunction()) { | 2148 if (fun && fun->IsJSFunction()) { |
2152 HandleScope scope(isolate_); | 2149 HandleScope scope(isolate_); |
2153 // Don't stop in builtin and blackboxed functions. | 2150 // Don't stop in builtin and blackboxed functions. |
2154 Handle<SharedFunctionInfo> shared(JSFunction::cast(fun)->shared(), | 2151 Handle<SharedFunctionInfo> shared(JSFunction::cast(fun)->shared(), |
2155 isolate_); | 2152 isolate_); |
2156 if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) { | 2153 if (IsBlackboxed(shared)) { |
2157 // Inspector uses pause on next statement for asynchronous breakpoints. | 2154 // Inspector uses pause on next statement for asynchronous breakpoints. |
2158 // When breakpoint is fired we try to break on first not blackboxed | 2155 // When breakpoint is fired we try to break on first not blackboxed |
2159 // statement. To achieve this goal we need to deoptimize current | 2156 // statement. To achieve this goal we need to deoptimize current |
2160 // function and don't clear requested DebugBreak even if it's blackboxed | 2157 // function and don't clear requested DebugBreak even if it's blackboxed |
2161 // to be able to break on not blackboxed function call. | 2158 // to be able to break on not blackboxed function call. |
2162 // TODO(yangguo): introduce break_on_function_entry since current | 2159 // TODO(yangguo): introduce break_on_function_entry since current |
2163 // implementation is slow. | 2160 // implementation is slow. |
2164 Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun)); | 2161 if (isolate_->stack_guard()->CheckDebugBreak()) { |
| 2162 Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun)); |
| 2163 } |
2165 return; | 2164 return; |
2166 } | 2165 } |
2167 JSGlobalObject* global = | 2166 JSGlobalObject* global = |
2168 JSFunction::cast(fun)->context()->global_object(); | 2167 JSFunction::cast(fun)->context()->global_object(); |
2169 // Don't stop in debugger functions. | 2168 // Don't stop in debugger functions. |
2170 if (IsDebugGlobal(global)) return; | 2169 if (IsDebugGlobal(global)) return; |
2171 // Don't stop if the break location is muted. | 2170 // Don't stop if the break location is muted. |
2172 if (IsMutedAtCurrentLocation(it.frame())) return; | 2171 if (IsMutedAtCurrentLocation(it.frame())) return; |
2173 } | 2172 } |
2174 } | 2173 } |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 isolate_->Throw(*isolate_->factory()->NewEvalError( | 2451 isolate_->Throw(*isolate_->factory()->NewEvalError( |
2453 MessageTemplate::kNoSideEffectDebugEvaluate)); | 2452 MessageTemplate::kNoSideEffectDebugEvaluate)); |
2454 } | 2453 } |
2455 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); | 2454 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); |
2456 isolate_->debug()->UpdateHookOnFunctionCall(); | 2455 isolate_->debug()->UpdateHookOnFunctionCall(); |
2457 isolate_->debug()->side_effect_check_failed_ = false; | 2456 isolate_->debug()->side_effect_check_failed_ = false; |
2458 } | 2457 } |
2459 | 2458 |
2460 } // namespace internal | 2459 } // namespace internal |
2461 } // namespace v8 | 2460 } // namespace v8 |
OLD | NEW |