diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:45:50 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 21:45:50 +0000 |
commit | 87339f0bdb7fa60bad0616348a6a2aa705d4716a (patch) | |
tree | 9e2eae044d261554c1fc53c8d5d303d8ae94f9db | |
parent | 1573dea0f088e514aacff7cdd706f18ec688b0dd (diff) | |
download | chromium_src-87339f0bdb7fa60bad0616348a6a2aa705d4716a.zip chromium_src-87339f0bdb7fa60bad0616348a6a2aa705d4716a.tar.gz chromium_src-87339f0bdb7fa60bad0616348a6a2aa705d4716a.tar.bz2 |
Fix a chrome browser crash observed in chrome frame reliability test runs. The crash occurs
when the automation channel is being torn down and a Send on the channel is attempted after
the channel has been closed.
We crash while dereferencing a NULL channel pointer in OnSendMessage task.
Fix is to add a check for the same.
Fixes bug http://code.google.com/p/chromium/issues/detail?can=2&q=54115
Bug=54115
Test=Covered by new ipc sync channel test.
Review URL: http://codereview.chromium.org/3337004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58408 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ipc/ipc_channel_proxy.cc | 5 | ||||
-rw-r--r-- | ipc/ipc_sync_channel.cc | 2 | ||||
-rw-r--r-- | ipc/ipc_sync_channel_unittest.cc | 53 |
3 files changed, 58 insertions, 2 deletions
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 6af4d73..ddf1ec8 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -155,6 +155,11 @@ void ChannelProxy::Context::OnChannelClosed() { // Called on the IPC::Channel thread void ChannelProxy::Context::OnSendMessage(Message* message) { + if (!channel_) { + delete message; + OnChannelClosed(); + return; + } if (!channel_->Send(message)) OnChannelError(); } diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc index bb0a245..8598c9c 100644 --- a/ipc/ipc_sync_channel.cc +++ b/ipc/ipc_sync_channel.cc @@ -283,7 +283,6 @@ bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) { void SyncChannel::SyncContext::Clear() { CancelPendingSends(); received_sync_msgs_->RemoveContext(this); - Context::Clear(); } @@ -320,6 +319,7 @@ void SyncChannel::SyncContext::OnChannelOpened() { } void SyncChannel::SyncContext::OnChannelClosed() { + CancelPendingSends(); shutdown_watcher_.StopWatching(); Context::OnChannelClosed(); } diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc index a3b757a..e01cc58 100644 --- a/ipc/ipc_sync_channel_unittest.cc +++ b/ipc/ipc_sync_channel_unittest.cc @@ -160,10 +160,11 @@ class Worker : public Channel::Listener, public Message::Sender { NOTREACHED(); } - private: base::Thread* ListenerThread() { return overrided_thread_ ? overrided_thread_ : &listener_thread_; } + + private: // Called on the listener thread to create the sync channel. void OnStart() { // Link ipc_thread_, listener_thread_ and channel_ altogether. @@ -1111,6 +1112,40 @@ class SyncMessageFilterServer : public Worker { scoped_refptr<TestSyncMessageFilter> filter_; }; +// This class provides functionality to test the case that a Send on the sync +// channel does not crash after the channel has been closed. +class ServerSendAfterClose : public Worker { + public: + ServerSendAfterClose() + : Worker(Channel::MODE_SERVER, "simpler_server"), + send_result_(true) { + } + + bool SendDummy() { + ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( + this, &ServerSendAfterClose::Send, new SyncChannelTestMsg_NoArgs)); + return true; + } + + bool send_result() const { + return send_result_; + } + + private: + virtual void Run() { + CloseChannel(); + Done(); + } + + bool Send(Message* msg) { + send_result_ = Worker::Send(msg); + Done(); + return send_result_; + } + + bool send_result_; +}; + } // namespace // Tests basic synchronous call @@ -1120,3 +1155,19 @@ TEST_F(IPCSyncChannelTest, SyncMessageFilter) { workers.push_back(new SimpleClient()); RunTest(workers); } + +// Test the case when the channel is closed and a Send is attempted after that. +TEST_F(IPCSyncChannelTest, SendAfterClose) { + ServerSendAfterClose server; + server.Start(); + + server.done_event()->Wait(); + server.done_event()->Reset(); + + server.SendDummy(); + server.done_event()->Wait(); + + EXPECT_FALSE(server.send_result()); +} + + |