Backed out 4 changesets (bug 1392411, bug 1546736) for failures on /browser_net_websocket_stacks.js. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Fri, 17 May 2019 04:27:56 +0300
changeset 533139 a67530e635b1a1b676a101150ac4c0e4cb73801b
parent 533138 5dd54f014ddd53b3114cb438162fc35ff53b0d93
child 533140 afd2db10c864309a1e58f055e380c98248fb25a1
push id11276
push userrgurzau@mozilla.com
push dateMon, 20 May 2019 13:11:24 +0000
treeherdermozilla-beta@847755a7c325 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1392411, 1546736
milestone68.0a1
backs outc37ca68a24e5a38192a1ef8ccf01c406ccc511ce
1c23ba0f835f1a097ba5249bbef8e5c79308ae29
fce11a50c0589bb63a61abc716ea05ca1c53f12f
2e2f3fc37e2eca6e5451c04d395ccf435c3a067c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 4 changesets (bug 1392411, bug 1546736) for failures on /browser_net_websocket_stacks.js. CLOSED TREE Backed out changeset c37ca68a24e5 (bug 1546736) Backed out changeset 1c23ba0f835f (bug 1392411) Backed out changeset fce11a50c058 (bug 1392411) Backed out changeset 2e2f3fc37e2e (bug 1392411)
devtools/client/netmonitor/test/browser.ini
devtools/client/netmonitor/test/browser_net_websocket_stacks.js
devtools/client/netmonitor/test/html_websocket-test-page.html
devtools/client/netmonitor/test/js_websocket-worker-test.js
devtools/server/actors/network-event.js
devtools/server/actors/network-monitor.js
devtools/server/actors/network-monitor/stack-trace-collector.js
dom/websocket/WebSocket.cpp
--- a/devtools/client/netmonitor/test/browser.ini
+++ b/devtools/client/netmonitor/test/browser.ini
@@ -40,20 +40,18 @@ support-files =
   html_statistics-test-page.html
   html_status-codes-test-page.html
   html_tracking-protection.html
   html_api-calls-test-page.html
   html_copy-as-curl.html
   html_curl-utils.html
   html_open-request-in-tab.html
   html_worker-test-page.html
-  html_websocket-test-page.html
   js_worker-test.js
   js_worker-test2.js
-  js_websocket-worker-test.js
   sjs_content-type-test-server.sjs
   sjs_cors-test-server.sjs
   sjs_https-redirect-test-server.sjs
   sjs_hsts-test-server.sjs
   sjs_json-test-server.sjs
   sjs_method-test-server.sjs
   sjs_set-cookie-same-site.sjs
   sjs_simple-test-server.sjs
@@ -221,10 +219,9 @@ skip-if = true # Bug 1373558
 [browser_net_timeline_ticks.js]
 skip-if = true # TODO: fix the test
 [browser_net_timing-division.js]
 [browser_net_tracking-resources.js]
 [browser_net_truncate-post-data.js]
 [browser_net_truncate.js]
 [browser_net_view-source-debugger.js]
 [browser_net_waterfall-click.js]
-[browser_net_websocket_stacks.js]
 [browser_net_worker_stacks.js]
