Commit 835b71e8 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] improved V8Debugger::breakProgram method

We should be ready for gone agent.

BUG=chromium:714819
R=dgozman@chromium.org

Review-Url: https://codereview.chromium.org/2842903002
Cr-Commit-Position: refs/heads/master@{#44874}
parent 70e58e70
...@@ -1250,7 +1250,7 @@ void V8DebuggerAgentImpl::breakProgram( ...@@ -1250,7 +1250,7 @@ void V8DebuggerAgentImpl::breakProgram(
std::vector<BreakReason> currentScheduledReason; std::vector<BreakReason> currentScheduledReason;
currentScheduledReason.swap(m_breakReason); currentScheduledReason.swap(m_breakReason);
pushBreakDetails(breakReason, std::move(data)); pushBreakDetails(breakReason, std::move(data));
m_debugger->breakProgram(); if (!m_debugger->breakProgram(m_session->contextGroupId())) return;
popBreakDetails(); popBreakDetails();
m_breakReason.swap(currentScheduledReason); m_breakReason.swap(currentScheduledReason);
if (!m_breakReason.empty()) { if (!m_breakReason.empty()) {
......
...@@ -354,11 +354,14 @@ bool V8Debugger::canBreakProgram() { ...@@ -354,11 +354,14 @@ bool V8Debugger::canBreakProgram() {
return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate);
} }
void V8Debugger::breakProgram() { bool V8Debugger::breakProgram(int targetContextGroupId) {
// Don't allow nested breaks. // Don't allow nested breaks.
if (isPaused()) return; if (isPaused()) return true;
if (!canBreakProgram()) return; if (!canBreakProgram()) return true;
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
v8::debug::BreakRightNow(m_isolate); v8::debug::BreakRightNow(m_isolate);
return m_inspector->enabledDebuggerAgentForGroup(targetContextGroupId);
} }
void V8Debugger::continueProgram(int targetContextGroupId) { void V8Debugger::continueProgram(int targetContextGroupId) {
......
...@@ -50,7 +50,7 @@ class V8Debugger : public v8::debug::DebugDelegate { ...@@ -50,7 +50,7 @@ class V8Debugger : public v8::debug::DebugDelegate {
v8::debug::ExceptionBreakState getPauseOnExceptionsState(); v8::debug::ExceptionBreakState getPauseOnExceptionsState();
void setPauseOnExceptionsState(v8::debug::ExceptionBreakState); void setPauseOnExceptionsState(v8::debug::ExceptionBreakState);
bool canBreakProgram(); bool canBreakProgram();
void breakProgram(); bool breakProgram(int targetContextGroupId);
void continueProgram(int targetContextGroupId); void continueProgram(int targetContextGroupId);
void setPauseOnNextStatement(bool, int targetContextGroupId); void setPauseOnNextStatement(bool, int targetContextGroupId);
......
Check destroying agent inside of breakProgram
// 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('Check destroying agent inside of breakProgram');
(async function test(){
await Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: 'inspector.breakProgram(\'\', \'{}\')'});
await Protocol.Debugger.oncePaused();
utils.disconnect();
utils.quit();
})();
...@@ -129,18 +129,25 @@ class ConnectTask : public TaskRunner::Task { ...@@ -129,18 +129,25 @@ class ConnectTask : public TaskRunner::Task {
class DisconnectTask : public TaskRunner::Task { class DisconnectTask : public TaskRunner::Task {
public: public:
explicit DisconnectTask(InspectorClientImpl* client) : client_(client) {} explicit DisconnectTask(InspectorClientImpl* client, bool reset_inspector,
v8::base::Semaphore* ready_semaphore)
: client_(client),
reset_inspector_(reset_inspector),
ready_semaphore_(ready_semaphore) {}
virtual ~DisconnectTask() = default; virtual ~DisconnectTask() = default;
bool is_inspector_task() final { return true; } bool is_inspector_task() final { return true; }
void Run(v8::Isolate* isolate, void Run(v8::Isolate* isolate,
const v8::Global<v8::Context>& global_context) { const v8::Global<v8::Context>& global_context) {
client_->disconnect(); client_->disconnect(reset_inspector_);
if (ready_semaphore_) ready_semaphore_->Signal();
} }
private: private:
InspectorClientImpl* client_; InspectorClientImpl* client_;
bool reset_inspector_;
v8::base::Semaphore* ready_semaphore_;
}; };
class CreateContextGroupTask : public TaskRunner::Task { class CreateContextGroupTask : public TaskRunner::Task {
...@@ -217,16 +224,23 @@ void InspectorClientImpl::connect(v8::Local<v8::Context> context) { ...@@ -217,16 +224,23 @@ void InspectorClientImpl::connect(v8::Local<v8::Context> context) {
void InspectorClientImpl::scheduleReconnect( void InspectorClientImpl::scheduleReconnect(
v8::base::Semaphore* ready_semaphore) { v8::base::Semaphore* ready_semaphore) {
task_runner_->Append(new DisconnectTask(this)); task_runner_->Append(
new DisconnectTask(this, /* reset_inspector */ true, nullptr));
task_runner_->Append(new ConnectTask(this, ready_semaphore)); task_runner_->Append(new ConnectTask(this, ready_semaphore));
} }
void InspectorClientImpl::disconnect() { void InspectorClientImpl::scheduleDisconnect(
v8::base::Semaphore* ready_semaphore) {
task_runner_->Append(
new DisconnectTask(this, /* reset_inspector */ false, ready_semaphore));
}
void InspectorClientImpl::disconnect(bool reset_inspector) {
for (const auto& it : sessions_) { for (const auto& it : sessions_) {
states_[it.first] = it.second->stateJSON(); states_[it.first] = it.second->stateJSON();
} }
sessions_.clear(); sessions_.clear();
inspector_.reset(); if (reset_inspector) inspector_.reset();
} }
void InspectorClientImpl::scheduleCreateContextGroup( void InspectorClientImpl::scheduleCreateContextGroup(
...@@ -359,7 +373,7 @@ class SendMessageToBackendTask : public TaskRunner::Task { ...@@ -359,7 +373,7 @@ class SendMessageToBackendTask : public TaskRunner::Task {
->sessions_[context_group_id_] ->sessions_[context_group_id_]
.get(); .get();
} }
CHECK(session); if (!session) return;
} }
v8_inspector::StringView message_view(message_.start(), message_.length()); v8_inspector::StringView message_view(message_.start(), message_.length());
session->dispatchProtocolMessage(message_view); session->dispatchProtocolMessage(message_view);
......
...@@ -26,6 +26,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient { ...@@ -26,6 +26,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
virtual ~InspectorClientImpl(); virtual ~InspectorClientImpl();
void scheduleReconnect(v8::base::Semaphore* ready_semaphore); void scheduleReconnect(v8::base::Semaphore* ready_semaphore);
void scheduleDisconnect(v8::base::Semaphore* ready_semaphore);
void scheduleCreateContextGroup( void scheduleCreateContextGroup(
TaskRunner::SetupGlobalTasks setup_global_tasks, TaskRunner::SetupGlobalTasks setup_global_tasks,
v8::base::Semaphore* ready_semaphore, int* context_group_id); v8::base::Semaphore* ready_semaphore, int* context_group_id);
...@@ -63,7 +64,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient { ...@@ -63,7 +64,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
friend class ConnectTask; friend class ConnectTask;
void connect(v8::Local<v8::Context> context); void connect(v8::Local<v8::Context> context);
friend class DisconnectTask; friend class DisconnectTask;
void disconnect(); void disconnect(bool reset_inspector);
friend class CreateContextGroupTask; friend class CreateContextGroupTask;
int createContextGroup( int createContextGroup(
const TaskRunner::SetupGlobalTasks& setup_global_tasks); const TaskRunner::SetupGlobalTasks& setup_global_tasks);
......
...@@ -84,6 +84,8 @@ class UtilsExtension : public TaskRunner::SetupGlobalTask { ...@@ -84,6 +84,8 @@ class UtilsExtension : public TaskRunner::SetupGlobalTask {
isolate, &UtilsExtension::CancelPauseOnNextStatement)); isolate, &UtilsExtension::CancelPauseOnNextStatement));
utils->Set(ToV8String(isolate, "reconnect"), utils->Set(ToV8String(isolate, "reconnect"),
v8::FunctionTemplate::New(isolate, &UtilsExtension::Reconnect)); v8::FunctionTemplate::New(isolate, &UtilsExtension::Reconnect));
utils->Set(ToV8String(isolate, "disconnect"),
v8::FunctionTemplate::New(isolate, &UtilsExtension::Disconnect));
utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"), utils->Set(ToV8String(isolate, "setLogConsoleApiMessageCalls"),
v8::FunctionTemplate::New( v8::FunctionTemplate::New(
isolate, &UtilsExtension::SetLogConsoleApiMessageCalls)); isolate, &UtilsExtension::SetLogConsoleApiMessageCalls));
...@@ -264,6 +266,16 @@ class UtilsExtension : public TaskRunner::SetupGlobalTask { ...@@ -264,6 +266,16 @@ class UtilsExtension : public TaskRunner::SetupGlobalTask {
ready_semaphore.Wait(); ready_semaphore.Wait();
} }
static void Disconnect(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 0) {
fprintf(stderr, "Internal error: disconnect().");
Exit();
}
v8::base::Semaphore ready_semaphore(0);
inspector_client_->scheduleDisconnect(&ready_semaphore);
ready_semaphore.Wait();
}
static void SetLogConsoleApiMessageCalls( static void SetLogConsoleApiMessageCalls(
const v8::FunctionCallbackInfo<v8::Value>& args) { const v8::FunctionCallbackInfo<v8::Value>& args) {
if (args.Length() != 1 || !args[0]->IsBoolean()) { if (args.Length() != 1 || !args[0]->IsBoolean()) {
......
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