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

Issue metadata

Status: Fixed
Owner:
Closed: May 2013
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug

Blocking:
issue 68208
issue 69298



Sign in to add a comment

Chrome freezes (all windows) when setting DownloadURL in ondragstart and clicking/dragging quickly

Reported by ben.gilb...@smartsheet.com, Nov 29 2012

Issue description

UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11

Steps to reproduce the problem:
1. Load the attached page (dragTest.htm).
2. Double-click and attempt to drag it at the same time - it doesn't seem to happen readily with just a normal single click and drag.
3. Repeat #2 until the browser freezes - it's usually pretty easy to see because the drag "ghost" will get stuck near where it started (see attached screenshot).

What is the expected behavior?
No freezing

What went wrong?
The entire browser freezes. No events are fired in any of the tabs or Chrome windows and if you try to open a new tab or click on any of the windows, nothing happens. You have to use End Process in Task Manager to shut down the browser.

Crashed report ID: 

How much crashed? Whole browser

Is it a problem with a plugin? No 

Did this work before? N/A 

Chrome version: 23.0.1271.91  Channel: stable
OS Version: 6.1 (Windows 7, Windows Server 2008 R2)

Note that while the repro steps sound a bit unlikely, we do have users running into this in the field (on our site - Smartsheet.com) - most likely they are accidentally double-clicking when they mean to single click, or they are accidentally starting a drag when they mean to simply double-click.
 
dragTest.htm
980 bytes View Download
Note - it's easiest to get it to happen if you click near the left side of the div, and drag it to the right as you're clicking. Perhaps this is because if the drag starts and another click occurs during the drag, the click is still over the same element.
dragTest-freeze.png
72.5 KB View Download

Comment 2 by pim...@live.nl, Feb 4 2013