deleted file mode 100644
--- a/devtools/client/netmonitor/test/browser_net_websocket_stacks.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-// Test that we get stack traces for the network requests made when creating
-// web sockets on the main or worker threads.
-
-const TOP_FILE_NAME = "html_websocket-test-page.html";
-const TOP_URL = EXAMPLE_URL + TOP_FILE_NAME;
-const WORKER_FILE_NAME = "js_websocket-worker-test.js";
-
-const EXPECTED_REQUESTS = [
-  {
-    method: "GET",
-    url: TOP_URL,
-    causeType: "document",
-    causeUri: null,
-    stack: true,
-  },
-  {
-    method: "GET",
-    url: "http://localhost:8080/",
-    causeType: "websocket",
-    causeUri: TOP_URL,
-    stack: [
-      { fn: "openSocket", file: TOP_FILE_NAME, line: 6 },
-      { file: TOP_FILE_NAME, line: 3 },
-    ],
-  },
-  {
-    method: "GET",
-    url: EXAMPLE_URL + WORKER_FILE_NAME,
-    causeType: "script",
-    causeUri: TOP_URL,
-    stack: [ { file: TOP_FILE_NAME, line: 9 } ],
-  },
-  {
-    method: "GET",
-    url: "https://localhost:8081/",
-    causeType: "websocket",
-    causeUri: TOP_URL,
-    stack: [
-      { fn: "openWorkerSocket", file: WORKER_FILE_NAME, line: 5 },
-      { file: WORKER_FILE_NAME, line: 2 },
-    ],
-  },
-];
-
-add_task(async function() {
-  // Load a different URL first to instantiate the network monitor before we
-  // load the page we're really interested in.
-  const { tab, monitor } = await initNetMonitor(SIMPLE_URL);
-
-  const { store, windowRequire, connector } = monitor.panelWin;
-  const {
-    getSortedRequests,
-  } = windowRequire("devtools/client/netmonitor/src/selectors/index");
-
-  BrowserTestUtils.loadURI(tab.linkedBrowser, TOP_URL);
-
-  await waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);
-
-  is(store.getState().requests.requests.size, EXPECTED_REQUESTS.length,
-    "All the page events should be recorded.");
-
-  // Wait for stack traces from all requests.
-  const requests = getSortedRequests(store.getState());
-  await Promise.all(requests.map(requestItem =>
-    connector.requestData(requestItem.id, "stackTrace")));
-
-  validateRequests(EXPECTED_REQUESTS, monitor);
-
-  await teardown(monitor);
-});
deleted file mode 100644
--- a/devtools/client/netmonitor/test/html_websocket-test-page.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<script>
-"use strict";
-openSocket();
-
-function openSocket() {
-  this.ws = new WebSocket("ws://localhost:8080/");
-}
-
-this.w = new Worker("js_websocket-worker-test.js");
-</script>
deleted file mode 100644
--- a/devtools/client/netmonitor/test/js_websocket-worker-test.js
+++ /dev/null
@@ -1,6 +0,0 @@
-"use strict";
-openWorkerSocket();
-
-function openWorkerSocket() {
-  this.ws = new WebSocket("wss://localhost:8081");
-}
--- a/devtools/server/actors/network-event.js
+++ b/devtools/server/actors/network-event.js
@@ -257,36 +257,28 @@ const NetworkEventActor = protocol.Actor
    *         The response packet - stack trace.
    */
   async getStackTrace() {
     let stacktrace = this._stackTrace;
     // If _stackTrace was "true", it means we are in parent process
     // and the stack is available from the content process.
     // Fetch it lazily from here via the message manager.
     if (stacktrace && typeof stacktrace == "boolean") {
-      let id;
-      if (this._cause.type == "websocket") {
-        // Convert to a websocket URL, as in onNetworkEvent.
-        id = this._request.url.replace(/^http/, "ws");
-      } else {
-        id = this._channelId;
-      }
-
       const messageManager = this.netMonitorActor.messageManager;
       stacktrace = await new Promise(resolve => {
         const onMessage = ({ data }) => {
           const { channelId, stack } = data;
-          if (channelId == id) {
+          if (channelId == this._channelId) {
             messageManager.removeMessageListener("debug:request-stack:response",
               onMessage);
             resolve(stack);
           }
         };
         messageManager.addMessageListener("debug:request-stack:response", onMessage);
-        messageManager.sendAsyncMessage("debug:request-stack:request", id);
+        messageManager.sendAsyncMessage("debug:request-stack:request", this._channelId);
       });
       this._stackTrace = stacktrace;
     }
 
     return {
       stacktrace,
     };
   },
--- a/devtools/server/actors/network-monitor.js
+++ b/devtools/server/actors/network-monitor.js
@@ -211,35 +211,24 @@ const NetworkMonitorActor = ActorClassWi
 
     // map channel to actor so we can associate future events with it
     this._netEvents.set(channelId, actor);
     return actor;
   },
 
   // This method is called by NetworkMonitor instance when a new request is fired
   onNetworkEvent(event) {
-    const { channelId, cause, url } = event;
+    const { channelId } = event;
 
     const actor = this.getNetworkEventActor(channelId);
     this._netEvents.set(channelId, actor);
 
-    // Find the ID which the stack trace collector will use to save this
-    // channel's stack trace.
-    let id;
-    if (cause.type == "websocket") {
-      // Use the URL, but convert from the http URL which this channel uses to
-      // the original websocket URL which triggered this channel's construction.
-      id = url.replace(/^http/, "ws");
-    } else {
-      id = channelId;
-    }
-
-    event.cause.stacktrace = this.stackTraces.has(id);
+    event.cause.stacktrace = this.stackTraces.has(channelId);
     if (event.cause.stacktrace) {
-      this.stackTraces.delete(id);
+      this.stackTraces.delete(channelId);
     }
     actor.init(event);
 
     this._networkEventActorsByURL.set(actor._request.url, actor);
 
     this.conn.sendActorEvent(this.parentID, "networkEvent", { eventActor: actor.form() });
     return actor;
   },
