Title: [227674] trunk/Source/WebDriver
Revision
227674
Author
[email protected]
Date
2018-01-26 05:20:11 -0800 (Fri, 26 Jan 2018)

Log Message

WebDriver: service hangs after a browser crash
https://bugs.webkit.org/show_bug.cgi?id=182170

Reviewed by Carlos Alberto Lopez Perez.

This is currently happening in the GTK+ debug bot. There's a test that makes the browser crash due to an assert,
hanging the whole process and preventing the rest of the tests from running. When the browser crashes, we
correctly handle the pending requests, by completing them with an error. However, if the client tries to send
another command we fail to send the message to the browser and the reply is never sent to the client. In the
case of the tests, delete session command is sent, but never gets a reply.

* Session.cpp:
(WebDriver::Session::isConnected const): Return whether the session is connected to the browser.
* Session.h:
* SessionHost.cpp:
(WebDriver::SessionHost::sendCommandToBackend): Pass the message ID to SessionHost::sendMessageToBackend().
* SessionHost.h:
* WebDriverService.cpp:
(WebDriver::WebDriverService::deleteSession): Ignore unknown errors if the session is no longer connected.
* glib/SessionHostGlib.cpp:
(WebDriver::SessionHost::sendMessageToBackend): Handle errors when sending the command by completing the request
with an error.

Modified Paths

Diff

Modified: trunk/Source/WebDriver/ChangeLog (227673 => 227674)


--- trunk/Source/WebDriver/ChangeLog	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/ChangeLog	2018-01-26 13:20:11 UTC (rev 227674)
@@ -1,5 +1,30 @@
 2018-01-26  Carlos Garcia Campos  <[email protected]>
 
+        WebDriver: service hangs after a browser crash
+        https://bugs.webkit.org/show_bug.cgi?id=182170
+
+        Reviewed by Carlos Alberto Lopez Perez.
+
+        This is currently happening in the GTK+ debug bot. There's a test that makes the browser crash due to an assert,
+        hanging the whole process and preventing the rest of the tests from running. When the browser crashes, we
+        correctly handle the pending requests, by completing them with an error. However, if the client tries to send
+        another command we fail to send the message to the browser and the reply is never sent to the client. In the
+        case of the tests, delete session command is sent, but never gets a reply.
+
+        * Session.cpp:
+        (WebDriver::Session::isConnected const): Return whether the session is connected to the browser.
+        * Session.h:
+        * SessionHost.cpp:
+        (WebDriver::SessionHost::sendCommandToBackend): Pass the message ID to SessionHost::sendMessageToBackend().
+        * SessionHost.h:
+        * WebDriverService.cpp:
+        (WebDriver::WebDriverService::deleteSession): Ignore unknown errors if the session is no longer connected.
+        * glib/SessionHostGlib.cpp:
+        (WebDriver::SessionHost::sendMessageToBackend): Handle errors when sending the command by completing the request
+        with an error.
+
+2018-01-26  Carlos Garcia Campos  <[email protected]>
+
         WebDriver: timeouts value and cookie expiry should be limited to max safe integer
         https://bugs.webkit.org/show_bug.cgi?id=182167
 

Modified: trunk/Source/WebDriver/Session.cpp (227673 => 227674)


--- trunk/Source/WebDriver/Session.cpp	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/Session.cpp	2018-01-26 13:20:11 UTC (rev 227674)
@@ -69,6 +69,11 @@
     return m_host->capabilities();
 }
 
+bool Session::isConnected() const
+{
+    return m_host->isConnected();
+}
+
 static std::optional<String> firstWindowHandleInResult(JSON::Value& result)
 {
     RefPtr<JSON::Array> handles;

Modified: trunk/Source/WebDriver/Session.h (227673 => 227674)


--- trunk/Source/WebDriver/Session.h	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/Session.h	2018-01-26 13:20:11 UTC (rev 227674)
@@ -48,6 +48,7 @@
 
     const String& id() const;
     const Capabilities& capabilities() const;
+    bool isConnected() const;
     Seconds scriptTimeout() const  { return m_scriptTimeout; }
     Seconds pageLoadTimeout() const { return m_pageLoadTimeout; }
     Seconds implicitWaitTimeout() const { return m_implicitWaitTimeout; }

Modified: trunk/Source/WebDriver/SessionHost.cpp (227673 => 227674)


--- trunk/Source/WebDriver/SessionHost.cpp	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/SessionHost.cpp	2018-01-26 13:20:11 UTC (rev 227674)
@@ -55,7 +55,7 @@
         messageBuilder.append(parameters->toJSONString());
     }
     messageBuilder.append('}');