I also ran into this issue. Right-clicking the Chrome window entry in the Windows taskbar solves it: a download starts, and the download bar is hidden immediately. It seems nothing has been really downloaded, but the browser becomes responsive again and the ghost drag image disappears. It looks like the DownloadURL download process starts without dropping in a directory (but I'm not sure where, if at all, the DownloadURL file is being saved).
Still freezing in Chrome 24.0.1312.57 m (Windows 7)

A live "freeze" can be done in this tutorial talking about the dragstart/DownloadURL feature:
http://codebits.glennjones.net/downloadurl/downloadurl.htm

Start dragging the "Drag this" link and quickly release the mouse button.
Then, the browser is dead as Ben described.


Comment 4 by asanka@chromium.org, Feb 13 2013

Cc: asanka@chromium.org
Labels: Feature-Downloads
[Adding Feature-Downloads for now]

I can't reproduce the freeze using either the test file nor the URL in #3. Could you try the following?:

- Close all other tabs except the one your are going to use to reproduce the freeze with.
- Reproduce the freeze.
- In the Windows Task Manager, select the Chrome application. Right click and select "Create Dump File".

A few seconds later, you should see a dialog indicating that a dump file was created in your temp directory. Unfortunately, this file may end up being somewhat large (perhaps ~400M). But you can compress it into a .zip file which would be much smaller.

Could you make this file available to me? You can use something like Google Drive to host the file.

Thanks! And apologies for the delay.

Comment 5 by asanka@chromium.org, Feb 13 2013

Blocking: chromium:68208

Comment 6 by asanka@chromium.org, Feb 13 2013

Blocking: chromium:69298

Comment 7 by asanka@chromium.org, Feb 13 2013

Labels: Action-FeedbackNeeded

Comment 8 by Deleted ...@, Feb 13 2013

I was able to reproduce the problem (with the attached dragTest.htm).  But there are seven instances of chrome.exe in my Task Manager, when loading that single tab - no other Chrome tabs or windows are open.

Which one should I create a dump file for? All of them?

Comment 9 by asanka@chromium.org, Feb 13 2013

Look in the "Applications" tab of the Task Manager. There should be only one entry on that tab.

Ah, I think I figured it out.  I'm using Windows 8, which doesn't have an "Applications" tab in Task Manager.  There is a "simple" mode where you just see the apps (not all the processes), but in that mode there is no "Create Dump File" option when you right-click on the app.  You have to select "Group By Type" on the View menu, then you get an "Apps" listing on the Processes tab that has one entry per visible app, and a "Create Dump File" option as well.

I've shared the file with you via Google Drive, it's about 209 MB. Let me know if you have any trouble getting it.

Cc: benjhayden@chromium.org
Labels: -Action-FeedbackNeeded
Thanks Ben for the dump. Unfortunately it looks like this is in fact a hang.

The UI thread and the drag & drop thread look like this:

UI Thread:
----------

(IDataObject::GetData call marshaled and dispatched as a COM Cross apartment call)
0047cf88 72e105a4 ole32!CDragDataObject::GetData+0x22
0047efdc 733c4d85 chrome_71b30000!ui::ClipboardUtil::GetFilenames+0x51 [c:\b\build\slave\win\build\src\ui\base\clipboard\clipboard_util_win.cc @ 300]
0047f110 730063fa chrome_71b30000!WebDropData::PopulateWebDropData+0xa9 [c:\b\build\slave\win\build\src\webkit\glue\webdropdata_win.cc @ 26]
0047f148 72e0b23b chrome_71b30000!content::WebDragDest::OnDragEnter+0x74 [c:\b\build\slave\win\build\src\content\browser\web_contents\web_drag_dest_win.cc @ 136]
0047f170 768b71f5 chrome_71b30000!ui::DropTarget::DragEnter+0x4a [c:\b\build\slave\win\build\src\ui\base\dragdrop\drop_target.cc @ 52]
(Message loops below this frame)

The UI thread is waiting for the following call to complete:

[ui/base/clipboard_util_win.cc]
bool ClipboardUtil::GetFilenames(IDataObject* data_object,
                                 std::vector<string16>* filenames) {
  ...
  STGMEDIUM medium;
  if (FAILED(data_object->GetData(GetCFHDropFormat(), &medium)))   <--- Waiting here
    return false;

Drag & Drop Thread:
-------------------

(Nested message loop)
0ae2e680 72dfe2da chrome_71b30000!content::DragDownloadFile::Wait+0x19 [c:\b\build\slave\win\build\src\content\browser\download\drag_download_file.cc @ 210]
0ae2e694 76fb6134 chrome_71b30000!ui::DataObjectImpl::GetData+0xb3 [c:\b\build\slave\win\build\src\ui\base\dragdrop\os_exchange_data_provider_win.cc @ 672]
0ae2e6a8 76f7836e combase!IDataObject_GetData_Stub+0x14 [d:\win8_gdr\com\combase\proxy\proxy\call_as.c @ 1292]
0ae2e6c0 777baa26 combase!IDataObject_RemoteGetData_Thunk+0x25 [e:\obj.x86fre\com\combase\proxy\proxy\daytona\objfre\i386\mega_p.c @ 1977]
(COM cross apartment call dispatched to IDataObject::GetData)
(OLE Modal loop)
0ae2f914 73007267 ole32!DoDragDrop+0xe1
0ae2f95c 730072d3 chrome_71b30000!content::WebContentsDragWin::DoDragging+0x15c [c:\b\build\slave\win\build\src\content\browser\web_contents\web_contents_drag_win.cc @ 366]
0ae2f998 7300689c chrome_71b30000!content::WebContentsDragWin::StartBackgroundDragging+0x2a [c:\b\build\slave\win\build\src\content\browser\web_contents\web_contents_drag_win.cc @ 200]
(Message loop)

The drag & drop thread is waiting for this call to complete:

[ui/base/dragdrop/os_exchange_data_provider_win.cc]
HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) {
....
        // Now we can start the download.
        if ((*iter)->downloader.get()) {
          (*iter)->downloader->Start(this);
          if (!(*iter)->downloader->Wait()) {    <--- This is DragDownloadFile::Wait()
            is_aborting_ = true;
            return DV_E_FORMATETC;
          }
        }

The nested message loop in DragDownloadFile::Wait() is waiting for the UI thread to signal completion of the download by posting the DragDownloadFile::DownloadCompleted() task. However, the UI thread never gets around to it since it's waiting for the GetData call to complete. Deadlock.

Status: Untriaged
Cc: jianli@chromium.org

Comment 14 by Deleted ...@, Feb 19 2013

Asanka and I chatted and think that this would be solved if DropTarget spawned its own thread, freeing up the UI thread to handle the download that is started by the DragDownloadFile. DropTarget is not specific to DragDownloadFile, so it would spawn its own thread any time any drag-n-drop drops anything into chrome, which is probably good for reducing UI thread contention regardless.
I'll look for an owner for DropTarget.
Cc: dcheng@chromium.org sky@chromium.org
Scott: would you mind taking a look at comments 11 and 14 and let us know if we're on the right track, and also who might know enough about DropTarget to safely do the fix? Daniel was the last person to meaningfully change DropTarget as far as I can tell, for some value of "meaningfully".

Comment 16 by sky@chromium.org, Feb 25 2013

Cc: tony@chromium.org
Tony knows about this code too.

Remember that DropTarget needs to interact with the UI, which is not thread safe.
I'm Chrome sheriff today still, so I won't be able to take a closer look at this until tomorrow. Comment #11 looks like the appropriate diagnosis; unfortunately, without thinking about it more, I'm not sure if there will be unexpected issues with using a helper thread for DropTarget.
Project Member

Comment 18 by bugdroid1@chromium.org, Mar 10 2013

Labels: -Feature-Downloads Cr-UI-Browser-Downloads
Owner: dcheng@chromium.org
Status: Started
Cc: jam@chromium.org
I think this issue is a result of https://src.chromium.org/viewvc/chrome?revision=171898&view=revision. Before that, GetFilenames() was a no-op (though I'm surprised I never triggered the NOTREACHED assert). I think we could fix it by simply populating WebDropData on another thread, and forwarding the events to WebKit from there. Before I do that though, I want to see if the IDataObject implementation is fixable; what it's doing is arguably wrong, as it looks like it's actually initiating a download even though the drop hasn't ended.
Cc: hongbo.min@chromium.org
My analysis in comment 20 is wrong.
The reported deadlock triggers if a drag with DownloadURL is dragged over Chrome and the left mouse button is not down. There are two circumstances where this can occur:
- Race between IDataObjcet::GetData() being serviced in the DnD thread and left mouse button being released. This is probably easier to repro on a slower machine. When when you drag over Chrome, we call IDataObject::GetData(CF_HDROP) on the UI thread during dragenter. If the drag is a DownloadURL drag that originated in Chrome, then the request must be serviced on the DnD thread. If the left mouse button is seen as released by the time the DnD thread receives the request, then it will enter the special DownloadURL processing logic and start waiting on the UI thread... deadlock!
- A touch-initiated drag (enabled by https://codereview.chromium.org/14294003/) will never have the left-mouse button down and will always deadlock as well.

To fix this, I plan on writing a sentinel value to IDataObject when a DownloadURL is present (it may make sense to use CFSTR_INDRAGLOOP for this). ClipboardUtil::GetFilenames() will check for the sentinel value and avoid reading CF_HDROP if it's present.
Project Member

Comment 22 by bugdroid1@chromium.org, Apr 27 2013

------------------------------------------------------------------------
r196925 | dcheng@chromium.org | 2013-04-27T02:31:38.496099Z

Changed paths:
   M http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/web_contents/web_contents_drag_win.cc?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/ui/base/dragdrop/os_exchange_data_provider_win.cc?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/web_contents/web_drag_source_win.cc?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/ui/base/dragdrop/os_exchange_data_provider_win.h?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/content/browser/web_contents/web_drag_source_win.h?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/ui/base/dragdrop/os_exchange_data.cc?r1=196925&r2=196924&pathrev=196925
   M http://src.chromium.org/viewvc/chrome/trunk/src/ui/base/dragdrop/os_exchange_data.h?r1=196925&r2=196924&pathrev=196925

Fix deadlock between UI thread and drag and drop thread on Windows.

During a drag and drop operation, drop targets may call
IDataObject::GetData() even though the drop is not yet complete.
This is problematic for DownloadURL since calling GetData() on the
stored CF_HDROP will actually trigger the download to start. In
order to prevent this, it called GetKeyState() to check if the left
mouse button was still down.

Chrome depends on the fact that this check is reliable, as it calls
GetData(CF_HDROP) to extract filenames when something is dragged
over a WebDropTargetWin. However, this is not a reliable heuristic
since the drag and drop loop doesn't run in the UI thread when
there is a DownloadURL in the drag. If the heuristic fails, this
results in a deadlock; the UI thread blocks in its call to
GetData(CF_HDROP) while the drag and drop thread is blocked on the
UI thread waiting for the download to complete.

In order to fix this, DataObjectImpl now has a bool member to track
whether the drag and drop operation is still in progress. On a
successful drop, WebDragSourceWin indicates that the drag operation
is complete prior to returning DRAGDROP_S_DROP.

BUG= 163387 

Review URL: https://codereview.chromium.org/13979012
------------------------------------------------------------------------
dcheng: mark this bug fixed, or is there something else that needs to be done?
Status: Fixed

Sign in to add a comment