--- a/devtools/server/actors/network-monitor/stack-trace-collector.js
+++ b/devtools/server/actors/network-monitor/stack-trace-collector.js
@@ -38,46 +38,34 @@ StackTraceCollector.prototype = {
     Services.obs.removeObserver(this, "network-monitor-alternate-stack");
     ChannelEventSinkFactory.getService().unregisterCollector(this);
     for (const { messageManager } of this.netmonitors) {
       messageManager.removeMessageListener("debug:request-stack:request",
         this.onGetStack);
     }
   },
 
-  _saveStackTrace(id, stacktrace) {
-    if (this.stacktracesById.has(id)) {
+  _saveStackTrace(channel, stacktrace) {
+    if (this.stacktracesById.has(channel.channelId)) {
       // We can get up to two stack traces for the same channel: one each from
       // the two observer topics we are listening to. Use the first stack trace
       // which is specified, and ignore any later one.
       return;
     }
     for (const { messageManager } of this.netmonitors) {
       messageManager.sendAsyncMessage("debug:request-stack-available", {
-        channelId: id,
+        channelId: channel.channelId,
         stacktrace: stacktrace && stacktrace.length > 0,
       });
     }
-    this.stacktracesById.set(id, stacktrace);
+    this.stacktracesById.set(channel.channelId, stacktrace);
   },
 
   observe(subject, topic, data) {
-    let channel, id;
-    try {
-      channel = subject.QueryInterface(Ci.nsIHttpChannel);
-      id = channel.channelId;
-    } catch (e) {
-      // WebSocketChannels do not have IDs, so use the URL. When a WebSocket is
-      // opened in a content process, a channel is created locally but the HTTP
-      // channel for the connection lives entirely in the parent process. When
-      // the server code running in the parent sees that HTTP channel, it will
-      // look for the creation stack using the websocket's URL.
-      channel = subject.QueryInterface(Ci.nsIWebSocketChannel);
-      id = channel.URI.spec;
-    }
+    const channel = subject.QueryInterface(Ci.nsIHttpChannel);
 
     if (!matchRequest(channel, this.filters)) {
       return;
     }
 
     const stacktrace = [];
     switch (topic) {
       case "http-on-opening-request": {
@@ -128,33 +116,33 @@ StackTraceCollector.prototype = {
           frame = frame.parent || frame.asyncParent;
         }
         break;
       }
       default:
         throw new Error("Unexpected observe() topic");
     }
 
-    this._saveStackTrace(id, stacktrace);
+    this._saveStackTrace(channel, stacktrace);
   },
 
   // eslint-disable-next-line no-shadow
   onChannelRedirect(oldChannel, newChannel, flags) {
     // We can be called with any nsIChannel, but are interested only in HTTP channels
     try {
       oldChannel.QueryInterface(Ci.nsIHttpChannel);
       newChannel.QueryInterface(Ci.nsIHttpChannel);
     } catch (ex) {
       return;
     }
 
     const oldId = oldChannel.channelId;
     const stacktrace = this.stacktracesById.get(oldId);
     if (stacktrace) {
-      this._saveStackTrace(newChannel.channelId, stacktrace);
+      this._saveStackTrace(newChannel, stacktrace);
     }
   },
 
   getStackTrace(channelId) {
     const trace = this.stacktracesById.get(channelId);
     this.stacktracesById.delete(channelId);
     return trace;
   },
--- a/dom/websocket/WebSocket.cpp
+++ b/dom/websocket/WebSocket.cpp
@@ -13,17 +13,16 @@
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/net/WebSocketChannel.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MessageEvent.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/nsCSPUtils.h"
 #include "mozilla/dom/ScriptSettings.h"
-#include "mozilla/dom/SerializedStackHolder.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "nsAutoPtr.h"
 #include "mozilla/LoadInfo.h"
 #include "nsGlobalWindow.h"
 #include "nsIScriptGlobalObject.h"
@@ -120,18 +119,17 @@ class WebSocketImpl final : public nsIIn
   nsresult Init(JSContext* aCx, nsIPrincipal* aLoadingPrincipal,
                 nsIPrincipal* aPrincipal, bool aIsServerSide,
                 const nsAString& aURL, nsTArray<nsString>& aProtocolArray,
                 const nsACString& aScriptFile, uint32_t aScriptLine,
                 uint32_t aScriptColumn);
 
   nsresult AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
                      nsITransportProvider* aTransportProvider,
-                     const nsACString& aNegotiatedExtensions,
-                     UniquePtr<SerializedStackHolder> aOriginStack);
+                     const nsACString& aNegotiatedExtensions);
 
   nsresult ParseURL(const nsAString& aURL);
   nsresult InitializeConnection(nsIPrincipal* aPrincipal,
                                 nsICookieSettings* aCookieSettings);
 
   // These methods when called can release the WebSocket object
   void FailConnection(uint16_t reasonCode,
                       const nsACString& aReasonString = EmptyCString());