-    sendMessageToBackend(messageBuilder.toString());
+    sendMessageToBackend(sequenceID, messageBuilder.toString());
 
     return sequenceID;
 }

Modified: trunk/Source/WebDriver/SessionHost.h (227673 => 227674)


--- trunk/Source/WebDriver/SessionHost.h	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/SessionHost.h	2018-01-26 13:20:11 UTC (rev 227674)
@@ -71,7 +71,7 @@
     };
 
     void inspectorDisconnected();
-    void sendMessageToBackend(const String&);
+    void sendMessageToBackend(long, const String&);
     void dispatchMessage(const String&);
 
 #if USE(GLIB)

Modified: trunk/Source/WebDriver/WebDriverService.cpp (227673 => 227674)


--- trunk/Source/WebDriver/WebDriverService.cpp	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/WebDriverService.cpp	2018-01-26 13:20:11 UTC (rev 227674)
@@ -754,7 +754,11 @@
 
     auto session = std::exchange(m_session, nullptr);
     session->close([this, session, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
-        completionHandler(WTFMove(result));
+        // Ignore unknown errors when closing the session if the browser is closed.
+        if (result.isError() && result.errorCode() == CommandResult::ErrorCode::UnknownError && !session->isConnected())
+            completionHandler(CommandResult::success());
+        else
+            completionHandler(WTFMove(result));
     });
 }
 

Modified: trunk/Source/WebDriver/glib/SessionHostGlib.cpp (227673 => 227674)


--- trunk/Source/WebDriver/glib/SessionHostGlib.cpp	2018-01-26 10:46:38 UTC (rev 227673)
+++ trunk/Source/WebDriver/glib/SessionHostGlib.cpp	2018-01-26 13:20:11 UTC (rev 227674)
@@ -340,12 +340,18 @@
     dispatchMessage(String::fromUTF8(message));
 }
 
-void SessionHost::sendMessageToBackend(const String& message)
+struct MessageContext {
+    long messageID;
+    SessionHost* host;
+};
+
+void SessionHost::sendMessageToBackend(long messageID, const String& message)
 {
     ASSERT(m_dbusConnection);
     ASSERT(m_connectionID);
     ASSERT(m_target.id);
 
+    auto messageContext = std::make_unique<MessageContext>(MessageContext { messageID, this });
     g_dbus_connection_call(m_dbusConnection.get(), nullptr,
         INSPECTOR_DBUS_OBJECT_PATH,
         INSPECTOR_DBUS_INTERFACE,
@@ -352,7 +358,20 @@
         "SendMessageToBackend",
         g_variant_new("(tts)", m_connectionID, m_target.id, message.utf8().data()),
         nullptr, G_DBUS_CALL_FLAGS_NO_AUTO_START,
-        -1, m_cancellable.get(), dbusConnectionCallAsyncReadyCallback, nullptr);
+        -1, m_cancellable.get(), [](GObject* source, GAsyncResult* result, gpointer userData) {
+            auto messageContext = std::unique_ptr<MessageContext>(static_cast<MessageContext*>(userData));
+            GUniqueOutPtr<GError> error;
+            GRefPtr<GVariant> resultVariant = adoptGRef(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error.outPtr()));
+            if (!resultVariant && !g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+                auto responseHandler = messageContext->host->m_commandRequests.take(messageContext->messageID);
+                if (responseHandler) {
+                    auto errorObject = JSON::Object::create();
+                    errorObject->setInteger(ASCIILiteral("code"), -32603);
+                    errorObject->setString(ASCIILiteral("message"), String::fromUTF8(error->message));
+                    responseHandler({ WTFMove(errorObject), true });
+                }
+            }
+        }, messageContext.release());
 }
 
 } // namespace WebDriver
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to