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 @@ ...@@ -101,6 +101,7 @@
#include "src/profiler/heap-snapshot-generator-inl.h" #include "src/profiler/heap-snapshot-generator-inl.h"
#include "src/profiler/profile-generator-inl.h" #include "src/profiler/profile-generator-inl.h"
#include "src/profiler/tick-sample.h" #include "src/profiler/tick-sample.h"
#include "src/regexp/regexp-stack.h"
#include "src/regexp/regexp-utils.h" #include "src/regexp/regexp-utils.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
#include "src/snapshot/code-serializer.h" #include "src/snapshot/code-serializer.h"
...@@ -9765,10 +9766,13 @@ void debug::SetTerminateOnResume(Isolate* v8_isolate) { ...@@ -9765,10 +9766,13 @@ void debug::SetTerminateOnResume(Isolate* v8_isolate) {
isolate->debug()->SetTerminateOnResume(); isolate->debug()->SetTerminateOnResume();
} }
bool debug::AllFramesOnStackAreBlackboxed(Isolate* v8_isolate) { bool debug::CanBreakProgram(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_DO_NOT_USE(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 { v8::Isolate* debug::Script::GetIsolate() const {
......
...@@ -110,7 +110,7 @@ V8_EXPORT_PRIVATE void BreakRightNow(Isolate* isolate); ...@@ -110,7 +110,7 @@ V8_EXPORT_PRIVATE void BreakRightNow(Isolate* isolate);
// the isolate to be entered for further JavaScript execution. // the isolate to be entered for further JavaScript execution.
V8_EXPORT_PRIVATE void SetTerminateOnResume(Isolate* isolate); V8_EXPORT_PRIVATE void SetTerminateOnResume(Isolate* isolate);
bool AllFramesOnStackAreBlackboxed(Isolate* isolate); bool CanBreakProgram(Isolate* isolate);
class Script; class Script;
......
...@@ -189,7 +189,7 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) { ...@@ -189,7 +189,7 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) {
} }
bool V8Debugger::canBreakProgram() { bool V8Debugger::canBreakProgram() {
return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); return !v8::debug::CanBreakProgram(m_isolate);
} }
void V8Debugger::breakProgram(int targetContextGroupId) { 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 { ...@@ -100,6 +100,9 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
utils->Set(isolate, "sendMessageToBackend", utils->Set(isolate, "sendMessageToBackend",
v8::FunctionTemplate::New( v8::FunctionTemplate::New(
isolate, &UtilsExtension::SendMessageToBackend)); isolate, &UtilsExtension::SendMessageToBackend));
utils->Set(isolate, "interruptForMessages",
v8::FunctionTemplate::New(
isolate, &UtilsExtension::InterruptForMessages));
global->Set(isolate, "utils", utils); global->Set(isolate, "utils", utils);
} }
...@@ -388,6 +391,11 @@ class UtilsExtension : public IsolateData::SetupGlobalTask { ...@@ -388,6 +391,11 @@ class UtilsExtension : public IsolateData::SetupGlobalTask {
ToVector(args.GetIsolate(), args[1].As<v8::String>()))); 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_; static std::map<int, std::unique_ptr<FrontendChannelImpl>> channels_;
}; };
......
...@@ -95,6 +95,15 @@ void TaskRunner::RunMessageLoop(bool only_protocol) { ...@@ -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() { void TaskRunner::QuitMessageLoop() {
DCHECK_LT(0, nested_loop_count_); DCHECK_LT(0, nested_loop_count_);
--nested_loop_count_; --nested_loop_count_;
......
...@@ -52,7 +52,7 @@ class TaskRunner : public v8::base::Thread { ...@@ -52,7 +52,7 @@ class TaskRunner : public v8::base::Thread {
void QuitMessageLoop(); void QuitMessageLoop();
void Append(std::unique_ptr<Task>); void Append(std::unique_ptr<Task>);
void InterruptForMessages();
void Terminate(); void Terminate();
private: private:
...@@ -74,7 +74,6 @@ class TaskRunner : public v8::base::Thread { ...@@ -74,7 +74,6 @@ class TaskRunner : public v8::base::Thread {
v8::base::Semaphore process_queue_semaphore_; v8::base::Semaphore process_queue_semaphore_;
int nested_loop_count_; int nested_loop_count_;
std::atomic<int> is_terminated_; 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