@@ -1116,23 +1114,21 @@ class ConnectRunnable final : public Web
   // Raw pointer. This worker runnable runs synchronously.
   WebSocketImpl* mImpl;
 
   bool mConnectionFailed;
 };
 
 class AsyncOpenRunnable final : public WebSocketMainThreadRunnable {
  public:
-  explicit AsyncOpenRunnable(WebSocketImpl* aImpl,
-                             UniquePtr<SerializedStackHolder> aOriginStack)
+  explicit AsyncOpenRunnable(WebSocketImpl* aImpl)
       : WebSocketMainThreadRunnable(
             aImpl->mWorkerRef->Private(),
             NS_LITERAL_CSTRING("WebSocket :: AsyncOpen")),
         mImpl(aImpl),
-        mOriginStack(std::move(aOriginStack)),
         mErrorCode(NS_OK) {
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
   nsresult ErrorCode() const { return mErrorCode; }
 
  protected:
@@ -1158,36 +1154,33 @@ class AsyncOpenRunnable final : public W
     if (topWindow) {
       topInner = topWindow->GetCurrentInnerWindow();
     }
 
     if (topInner) {
       windowID = topInner->WindowID();
     }
 
-    mErrorCode = mImpl->AsyncOpen(principal, windowID, nullptr, EmptyCString(),
-                                  std::move(mOriginStack));
+    mErrorCode = mImpl->AsyncOpen(principal, windowID, nullptr, EmptyCString());
     return true;
   }
 
   virtual bool InitWindowless(WorkerPrivate* aTopLevelWorkerPrivate) override {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aTopLevelWorkerPrivate && !aTopLevelWorkerPrivate->GetWindow());
 
     mErrorCode = mImpl->AsyncOpen(aTopLevelWorkerPrivate->GetPrincipal(), 0,
-                                  nullptr, EmptyCString(), nullptr);
+                                  nullptr, EmptyCString());
     return true;
   }
 
  private:
   // Raw pointer. This worker runs synchronously.
   WebSocketImpl* mImpl;
 
