Commit 32c29e8f authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

[inspector] do not interrupt with pause when running regexp

If we attempt to pause, we'd check whether frames are framework code
which we pattern match with a regexp. That could cause re-entering
regexp, which is not allowed.

Fixed: chromium:1125934
Change-Id: I3b52b202a5570f7929def39176cfe5e52be3dfd5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2602948
Commit-Queue: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71876}
parent f4d408fd
......@@ -101,6 +101,7 @@
#include "src/profiler/heap-snapshot-generator-inl.h"
#include "src/profiler/profile-generator-inl.h"
#include "src/profiler/tick-sample.h"
#include "src/regexp/regexp-stack.h"
#include "src/regexp/regexp-utils.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/code-serializer.h"
......@@ -9765,10 +9766,13 @@ void debug::SetTerminateOnResume(Isolate* v8_isolate) {
isolate->debug()->SetTerminateOnResume();
}
bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) {
bool debug::CanBreakProgram(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_DO_NOT_USE(isolate);
return isolate->debug()->AllFramesOnStackAreBlackboxed();
// We cannot break a program if we are currently running a regexp.
// TODO(yangguo): fix this exception.
return !isolate->regexp_stack()->is_in_use() &&
isolate->debug()->AllFramesOnStackAreBlackboxed();
}
v8::Isolate* debug::Script::GetIsolate() const {
......
......@@ -110,7 +110,7 @@ V8_EXPORT_PRIVATE void BreakRightNow(Isolate* isolate);
// the isolate to be entered for further JavaScript execution.
V8_EXPORT_PRIVATE void SetTerminateOnResume(Isolate* isolate);
bool AllFramesOnStackAreBlackboxed(Isolate* isolate);
bool CanBreakProgram(Isolate* isolate);
class Script;
......
......@@ -189,7 +189,7 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) {
}
bool V8Debugger::canBreakProgram() {
return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate);
return !v8::debug::CanBreakProgram(m_isolate);
}
void V8Debugger::breakProgram(int targetContextGroupId) {
......
Checks pause inside blackboxed optimized function call.
// Copyright 2020 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.
// Flags: --allow-natives-syntax
// Flags: --no-enable-experimental-regexp-engine
// Flags: --no-enable-experimental-regexp-engine-on-excessive-backtracks
// Flags: --no-regexp-tier-up
let {session, contextGroup, Protocol} = InspectorTest.start(
'Checks pause inside blackboxed optimized function call.');
session.setupScriptMap();
(async function test(){
Protocol.Debugger.enable();
// Use an non-atomic regexp to trigger the actual regexp engine.
Protocol.Debugger.setBlackboxPatterns({patterns: ['.*\.js']});
// Run a script dominated by a regexp, with a sourceURL to pattern-match.
Protocol.Runtime.evaluate({expression: `
/((a*)*)*b/.exec('aaaaaaaaaaaaaa');
//# sourceURL=framework.js`});
// Issue lots of pause messages to trigger at least one during regexp.
for (let i = 0; i < 100; i++) Protocol.Debugger.pause();
// Send the messages through interupt while regexp is running.
utils.interruptForMessages();
InspectorTest.completeTest();
})();
......@@ -100,6 +100,9 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
utils->Set(isolate, "sendMessageToBackend",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::SendMessageToBackend));
utils->Set(isolate, "interruptForMessages",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::InterruptForMessages));
global->Set(isolate, "utils", utils);
}
......@@ -388,6 +391,11 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
ToVector(args.GetIsolate(), args[1].As<v8::String>())));
}
static void InterruptForMessages(
const v8::FunctionCallbackInfo<v8::Value>& args) {
backend_runner_->InterruptForMessages();
}
static std::map<int, std::unique_ptr<FrontendChannelImpl>> channels_;
};
......
......@@ -95,6 +95,15 @@ void TaskRunner::RunMessageLoop(bool only_protocol) {
}
}
static void RunMessageLoopInInterrupt(v8::Isolate* isolate, void* task_runner) {
TaskRunner* runner = reinterpret_cast<TaskRunner*>(task_runner);
runner->RunMessageLoop(true);
}
void TaskRunner::InterruptForMessages() {
isolate()->RequestInterrupt(&RunMessageLoopInInterrupt, this);
}
void TaskRunner::QuitMessageLoop() {
DCHECK_LT(0, nested_loop_count_);
--nested_loop_count_;
......
......@@ -52,7 +52,7 @@ class TaskRunner : public v8::base::Thread {
void QuitMessageLoop();
void Append(std::unique_ptr<Task>);
void InterruptForMessages();
void Terminate();
private:
......@@ -74,7 +74,6 @@ class TaskRunner : public v8::base::Thread {
v8::base::Semaphore process_queue_semaphore_;
int nested_loop_count_;
std::atomic<int> is_terminated_;
};
......
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