Commit fb147b0e authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] merged IsSubjectToDebugging and IsBlackboxed and fixed issue

- additionally doesn't deoptimize function in HandleDebugBreak for debugger statements inside of blackboxed code.

BUG=none
R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2742843003
Cr-Commit-Position: refs/heads/master@{#43724}
parent 6b15cdb2
...@@ -815,7 +815,7 @@ void Debug::ClearAllBreakPoints() { ...@@ -815,7 +815,7 @@ void Debug::ClearAllBreakPoints() {
} }
void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) return; if (IsBlackboxed(shared)) return;
// Make sure the function is compiled and has set up the debug info. // Make sure the function is compiled and has set up the debug info.
if (!EnsureDebugInfo(shared)) return; if (!EnsureDebugInfo(shared)) return;
Handle<DebugInfo> debug_info(shared->GetDebugInfo()); Handle<DebugInfo> debug_info(shared->GetDebugInfo());
...@@ -960,7 +960,7 @@ void Debug::PrepareStepOnThrow() { ...@@ -960,7 +960,7 @@ void Debug::PrepareStepOnThrow() {
} }
Handle<SharedFunctionInfo> info( Handle<SharedFunctionInfo> info(
summaries[i].AsJavaScript().function()->shared()); summaries[i].AsJavaScript().function()->shared());
if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; if (IsBlackboxed(info)) continue;
FloodWithOneShot(info); FloodWithOneShot(info);
return; return;
} }
...@@ -1055,7 +1055,7 @@ void Debug::PrepareStep(StepAction step_action) { ...@@ -1055,7 +1055,7 @@ void Debug::PrepareStep(StepAction step_action) {
in_current_frame = false; in_current_frame = false;
continue; continue;
} }
if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; if (IsBlackboxed(info)) continue;
FloodWithOneShot(info); FloodWithOneShot(info);
thread_local_.target_frame_count_ = current_frame_count; thread_local_.target_frame_count_ = current_frame_count;
return; return;
...@@ -1732,25 +1732,23 @@ v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { ...@@ -1732,25 +1732,23 @@ v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) {
} // anonymous namespace } // anonymous namespace
bool Debug::IsExceptionBlackboxed(bool uncaught) { bool Debug::IsExceptionBlackboxed(bool uncaught) {
JavaScriptFrameIterator it(isolate_);
if (it.done()) return false;
// Uncaught exception is blackboxed if all current frames are blackboxed, // Uncaught exception is blackboxed if all current frames are blackboxed,
// caught exception if top frame is blackboxed. // caught exception if top frame is blackboxed.
bool is_top_frame_blackboxed = IsFrameBlackboxed(it.frame()); StackTraceFrameIterator it(isolate_);
while (!it.done() && it.is_wasm()) it.Advance();
bool is_top_frame_blackboxed =
!it.done() ? IsFrameBlackboxed(it.javascript_frame()) : true;
if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed; if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed;
return AllFramesOnStackAreBlackboxed(); return AllFramesOnStackAreBlackboxed();
} }
bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
if (!frame->HasInlinedFrames()) {
Handle<SharedFunctionInfo> shared(frame->function()->shared(), isolate_);
return IsBlackboxed(shared);
}
List<Handle<SharedFunctionInfo>> infos; List<Handle<SharedFunctionInfo>> infos;
frame->GetFunctions(&infos); frame->GetFunctions(&infos);
for (const auto& info : infos) for (const auto& info : infos) {
if (!IsBlackboxed(info)) return false; if (!IsBlackboxed(info)) return false;
}
return true; return true;
} }
...@@ -1970,22 +1968,23 @@ debug::Location GetDebugLocation(Handle<Script> script, int source_position) { ...@@ -1970,22 +1968,23 @@ debug::Location GetDebugLocation(Handle<Script> script, int source_position) {
} // namespace } // namespace
bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) {
if (!debug_delegate_) return false; if (!debug_delegate_) return !shared->IsSubjectToDebugging();
if (!shared->computed_debug_is_blackboxed()) { if (!shared->computed_debug_is_blackboxed()) {
bool is_blackboxed = false; bool is_blackboxed =
if (shared->script()->IsScript()) { !shared->IsSubjectToDebugging() || !shared->script()->IsScript();
if (!is_blackboxed) {
SuppressDebug while_processing(this); SuppressDebug while_processing(this);
HandleScope handle_scope(isolate_); HandleScope handle_scope(isolate_);
PostponeInterruptsScope no_interrupts(isolate_); PostponeInterruptsScope no_interrupts(isolate_);
DisableBreak no_recursive_break(this); DisableBreak no_recursive_break(this);
DCHECK(shared->script()->IsScript());
Handle<Script> script(Script::cast(shared->script())); Handle<Script> script(Script::cast(shared->script()));
if (script->type() == i::Script::TYPE_NORMAL) { DCHECK(script->type() == i::Script::TYPE_NORMAL);
debug::Location start = debug::Location start =
GetDebugLocation(script, shared->start_position()); GetDebugLocation(script, shared->start_position());
debug::Location end = GetDebugLocation(script, shared->end_position()); debug::Location end = GetDebugLocation(script, shared->end_position());
is_blackboxed = debug_delegate_->IsFunctionBlackboxed( is_blackboxed = debug_delegate_->IsFunctionBlackboxed(
ToApiHandle<debug::Script>(script), start, end); ToApiHandle<debug::Script>(script), start, end);
}
} }
shared->set_debug_is_blackboxed(is_blackboxed); shared->set_debug_is_blackboxed(is_blackboxed);
shared->set_computed_debug_is_blackboxed(true); shared->set_computed_debug_is_blackboxed(true);
...@@ -1996,7 +1995,6 @@ bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) { ...@@ -1996,7 +1995,6 @@ bool Debug::IsBlackboxed(Handle<SharedFunctionInfo> shared) {
bool Debug::AllFramesOnStackAreBlackboxed() { bool Debug::AllFramesOnStackAreBlackboxed() {
HandleScope scope(isolate_); HandleScope scope(isolate_);
for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) { for (StackTraceFrameIterator it(isolate_); !it.done(); it.Advance()) {
if (!it.is_javascript()) continue;
if (!IsFrameBlackboxed(it.javascript_frame())) return false; if (!IsFrameBlackboxed(it.javascript_frame())) return false;
} }
return true; return true;
...@@ -2019,7 +2017,6 @@ void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, ...@@ -2019,7 +2017,6 @@ void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id,
it.Advance(); it.Advance();
created_by_user = created_by_user =
!it.done() && !it.done() &&
it.frame()->function()->shared()->IsSubjectToDebugging() &&
!IsFrameBlackboxed(it.frame()); !IsFrameBlackboxed(it.frame());
} }
debug_delegate_->PromiseEventOccurred( debug_delegate_->PromiseEventOccurred(
...@@ -2153,7 +2150,7 @@ void Debug::HandleDebugBreak() { ...@@ -2153,7 +2150,7 @@ void Debug::HandleDebugBreak() {
// Don't stop in builtin and blackboxed functions. // Don't stop in builtin and blackboxed functions.
Handle<SharedFunctionInfo> shared(JSFunction::cast(fun)->shared(), Handle<SharedFunctionInfo> shared(JSFunction::cast(fun)->shared(),
isolate_); isolate_);
if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) { if (IsBlackboxed(shared)) {
// Inspector uses pause on next statement for asynchronous breakpoints. // Inspector uses pause on next statement for asynchronous breakpoints.
// When breakpoint is fired we try to break on first not blackboxed // When breakpoint is fired we try to break on first not blackboxed
// statement. To achieve this goal we need to deoptimize current // statement. To achieve this goal we need to deoptimize current
...@@ -2161,7 +2158,9 @@ void Debug::HandleDebugBreak() { ...@@ -2161,7 +2158,9 @@ void Debug::HandleDebugBreak() {
// to be able to break on not blackboxed function call. // to be able to break on not blackboxed function call.
// TODO(yangguo): introduce break_on_function_entry since current // TODO(yangguo): introduce break_on_function_entry since current
// implementation is slow. // implementation is slow.
Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun)); if (isolate_->stack_guard()->CheckDebugBreak()) {
Deoptimizer::DeoptimizeFunction(JSFunction::cast(fun));
}
return; return;
} }
JSGlobalObject* global = JSGlobalObject* global =
......
Async caught exception prediction and blackboxing.
paused at:
#debugger;
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
InspectorTest.log('Async caught exception prediction and blackboxing.');
InspectorTest.addScript(`
function constructorThrow() {
return new Promise((resolve, reject) =>
Promise.resolve().then(() =>
reject("f") // Exception f
)
);
}
function dotCatch(producer) {
Promise.resolve(producer()).catch(() => {});
}
//# sourceURL=framework.js`);
InspectorTest.setupScriptMap();
(async function test() {
Protocol.Debugger.enable();
Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']});
Protocol.Debugger.setPauseOnExceptions({state: 'all'});
Protocol.Runtime.evaluate({expression: 'dotCatch(constructorThrow);'});
// Should break at this debugger statement, not at reject.
Protocol.Runtime.evaluate({expression: 'setTimeout(\'debugger;\', 0);'});
await waitPauseAndDumpLocation();
InspectorTest.completeTest();
})();
async function waitPauseAndDumpLocation() {
var message = await Protocol.Debugger.oncePaused();
InspectorTest.log('paused at:');
InspectorTest.logSourceLocation(message.params.callFrames[0].location);
return message;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment