--- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h +++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h @@ -57,6 +57,7 @@ v8_inspector::V8InspectorSession* v8_session() { return v8_session_; } + void Dispose() override; void Restore() override; void DidCommitLoadForLocalFrame(LocalFrame*) override; @@ -115,6 +116,8 @@ std::unique_ptr) override; private: + void ReleaseObjectGroup(); + // This is null while inspecting workers. Member inspected_frames_; // This is null while inspecting frames. --- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc +++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc @@ -104,6 +104,8 @@ const char kIndexedDBObjectGroup[] = "indexeddb"; const char kNoDocumentError[] = "No document for given frame found"; +const char kSessionDetachedDuringOperation[] = + "DevTools session detached during operation."; const char kOriginMismatchError[] = "Requested security origin does not match the target's origin."; @@ -678,18 +680,29 @@ result_ = std::make_unique>(); } ~OpenCursorCallback() override = default; + + void SendFailure(protocol::Response response) { + if (!request_callback_) { + return; + } + auto request_callback = std::move(request_callback_); + request_callback->sendFailure(std::move(response)); + } void Invoke(ExecutionContext*, Event* event) override { + if (!request_callback_) { + return; + } + InspectorIndexedDBAgent* agent = agent_.Get(); if (!agent) { - request_callback_->sendFailure(protocol::Response::ServerError( - "DevTools session detached during operation.")); + SendFailure( + protocol::Response::ServerError(kSessionDetachedDuringOperation)); return; } if (event->type() != event_type_names::kSuccess) { - request_callback_->sendFailure( - protocol::Response::ServerError("Unexpected event type.")); + SendFailure(protocol::Response::ServerError("Unexpected event type.")); return; } @@ -700,8 +713,7 @@ return; } if (request_result->GetType() != IDBAny::kIDBCursorWithValueType) { - request_callback_->sendFailure( - protocol::Response::ServerError("Unexpected result type.")); + SendFailure(protocol::Response::ServerError("Unexpected result type.")); return; } @@ -711,8 +723,7 @@ DummyExceptionStateForTesting exception_state; idb_cursor->advance(skip_count_, exception_state); if (exception_state.HadException()) { - request_callback_->sendFailure( - protocol::Response::ServerError("Could not advance cursor.")); + SendFailure(protocol::Response::ServerError("Could not advance cursor.")); } skip_count_ = 0; return; @@ -729,8 +740,7 @@ idb_cursor->Continue(nullptr, nullptr, IDBRequest::AsyncTraceState(), exception_state); if (exception_state.HadException()) { - request_callback_->sendFailure( - protocol::Response::ServerError("Could not continue cursor.")); + SendFailure(protocol::Response::ServerError("Could not continue cursor.")); return; } @@ -739,6 +749,11 @@ } v8_inspector::V8InspectorSession* v8_session = agent->v8_session(); + if (!v8_session) { + SendFailure( + protocol::Response::ServerError(kSessionDetachedDuringOperation)); + return; + } ScriptState::Scope scope(script_state_); v8::Local context = script_state_->GetContext(); v8_inspector::StringView object_group = @@ -759,7 +774,11 @@ } void end(bool has_more) { - request_callback_->sendSuccess(std::move(result_), has_more); + if (!request_callback_) { + return; + } + auto request_callback = std::move(request_callback_); + request_callback->sendSuccess(std::move(result_), has_more); } void Trace(Visitor* visitor) const override { @@ -796,10 +815,9 @@ void Execute(IDBDatabase* idb_database, ScriptState* script_state) override { InspectorIndexedDBAgent* agent = agent_.Get(); - if (!agent) { - request_callback_->sendFailure(protocol::Response::ServerError( - "The DevTools session was detached before the operation could " - "complete.")); + if (!agent || !agent->v8_session()) { + request_callback_->sendFailure( + protocol::Response::ServerError(kSessionDetachedDuringOperation)); return; } @@ -883,6 +901,22 @@ InspectorIndexedDBAgent::~InspectorIndexedDBAgent() = default; +void InspectorIndexedDBAgent::Dispose() { + ReleaseObjectGroup(); + // Make any outstanding asynchronous IndexedDB callbacks fail closed before + // DevToolsSession tears down the underlying V8InspectorSession. + v8_session_ = nullptr; + InspectorBaseAgent::Dispose(); +} + +void InspectorIndexedDBAgent::ReleaseObjectGroup() { + if (!v8_session_) { + return; + } + v8_session_->releaseObjectGroup( + ToV8InspectorStringView(kIndexedDBObjectGroup)); +} + void InspectorIndexedDBAgent::Restore() { if (enabled_.Get()) { enable(); @@ -891,8 +925,7 @@ void InspectorIndexedDBAgent::DidCommitLoadForLocalFrame(LocalFrame* frame) { if (frame == inspected_frames_->Root()) { - v8_session_->releaseObjectGroup( - ToV8InspectorStringView(kIndexedDBObjectGroup)); + ReleaseObjectGroup(); } } @@ -903,8 +936,7 @@ protocol::Response InspectorIndexedDBAgent::disable() { enabled_.Clear(); - v8_session_->releaseObjectGroup( - ToV8InspectorStringView(kIndexedDBObjectGroup)); + ReleaseObjectGroup(); return protocol::Response::Success(); }