-  UniquePtr<SerializedStackHolder> mOriginStack;
-
   nsresult mErrorCode;
 };
 
 }  // namespace
 
 already_AddRefed<WebSocket> WebSocket::ConstructorCommon(
     const GlobalObject& aGlobal, const nsAString& aUrl,
     const Sequence<nsString>& aProtocols,
@@ -1363,47 +1356,34 @@ already_AddRefed<WebSocket> WebSocket::C
   }
 
   if (NS_IsMainThread()) {
     MOZ_ASSERT(principal);
 
     nsCOMPtr<nsPIDOMWindowInner> ownerWindow = do_QueryInterface(global);
     nsPIDOMWindowOuter* outerWindow = ownerWindow->GetOuterWindow();
 
-    UniquePtr<SerializedStackHolder> stack;
-    nsIDocShell* docShell = outerWindow->GetDocShell();
-    if (docShell && docShell->GetWatchedByDevtools()) {
-      stack = GetCurrentStackForNetMonitor(aGlobal.Context());
-    }
-
     uint64_t windowID = 0;
     nsCOMPtr<nsPIDOMWindowOuter> topWindow = outerWindow->GetScriptableTop();
     nsCOMPtr<nsPIDOMWindowInner> topInner;
     if (topWindow) {
       topInner = topWindow->GetCurrentInnerWindow();
     }
 
     if (topInner) {
       windowID = topInner->WindowID();
     }
 
     aRv = webSocket->mImpl->AsyncOpen(principal, windowID, aTransportProvider,
-                                      aNegotiatedExtensions, std::move(stack));
+                                      aNegotiatedExtensions);
   } else {
     MOZ_ASSERT(!aTransportProvider && aNegotiatedExtensions.IsEmpty(),
                "not yet implemented");
-
-    UniquePtr<SerializedStackHolder> stack;
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-    if (workerPrivate->IsWatchedByDevtools()) {
-      stack = GetCurrentStackForNetMonitor(aGlobal.Context());
-    }
-
     RefPtr<AsyncOpenRunnable> runnable =
-        new AsyncOpenRunnable(webSocket->mImpl, std::move(stack));
+        new AsyncOpenRunnable(webSocket->mImpl);
     runnable->Dispatch(Canceling, aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
     aRv = runnable->ErrorCode();
   }
 
@@ -1647,18 +1627,17 @@ nsresult WebSocketImpl::Init(JSContext* 
   }
 
   return NS_OK;
 }
 
 nsresult WebSocketImpl::AsyncOpen(nsIPrincipal* aPrincipal,
                                   uint64_t aInnerWindowID,
                                   nsITransportProvider* aTransportProvider,
-                                  const nsACString& aNegotiatedExtensions,
-                                  UniquePtr<SerializedStackHolder> aOriginStack) {
+                                  const nsACString& aNegotiatedExtensions) {
   MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
   MOZ_ASSERT_IF(!aTransportProvider, aNegotiatedExtensions.IsEmpty());
 
   nsCString asciiOrigin;
   nsresult rv = nsContentUtils::GetASCIIOrigin(aPrincipal, asciiOrigin);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aTransportProvider) {
@@ -1675,18 +1654,16 @@ nsresult WebSocketImpl::AsyncOpen(nsIPri
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
   rv = mChannel->AsyncOpen(uri, asciiOrigin, aInnerWindowID, this, nullptr);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return NS_ERROR_CONTENT_BLOCKED;
   }
 
-  NotifyNetworkMonitorAlternateStack(mChannel, std::move(aOriginStack));
-
   mInnerWindowID = aInnerWindowID;
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketImpl methods:
 //-----------------------------------------------------------------------------