New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 604675 link

Starred by 4 users

Issue metadata

Status: Fixed
Owner:
Closed: May 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug

Blocking:
issue 433667
issue 551193
issue 621790



Sign in to add a comment

move alert() away from nested message loop

Project Member Reported by changwan@chromium.org, Apr 19 2016

Issue description

We found that alert() path allows nested calls inside renderer, causing DCHECK failure and reordering of messages (see https://codereview.chromium.org/1865143003/ for details).

Excerpt from aelias@'s email:

alert() needs to block on a single result, the Yes/No boolean answer from the browser-side dialog box.  A full nested message loop that processes every message is overkill for this and introduces a requirement on a lot of other subsystems to support possible reentrancy and reordering.  If we simply need to wait on a single message type, why not use an ordinary sync IPC for alert?  (Or, if we need to also process one or two other types of messages, why not specifically filter those in the nested message loop and repost out every unknown message to the outer loop?)

We'll try to disable nested message loop and only use SyncChannel to simplify the process.
We suspect that <marquee> and animated gifs are the main differences but the changed behavior is compatible with the spec.

 
Here's an update:

I'm trying this at https://codereview.chromium.org/1884063002/.

One failure I'm trying to fix is DevToolsBeforeUnloadTest.TestUndockedDevToolsApplicationClose.

It seems that DispatchBeforeUnload was called multiple times even before this patch. However, we were still able to close the browser through async messages. Now this is not possible as closing requires sync message handling to be finished, and we should make sure that dispatch beforeunload is not called more than necessary.

More specifically, DispatchBeforeUnload() is called once more, even after beforeunload ACK was received, with the following callstack.

#1 0x7f38c8c39ef6 content::RenderFrameHostImpl::DispatchBeforeUnload()
#2 0x7f38c92ef36a content::WebContentsImpl::DispatchBeforeUnload()
#3 0x00000265adae chrome::UnloadController::RunUnloadEventsHelper()
#4 0x00000257e640 Browser::RunUnloadListenerBeforeClosing()
#5 0x0000025a6521 chrome::BrowserTabStripModelDelegate::RunUnloadListenerBeforeClosing()
#6 0x00000261d3f8 TabStripModel::InternalCloseTabs()
#7 0x00000261cf90 TabStripModel::CloseAllTabs()
#8 0x00000257e879 Browser::OnWindowClosing()
#9 0x000002895cdf BrowserView::CanClose()
#10 0x7f38cc383d20 views::NonClientView::CanClose()
#11 0x7f38cc36bf1c views::Widget::Close()
#12 0x00000289047e BrowserView::Close()
#13 0x000001eb2180 BrowserCloseManager::CloseBrowsers()
#14 0x000001eb260f BrowserCloseManager::CheckForDownloadsInProgress()
#15 0x000001eb24cb BrowserCloseManager::TryToCloseBrowsers()
#16 0x000001eb25cb BrowserCloseManager::OnBrowserReportCloseable()

Probably unload controller should keep track of the states more precisely.

Comment 2 by tkent@chromium.org, Apr 19 2016

Components: -Blink>HTML>Dialog Blink>WindowDialog

Comment 3 by aelias@chromium.org, Apr 21 2016

Labels: M-52 OS-All

Comment 4 by aelias@chromium.org, Apr 21 2016

Blocking: 551193

Comment 5 by aelias@chromium.org, Apr 21 2016

For the record, this change has an approved Intent to Ship at https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/HCPVfo254eY
Project Member

Comment 6 by bugdroid1@chromium.org, May 19 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/6ed4d4373c5ce4743850df50f94b867240472033

commit 6ed4d4373c5ce4743850df50f94b867240472033
Author: changwan <changwan@chromium.org>
Date: Thu May 19 22:03:54 2016

Stop using nested message loop for alert() and other JS dialogs

alert() needs to block on a single boolean result and is currently using
a nested loop to process async messages while waiting for a reply from
browser process. The nested loop adds a huge complexity to the subsystem as
it requires support for reentrancy and reordering in handling every message.

Especially, when ImeThread feature was enabled, it was causing a DCHECK
failure and a hang because some messages got unexpectedly reordered.

Instead of landing a workaround for ImeThread case, this removes nested
message loop use case for RenderFrameImpl.

Other changes here includes:
1) Fix ExtensionApiTest not to send async messages and wait for result
   while alert dialog is showing up. This would hang otherwise.
2) Change UnloadController / FastUnloadController to check whether
   beforeunload events have already been fired in the case of devtools.
   We were firing beforeunload events twice when closing devtools
   incorrectly even before this change, but closing process continued
   because async messages were allowed. This fixes
   DevToolsBeforeUnloadTest::TestUndockedDevToolsApplicationClose.
3) For 2), change Browser and BrowserTabStripModel to call non-static
   member functions.
4) Fix UnloadTest by removing the two second wait limit. Sometimes it took
   more than 2 seconds just to close the browser, but the test could close
   the browser because async messages were allowed. Now the test fails if
   before unload dialog shows up, so we prevent it by running an infinite
   loop.

BUG= 604675 

Review-Url: https://codereview.chromium.org/1931793002
Cr-Commit-Position: refs/heads/master@{#394883}

[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/extensions/content_script_apitest.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/browser.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/browser.h
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/browser_tab_strip_model_delegate.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/fast_unload_controller.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/fast_unload_controller.h
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/unload_controller.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/ui/unload_controller.h
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/chrome/browser/unload_browsertest.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/content/public/android/javatests/src/org/chromium/content/browser/input/ImeTest.java
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/content/renderer/render_frame_impl.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/content/renderer/render_frame_impl.h
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/content/renderer/render_thread_impl.cc
[modify] https://crrev.com/6ed4d4373c5ce4743850df50f94b867240472033/content/renderer/render_thread_impl.h

Status: Fixed (was: Started)
Blocking: 433667
Blocking: 621790

Sign in to add a comment