Updates:
        Cc: [email protected] [email protected]

Comment #13 on issue 27510 by [email protected]: Chrome crashes during  
reload a page with Flash Player crashed object
http://code.google.com/p/chromium/issues/detail?id=27510

I was investigating bug 26754 and took a detour over to this bug because it  
seems
like a similar IPC problem, and because I can reproduce this one.

Being able to reproduce it means that I can diagnose it and learn fun  
things about
our IPC system at the same time!

This bug is caused by a thread race conflicting with the lifetime of the  
transport DIB.

The problem we're seeing is EBADF from sendmsg while the renderer process is
trying to send to the plugin process.  The bad file descriptor isn't the  
pipe's
descriptor, it's the descriptor that the renderer is trying to send.  EBADF  
occurs with
this stack on the IPC thread:

#0  IPC::Channel::ChannelImpl::ProcessOutgoingMessages (this=0x89d000) at
/chrome/trunk/src/ipc/ipc_channel_posix.cc:828
#1  0x0767eea3 in IPC::Channel::ChannelImpl::Send (this=0x89d000,
message=0x21b0eed0) at /chrome/trunk/src/ipc/ipc_channel_posix.cc:879
#2  0x0767eedf in IPC::Channel::Send (this=0x1b6930, message=0x21b0eed0) at
/chrome/trunk/src/ipc/ipc_channel_posix.cc:1024
#3  0x07682015 in IPC::ChannelProxy::Context::OnSendMessage (this=0x1b6e50,
message=0x21b0eed0) at /chrome/trunk/src/ipc/ipc_channel_proxy.cc:156
#4  0x07683857 in IPC::SendTask::Run (this=0x12ae30) at
/chrome/trunk/src/ipc/ipc_channel_proxy.cc:25
(trimmed)

Here's where the offending SendTask is born, on the renderer thread, where  
it is
posted to the IPC thread's message loop:

#0  IPC::ChannelProxy::Send (this=0x1ba470, message=0x21a24730) at
/chrome/trunk/src/ipc/ipc_channel_proxy.cc:276
#1  0x0768b82a in IPC::SyncChannel::SendWithTimeout (this=0x1ba470,
message=0x21a24730, timeout_ms=-1) at
/chrome/trunk/src/ipc/ipc_sync_channel.cc:381
#2  0x0768a835 in IPC::SyncChannel::Send (this=0x1ba470, message=0x21a24730)
at /chrome/trunk/src/ipc/ipc_sync_channel.cc:376
#3  0x082fbe5e in PluginChannelBase::Send (this=0x1ba700,
message=0x21a24730) at
/chrome/trunk/src/chrome/plugin/plugin_channel_base.cc:117
#4  0x06f8f38c in WebPluginDelegateProxy::Send (this=0x21a1e600,
msg=0x21a24730) at
/chrome/trunk/src/chrome/renderer/webplugin_delegate_proxy.cc:304
#5  0x06f91ea9 in WebPluginDelegateProxy::UpdateGeometry (this=0x21a1e600,
window_re...@0x21a1c1a4, clip_re...@0x21a1c1b4) at
/chrome/trunk/src/chrome/renderer/webplugin_delegate_proxy.cc:463
#6  0x081ffea5 in webkit_glue::WebPluginImpl::updateGeometry  
(this=0x21a1c110,
window_re...@0xbfffc7b0, clip_re...@0xbfffc7a0, cutout_rec...@0xbfffc798,
is_visible=true) at /chrome/trunk/src/webkit/glue/webplugin_impl.cc:272
#7  0x0783f32a in WebKit::WebPluginContainerImpl::reportGeometry
(this=0x21a1e090) at
/chrome/trunk/src/third_party/WebKit/WebKit/chromium/src/WebPluginContainerI
mpl.cpp:221
(trimmed)

Frame 5, WebPluginDelegateProxy::UpdateGeometry, is crucial.  The "bad" file
descriptor is placed into the message as param.windowless_buffer.fd, which  
comes
from the WebPluginDelegateProxy's transport_store_->handle().fd.  The  
transport
store (TransportDIB)'s file descriptor is good at the point that it's  
inserted into the
message.

Earlier in WebPluginDelegateProxy::UpdateGeometry, windowless_buffer_ may be
destroyed (and replaced).  That happens on this renderer thread stack:

#0  base::SharedMemory::Close (this=0x21a39660) at
/chrome/trunk/src/base/shared_memory_posix.cc:287
#1  0x07017d4b in base::SharedMemory::~SharedMemory (this=0x21a39660) at
/chrome/trunk/src/base/shared_memory_posix.cc:64
#2  0x069770d1 in TransportDIB::~TransportDIB (this=0x21a39660) at
/chrome/trunk/src/chrome/common/transport_dib_mac.cc:24
#3  0x0830d143 in scoped_ptr<TransportDIB>::reset (this=0x21a25208, p=0x0)  
at
scoped_ptr.h:81
#4  0x06f91844 in WebPluginDelegateProxy::ResetWindowlessBitmaps
(this=0x21a25190) at
/chrome/trunk/src/chrome/renderer/webplugin_delegate_proxy.cc:484
#5  0x06f91a15 in WebPluginDelegateProxy::UpdateGeometry (this=0x21a25190,
window_re...@0x21a14824, clip_re...@0x21a14834) at
/chrome/trunk/src/chrome/renderer/webplugin_delegate_proxy.cc:413
(trimmed)

When the base::SharedMemory is closed (for replacement or otherwise), its  
associated
file descriptor is closed.

This results in a race: if we enter WebPluginDelegateProxy::UpdateGeometry a
subsequent time while the IPC::SendTask from an earlier call is still  
pending, it's
possible to close the file descriptor that the pending task is still  
carrying.

In most cases, WebPluginDelegateProxy::UpdateGeometry will simply replace  
the
base::SharedMemory object with a new one that will wind up with the same  
file
descriptor as the old one.  However, it's possible for a different file  
descriptor to be
assigned.  It's also possible that the IPC thread will run the  
IPC::SendTask and wind
up in IPC::Channel::ChannelImpl::ProcessOutgoingMessages after the renderer
thread's WebPluginDelegateProxy::UpdateGeometry has closed the old file  
descriptor
but before it's opened the new one.

Kaboom.  There's your race.  The IPC channel goes dead, even though the  
plugin
process doesn't crash.  You get a sad plug-in.

Now reload the page.  Because of some sick twist,  
IPC::Channel::ChannelImpl::ProcessOutgoingMessages  
(ipc/ipc_channel_posix.cc)
doesn't close down the channel when an unexpected send error occurs, like  
EBADF.
Hit reload and the renderer process will attempt to reestablish IPC with  
the plugin
process using the same channel name.  It'll find the existing IPC pipe file  
descriptor
in its map (because it was never closed) and try to recycle it.  Treating  
the kinda-
sorta half-open channel as a brand new pipe in some ways, we'll go through  
the
"hello" message handshake thing and fire off all of the usual  
OnChannelConnected
callbacks, which starts upsetting parts of the program that are aware  
(either directly
or as a side effect) that the channel once was connected and really  
shouldn't be
going through that bring-up all over again.

Kaboom.  There's your crash.

--
You received this message because you are listed in the owner
or CC fields of this issue, or because you starred this issue.
You may adjust your issue notification preferences at:
http://code.google.com/hosting/settings

-- 
Automated mail from issue updates at http://crbug.com/
Subscription options: http://groups.google.com/group/chromium-bugs

Reply via email to