Bug 1559244 - Step 2: Add support for crashing sub-frame. r=mconley
☠☠ backed out by fa80b89e0ce4 ☠ ☠
authorAbdoulaye O. Ly <ablayelyfondou@gmail.com>
Thu, 15 Aug 2019 17:16:26 +0000
changeset 488317 dced8cea7b23c28a0e2b66b51a4b022fdec2c1d1
parent 488316 dabda4e90259abe8a2fc766549a0dfd77beb6c31
child 488318 1ce7d9bbe7a1bb01a5f4fb57882b5291b5b7f7c2
push id36440
push userncsoregi@mozilla.com
push dateFri, 16 Aug 2019 03:57:48 +0000
treeherdermozilla-central@a58b7dc85887 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1559244
milestone70.0a1
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
Bug 1559244 - Step 2: Add support for crashing sub-frame. r=mconley Differential Revision: https://phabricator.services.mozilla.com/D37780
browser/base/content/test/general/browser_restore_isAppTab.js
browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
browser/base/content/test/tabcrashed/browser_clearEmail.js
browser/base/content/test/tabcrashed/browser_noPermanentKey.js
browser/base/content/test/tabcrashed/browser_showForm.js
browser/base/content/test/tabcrashed/browser_shown.js
browser/base/content/test/tabcrashed/browser_shownRestartRequired.js
browser/base/content/test/tabcrashed/browser_withoutDump.js
browser/components/extensions/test/browser/browser_ext_port_disconnect_on_crash.js
browser/components/sessionstore/test/browser_async_flushes.js
browser/components/sessionstore/test/browser_background_tab_crash.js
browser/components/sessionstore/test/browser_crashedTabs.js
browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
browser/components/sessionstore/test/browser_tabicon_after_bg_tab_crash.js
browser/components/sessionstore/test/browser_unrestored_crashedTabs.js
dom/ipc/tests/process_error.xul
netwerk/test/browser/browser_child_resource.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
toolkit/components/extensions/test/xpcshell/test_ext_background_early_shutdown.js
toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_during_capture.js
toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_while_idle.js
toolkit/content/tests/browser/browser_content_url_annotation.js
--- a/browser/base/content/test/general/browser_restore_isAppTab.js
+++ b/browser/base/content/test/general/browser_restore_isAppTab.js
@@ -43,17 +43,17 @@ var restart = async function(browser) {
   // If the tab isn't remote this would crash the main process so skip it
   if (!browser.isRemoteBrowser) {
     return;
   }
 
   // Make sure the main process has all of the current tab state before crashing
   await TabStateFlusher.flush(browser);
 
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   let tab = gBrowser.getTabForBrowser(browser);
   SessionStore.reviveCrashedTab(tab);
 
   await promiseTabLoaded(tab);
 };
 
 add_task(async function navigate() {
--- a/browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
+++ b/browser/base/content/test/tabcrashed/browser_autoSubmitRequest.js
@@ -29,17 +29,17 @@ add_task(async function test_show_form()
       url: PAGE,
     },
     async function(browser) {
       // Make sure we've flushed the browser messages so that
       // we can restore it.
       await TabStateFlusher.flush(browser);
 
       // Now crash the browser.
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       let doc = browser.contentDocument;
 
       // Ensure the request is visible. We can safely reach into
       // the content since about:tabcrashed is an in-process URL.
       let requestAutoSubmit = doc.getElementById("requestAutoSubmit");
       Assert.ok(
         !requestAutoSubmit.hidden,
@@ -82,17 +82,17 @@ add_task(async function test_show_form()
   await BrowserTestUtils.withNewTab(
     {
       gBrowser,
       url: PAGE,
     },
     async function(browser) {
       await TabStateFlusher.flush(browser);
       // Now crash the browser.
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       let doc = browser.contentDocument;
 
       // Ensure the request is NOT visible. We can safely reach into
       // the content since about:tabcrashed is an in-process URL.
       let requestAutoSubmit = doc.getElementById("requestAutoSubmit");
       Assert.ok(
         requestAutoSubmit.hidden,
@@ -133,17 +133,17 @@ add_task(async function test_no_offer() 
     },
     async function(browser) {
       await TabStateFlusher.flush(browser);
 
       // Make it so that it seems like no dump is available for the next crash.
       prepareNoDump();
 
       // Now crash the browser.
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       let doc = browser.contentDocument;
 
       // Ensure the request to autosubmit is invisible, since there's no report.
       let requestRect = doc
         .getElementById("requestAutoSubmit")
         .getBoundingClientRect();
       Assert.equal(
--- a/browser/base/content/test/tabcrashed/browser_clearEmail.js
+++ b/browser/base/content/test/tabcrashed/browser_clearEmail.js
@@ -32,17 +32,17 @@ add_task(async function test_clear_email
       let originalEmail = prefs.getCharPref("email");
 
       // Pretend that we stored an email address from the previous
       // crash
       prefs.setCharPref("email", EMAIL);
       prefs.setBoolPref("emailMe", true);
 
       let tab = gBrowser.getTabForBrowser(browser);
-      await BrowserTestUtils.crashBrowser(
+      await BrowserTestUtils.crashFrame(
         browser,
         /* shouldShowTabCrashPage */ true,
         /* shouldClearMinidumps */ false
       );
       let doc = browser.contentDocument;
 
       // Since about:tabcrashed will run in the parent process, we can safely
       // manipulate its DOM nodes directly
--- a/browser/base/content/test/tabcrashed/browser_noPermanentKey.js
+++ b/browser/base/content/test/tabcrashed/browser_noPermanentKey.js
@@ -15,17 +15,17 @@ add_task(async function test_without_dum
   return BrowserTestUtils.withNewTab(
     {
       gBrowser,
       url: PAGE,
     },
     async function(browser) {
       delete browser.permanentKey;
 
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
       let crashReport = promiseCrashReport();
 
       await ContentTask.spawn(browser, null, async function() {
         let doc = content.document;
         Assert.ok(
           doc.documentElement.classList.contains("crashDumpAvailable"),
           "Should be offering to submit a crash report."
         );
--- a/browser/base/content/test/tabcrashed/browser_showForm.js
+++ b/browser/base/content/test/tabcrashed/browser_showForm.js
@@ -22,17 +22,17 @@ add_task(async function test_show_form()
       // Flip the pref so that the checkbox should be checked
       // by default.
       let pref = TabCrashHandler.prefs.root + "sendReport";
       await SpecialPowers.pushPrefEnv({
         set: [[pref, true]],
       });
 
       // Now crash the browser.
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       let doc = browser.contentDocument;
 
       // Ensure the checkbox is checked. We can safely reach into
       // the content since about:tabcrashed is an in-process URL.
       let checkbox = doc.getElementById("sendReport");
       ok(checkbox.checked, "Send report checkbox is checked.");
 
--- a/browser/base/content/test/tabcrashed/browser_shown.js
+++ b/browser/base/content/test/tabcrashed/browser_shown.js
@@ -53,17 +53,17 @@ function crashTabTestHelper(fieldValues,
     async function(browser) {
       let prefs = TabCrashHandler.prefs;
       let originalSendReport = prefs.getBoolPref("sendReport");
       let originalEmailMe = prefs.getBoolPref("emailMe");
       let originalIncludeURL = prefs.getBoolPref("includeURL");
       let originalEmail = prefs.getCharPref("email");
 
       let tab = gBrowser.getTabForBrowser(browser);
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
       let doc = browser.contentDocument;
 
       // Since about:tabcrashed will run in the parent process, we can safely
       // manipulate its DOM nodes directly
       let comments = doc.getElementById("comments");
       let email = doc.getElementById("email");
       let emailMe = doc.getElementById("emailMe");
       let includeURL = doc.getElementById("includeURL");
--- a/browser/base/content/test/tabcrashed/browser_shownRestartRequired.js
+++ b/browser/base/content/test/tabcrashed/browser_shownRestartRequired.js
@@ -18,17 +18,17 @@ function crashTabTestHelper() {
     {
       gBrowser,
       url: PAGE,
     },
     async function(browser) {
       // Simulate buildID mismatch.
       TabCrashHandler.testBuildIDMismatch = true;
 
-      await BrowserTestUtils.crashBrowser(browser, false);
+      await BrowserTestUtils.crashFrame(browser, false);
       let doc = browser.contentDocument;
 
       // Since about:restartRequired will run in the parent process, we can safely
       // manipulate its DOM nodes directly
       let title = doc.getElementById("title");
       let description = doc.getElementById("errorLongContent");
       let restartButton = doc.getElementById("restart");
 
--- a/browser/base/content/test/tabcrashed/browser_withoutDump.js
+++ b/browser/base/content/test/tabcrashed/browser_withoutDump.js
@@ -13,17 +13,17 @@ add_task(async function setup() {
 add_task(async function test_without_dump() {
   return BrowserTestUtils.withNewTab(
     {
       gBrowser,
       url: PAGE,
     },
     async function(browser) {
       let tab = gBrowser.getTabForBrowser(browser);
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       let tabClosingPromise = BrowserTestUtils.waitForTabClosing(tab);
 
       await ContentTask.spawn(browser, null, async function() {
         let doc = content.document;
         Assert.ok(
           !doc.documentElement.classList.contains("crashDumpAvailable"),
           "doesn't have crash dump"
--- a/browser/components/extensions/test/browser/browser_ext_port_disconnect_on_crash.js
+++ b/browser/components/extensions/test/browser/browser_ext_port_disconnect_on_crash.js
@@ -42,17 +42,17 @@ add_task(async function connect_from_tab
 
   let tab = await BrowserTestUtils.openNewForegroundTab(
     gBrowser,
     "http://example.com/?crashme"
   );
   await extension.awaitMessage("bg_runtime_onConnect");
   // Force the message manager to disconnect without giving the content a
   // chance to send an "Extension:Port:Disconnect" message.
-  await BrowserTestUtils.crashBrowser(tab.linkedBrowser);
+  await BrowserTestUtils.crashFrame(tab.linkedBrowser);
   await extension.awaitMessage("port_disconnected");
   BrowserTestUtils.removeTab(tab);
   await extension.unload();
 });
 
 add_task(async function connect_from_bg_to_tab_and_crash_tab() {
   let extension = ExtensionTestUtils.loadExtension({
     manifest: {
@@ -99,13 +99,13 @@ add_task(async function connect_from_bg_
 
   let tab = await BrowserTestUtils.openNewForegroundTab(
     gBrowser,
     "http://example.com/?crashme"
   );
   await extension.awaitMessage("tab_runtime_onConnect");
   // Force the message manager to disconnect without giving the content a
   // chance to send an "Extension:Port:Disconnect" message.
-  await BrowserTestUtils.crashBrowser(tab.linkedBrowser);
+  await BrowserTestUtils.crashFrame(tab.linkedBrowser);
   await extension.awaitMessage("port_disconnected");
   BrowserTestUtils.removeTab(tab);
   await extension.unload();
 });
--- a/browser/components/sessionstore/test/browser_async_flushes.js
+++ b/browser/components/sessionstore/test/browser_async_flushes.js
@@ -69,17 +69,17 @@ add_task(async function test_crash() {
       content.document.querySelector("a").click();
     });
   });
 
   // Crash the browser and flush. Both messages are async and will be sent to
   // the content process. The "crash" message makes it first so that we don't
   // get a chance to process the flush. The TabStateFlusher however should be
   // notified so that the flush still completes.
-  let promise1 = BrowserTestUtils.crashBrowser(browser);
+  let promise1 = BrowserTestUtils.crashFrame(browser);
   let promise2 = TabStateFlusher.flush(browser);
   await Promise.all([promise1, promise2]);
 
   // The pending update should be lost.
   ({ entries } = JSON.parse(ss.getTabState(tab)));
   is(entries.length, 1, "still only one history entry");
 
   // Cleanup.
--- a/browser/components/sessionstore/test/browser_background_tab_crash.js
+++ b/browser/components/sessionstore/test/browser_background_tab_crash.js
@@ -88,17 +88,17 @@ async function crashBackgroundTabs(tabs)
   let remotenessChangePromises = tabs.map(t => {
     return BrowserTestUtils.waitForEvent(t, "TabRemotenessChange");
   });
 
   let tabsRevived = tabs.map(t => {
     return promiseTabRestoring(t);
   });
 
-  await BrowserTestUtils.crashBrowser(tabs[0].linkedBrowser, false);
+  await BrowserTestUtils.crashFrame(tabs[0].linkedBrowser, false);
   await Promise.all(remotenessChangePromises);
   await Promise.all(tabsRevived);
 
   // Both background tabs should now be in the pending restore
   // state.
   for (let tab of tabs) {
     Assert.ok(!tab.linkedBrowser.isRemoteBrowser, "tab is not remote");
     Assert.ok(!tab.linkedBrowser.hasAttribute("crashed"), "tab is not crashed");
--- a/browser/components/sessionstore/test/browser_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_crashedTabs.js
@@ -145,17 +145,17 @@ add_task(async function test_crash_page_
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   // Check the tab state and make sure the tab crashed page isn't
   // mentioned.
   let { entries } = JSON.parse(ss.getTabState(newTab));
   is(entries.length, 1, "Should have a single history entry");
   is(
     entries[0].url,
     PAGE_1,
@@ -177,17 +177,17 @@ add_task(async function test_revived_his
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   // Browse to a new site that will cause the browser to
   // become remote again.
   BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseTabRestored(newTab);
   ok(
     !newTab.hasAttribute("crashed"),
     "Tab shouldn't be marked as crashed anymore."
@@ -225,17 +225,17 @@ add_task(async function test_revived_his
   ok(browser.isRemoteBrowser, "Should be a remote browser");
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   // Browse to a new site that will not cause the browser to
   // become remote again.
   BrowserTestUtils.loadURI(browser, "about:mozilla");
   await promiseBrowserLoaded(browser);
   ok(
     !newTab.hasAttribute("crashed"),
     "Tab shouldn't be marked as crashed anymore."
@@ -286,17 +286,17 @@ add_task(async function test_revive_tab_
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
   // Background tabs should not be crashed, but should be in the "to be restored"
   // state.
   ok(!newTab2.hasAttribute("crashed"), "Second tab should not be crashed.");
   ok(newTab2.hasAttribute("pending"), "Second tab should be pending.");
 
   // Use SessionStore to revive the first tab
   clickButton(browser, "restoreTab");
   await promiseTabRestored(newTab);
@@ -350,17 +350,17 @@ add_task(async function test_revive_all_
 
   BrowserTestUtils.loadURI(browser, PAGE_2);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
   await TabStateFlusher.flush(browser2);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
   // Both tabs should now be crashed.
   is(newTab.getAttribute("crashed"), "true", "First tab should be crashed");
   is(
     newTab2.getAttribute("crashed"),
     "true",
     "Second window tab should be crashed"
   );
 
@@ -403,17 +403,17 @@ add_task(async function test_close_tab_a
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   let promise = BrowserTestUtils.waitForEvent(
     gBrowser.tabContainer,
     "TabClose"
   );
 
   // Click the close tab button
   clickButton(browser, "closeTab");
@@ -434,17 +434,17 @@ add_task(async function test_hide_restor
   await promiseBrowserLoaded(browser);
 
   BrowserTestUtils.loadURI(browser, PAGE_1);
   await promiseBrowserLoaded(browser);
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   let doc = browser.contentDocument;
   let restoreAllButton = doc.getElementById("restoreAll");
   let restoreOneButton = doc.getElementById("restoreTab");
 
   let restoreAllStyles = window.getComputedStyle(restoreAllButton);
   is(restoreAllStyles.display, "none", "Restore All button should be hidden");
   ok(
@@ -468,17 +468,17 @@ add_task(async function test_hide_restor
   let otherWinBrowser = newTab3.linkedBrowser;
   await promiseBrowserLoaded(otherWinBrowser);
   // We'll need to make sure the second tab's browser has finished
   // sending its AboutTabCrashedReady event before we know for
   // sure whether or not we're showing the right Restore buttons.
   let otherBrowserReady = promiseTabCrashedReady(otherWinBrowser);
 
   // Crash the first tab.
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
   await otherBrowserReady;
 
   doc = browser.contentDocument;
   restoreAllButton = doc.getElementById("restoreAll");
   restoreOneButton = doc.getElementById("restoreTab");
 
   restoreAllStyles = window.getComputedStyle(restoreAllButton);
   isnot(
@@ -508,17 +508,17 @@ add_task(async function test_aboutcrashe
 
   FullZoom.enlarge();
   let zoomLevel = ZoomManager.getZoomForBrowser(browser);
   ok(zoomLevel !== 1, "should have enlarged");
 
   await TabStateFlusher.flush(browser);
 
   // Crash the tab
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   ok(
     ZoomManager.getZoomForBrowser(browser) === 1,
     "zoom should have reset on crash"
   );
 
   clickButton(browser, "restoreTab");
   await promiseTabRestored(newTab);
--- a/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
+++ b/browser/components/sessionstore/test/browser_revive_crashed_bg_tabs.js
@@ -32,17 +32,17 @@ add_task(async function test_revive_bg_t
   let newTab2 = BrowserTestUtils.addTab(gBrowser, PAGE_2);
   let browser2 = newTab2.linkedBrowser;
   await BrowserTestUtils.browserLoaded(browser2);
 
   await TabStateFlusher.flush(browser2);
 
   // Now crash the selected tab
   let windowReady = BrowserTestUtils.waitForEvent(window, "SSWindowStateReady");
-  await BrowserTestUtils.crashBrowser(browser1);
+  await BrowserTestUtils.crashFrame(browser1);
 
   ok(newTab1.hasAttribute("crashed"), "Selected tab should be crashed");
   ok(!newTab2.hasAttribute("crashed"), "Background tab should not be crashed");
 
   // Wait until we've had a chance to restore all tabs immediately
   await windowReady;
 
   // But we should not have restored the background tab
--- a/browser/components/sessionstore/test/browser_tabicon_after_bg_tab_crash.js
+++ b/browser/components/sessionstore/test/browser_tabicon_after_bg_tab_crash.js
@@ -33,17 +33,17 @@ add_task(async function test_tabicon_aft
           return gBrowser.getIcon() != null;
         },
         "wait for favicon load to finish",
         100,
         5
       );
       Assert.equal(browser.mIconURL, FAVICON, "Favicon is correctly set.");
       await BrowserTestUtils.switchTab(gBrowser, originalTab);
-      await BrowserTestUtils.crashBrowser(
+      await BrowserTestUtils.crashFrame(
         browser,
         false /* shouldShowTabCrashPage */
       );
       Assert.equal(
         browser.mIconURL,
         FAVICON,
         "Favicon is still set after crash."
       );
--- a/browser/components/sessionstore/test/browser_unrestored_crashedTabs.js
+++ b/browser/components/sessionstore/test/browser_unrestored_crashedTabs.js
@@ -39,17 +39,17 @@ add_task(async function test() {
       };
 
       ss.setTabState(unrestoredTab, JSON.stringify(state));
 
       ok(!unrestoredTab.hasAttribute("crashed"), "tab is not crashed");
       ok(unrestoredTab.hasAttribute("pending"), "tab is pending");
 
       // Now crash the selected browser.
-      await BrowserTestUtils.crashBrowser(browser);
+      await BrowserTestUtils.crashFrame(browser);
 
       ok(!unrestoredTab.hasAttribute("crashed"), "tab is still not crashed");
       ok(unrestoredTab.hasAttribute("pending"), "tab is still pending");
 
       // Selecting the tab should now restore it.
       gBrowser.selectedTab = unrestoredTab;
       await promiseTabRestored(unrestoredTab);
 
--- a/dom/ipc/tests/process_error.xul
+++ b/dom/ipc/tests/process_error.xul
@@ -41,15 +41,15 @@
       let browsingContextId = browser.frameLoader.browsingContext.id;
 
       let eventFiredPromise = BrowserTestUtils.waitForEvent(browser, "oop-browser-crashed");
       let eventPromise = eventFiredPromise.then(event => {
         is(event.browsingContextId, browsingContextId,
            "Expected the right browsing context id on the oop-browser-crashed event.");
       })
 
-      BrowserTestUtils.crashBrowser(browser, true, false);
+      BrowserTestUtils.crashFrame(browser, true, false);
 
       Promise.all([observerPromise, eventPromise]).then(done);
     });
   ]]></script>
 
 </window>
--- a/netwerk/test/browser/browser_child_resource.js
+++ b/netwerk/test/browser/browser_child_resource.js
@@ -81,17 +81,17 @@ var loadTestTab = async function() {
 // Restarts the child process by crashing it then reloading the tab
 var restart = async function() {
   let browser = gBrowser.selectedBrowser;
   // If the tab isn't remote this would crash the main process so skip it
   if (browser.getAttribute("remote") != "true") {
     return browser;
   }
 
-  await BrowserTestUtils.crashBrowser(browser);
+  await BrowserTestUtils.crashFrame(browser);
 
   browser.reload();
 
   await BrowserTestUtils.browserLoaded(browser);
   is(
     browser.getAttribute("remote"),
     expectedRemote,
     "Browser should be in the right process"
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -1610,36 +1610,40 @@ var BrowserTestUtils = {
    * @returns (Promise)
    * @resolves When the tab starts closing. Does not get passed a value.
    */
   waitForTabClosing(tab) {
     return this.waitForEvent(tab, "TabClose");
   },
 
   /**
-   * Crashes a remote browser tab and cleans up the generated minidumps.
+   * Crashes a remote frame tab and cleans up the generated minidumps.
    * Resolves with the data from the .extra file (the crash annotations).
    *
    * @param (Browser) browser
    *        A remote <xul:browser> element. Must not be null.
    * @param (bool) shouldShowTabCrashPage
    *        True if it is expected that the tab crashed page will be shown
    *        for this browser. If so, the Promise will only resolve once the
    *        tab crash page has loaded.
    * @param (bool) shouldClearMinidumps
    *        True if the minidumps left behind by the crash should be removed.
+   * @param (BrowsingContext) browsingContext
+   *        The context where the frame leaves. Default to
+   *        top level context if not supplied.
    *
    * @returns (Promise)
    * @resolves An Object with key-value pairs representing the data from the
    *           crash report's extra file (if applicable).
    */
-  async crashBrowser(
+  async crashFrame(
     browser,
     shouldShowTabCrashPage = true,
-    shouldClearMinidumps = true
+    shouldClearMinidumps = true,
+    browsingContext
   ) {
     let extra = {};
     let KeyValueParser = {};
     if (AppConstants.MOZ_CRASHREPORTER) {
       ChromeUtils.import(
         "resource://gre/modules/KeyValueParser.jsm",
         KeyValueParser
       );
@@ -1765,17 +1769,17 @@ var BrowserTestUtils = {
             true
           );
         })
       );
     }
 
     // Trigger crash by sending a message to BrowserTestUtils actor.
     this.sendAsyncMessage(
-      browser.browsingContext,
+      browsingContext || browser.browsingContext,
       "BrowserTestUtils:CrashFrame",
       {}
     );
 
     await Promise.all(expectedPromises);
 
     if (shouldShowTabCrashPage) {
       let gBrowser = browser.ownerGlobal.gBrowser;
--- a/toolkit/components/extensions/test/xpcshell/test_ext_background_early_shutdown.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_background_early_shutdown.js
@@ -1,12 +1,16 @@
 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set sts=2 sw=2 et tw=80: */
 "use strict";
 
+const { BrowserTestUtils } = ChromeUtils.import(
+  "resource://testing-common/BrowserTestUtils.jsm"
+);
+
 AddonTestUtils.init(this);
 AddonTestUtils.overrideCertDB();
 AddonTestUtils.createAppInfo(
   "xpcshell@tests.mozilla.org",
   "XPCShell",
   "1",
   "43"
 );
@@ -23,32 +27,29 @@ Services.prefs.setBoolPref(
 );
 
 let { Management } = ChromeUtils.import(
   "resource://gre/modules/Extension.jsm",
   null
 );
 
 // Crashes a <browser>'s remote process.
-// Based on BrowserTestUtils.crashBrowser.
-function crashBrowser(browser) {
+// Based on BrowserTestUtils.crashFrame.
+function crashFrame(browser) {
   if (!browser.isRemoteBrowser) {
     // The browser should be remote, or the test runner would be killed.
     throw new Error("<browser> must be remote");
   }
 
-  let frameScript = () => {
-    const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
-    privateNoteIntentionalCrash(); /* eslint-disable-line no-undef */
-    let zero = new ctypes.intptr_t(8);
-    let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
-    dump("Intentionally crashing extension process...\n");
-    badptr.contents; /* eslint-disable-line no-unused-expressions */
-  };
-  browser.messageManager.loadFrameScript(`data:,(${frameScript})();`, false);
+  // Trigger crash by sending a message to BrowserTestUtils actor.
+  BrowserTestUtils.sendAsyncMessage(
+    browser.browsingContext,
+    "BrowserTestUtils:CrashFrame",
+    {}
+  );
 }
 
 // Verifies that a delayed background page is not loaded when an extension is
 // shut down during startup.
 add_task(async function test_unload_extension_before_background_page_startup() {
   await promiseStartupManager();
 
   let extension = ExtensionTestUtils.loadExtension({
@@ -158,17 +159,17 @@ add_task(async function test_unload_exte
           "Expected background page"
         );
         // Reset to "about:blank" to not load the actual background page.
         arguments[0] = "about:blank";
         browserLoadURI.apply(this, arguments);
 
         // And force the extension process to crash.
         if (browser.isRemote) {
-          crashBrowser(browser);
+          crashFrame(browser);
         } else {
           // If extensions are not running in out-of-process mode, then the
           // non-remote process should not be killed (or the test runner dies).
           // Remove <browser> instead, to simulate the immediate disconnection
           // of the message manager (that would happen if the process crashed).
           browser.remove();
         }
         resolve();
--- a/toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_during_capture.js
+++ b/toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_during_capture.js
@@ -42,17 +42,17 @@ function* runTests() {
   let capturePromise = new Promise(resolve => {
     bgAddPageThumbObserver(goodUrl).then(() => {
       ok(true, `page-thumbnail created for ${goodUrl}`);
       resolve();
     });
   });
 
   info("Crashing the thumbnail content process.");
-  let crash = yield BrowserTestUtils.crashBrowser(
+  let crash = yield BrowserTestUtils.crashFrame(
     BackgroundPageThumbs._thumbBrowser,
     false
   );
   ok(crash.CrashTime, "Saw a crash from this test");
 
   yield crashPromise;
   yield capturePromise;
 }
--- a/toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_while_idle.js
+++ b/toolkit/components/thumbnails/test/browser_thumbnails_bg_crash_while_idle.js
@@ -5,17 +5,17 @@ function* runTests() {
   // make a good capture first - this ensures we have the <browser>
   let goodUrl = bgTestPageURL();
   yield bgCapture(goodUrl);
   ok(thumbnailExists(goodUrl), "Thumbnail should be cached after capture");
   removeThumbnail(goodUrl);
 
   // Nothing is pending - crash the process.
   info("Crashing the thumbnail content process.");
-  let crash = yield BrowserTestUtils.crashBrowser(
+  let crash = yield BrowserTestUtils.crashFrame(
     BackgroundPageThumbs._thumbBrowser,
     false
   );
   ok(crash.CrashTime, "Saw a crash from this test");
 
   // Now queue another capture and ensure it recovers.
   bgCapture(goodUrl, {
     onDone: () => {
--- a/toolkit/content/tests/browser/browser_content_url_annotation.js
+++ b/toolkit/content/tests/browser/browser_content_url_annotation.js
@@ -68,17 +68,17 @@ add_task(async function test_content_url
             true
           );
         });
       });
       BrowserTestUtils.loadURI(browser, url);
       await promise;
 
       // Crash the tab
-      let annotations = await BrowserTestUtils.crashBrowser(browser);
+      let annotations = await BrowserTestUtils.crashFrame(browser);
 
       ok("URL" in annotations, "annotated a URL");
       is(
         annotations.URL,
         redirect_url,
         "Should have annotated the URL after redirect"
       );
     }