WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
41507
WebSocket: Crash caused by calling close() within onmessage handler
https://bugs.webkit.org/show_bug.cgi?id=41507
Summary
WebSocket: Crash caused by calling close() within onmessage handler
Yuta Kitamura
Reported
2010-07-01 23:01:01 PDT
If you create a WebSocket object during onclose() handler of another WebSocket object, the browser will crash. This crash may be related to
http://crbug.com/44792
.
Attachments
Fix
(8.43 KB, patch)
2010-07-01 23:16 PDT
,
Yuta Kitamura
no flags
Details
Formatted Diff
Diff
a simpler test
(733 bytes, application/x-javascript)
2010-07-07 14:09 PDT
,
Alexey Proskuryakov
no flags
Details
Fix v2 (Simplify test, add comments)
(8.66 KB, patch)
2010-07-09 02:44 PDT
,
Yuta Kitamura
no flags
Details
Formatted Diff
Diff
Fix v3 (Improve comments as per Alexey's suggestion)
(8.79 KB, patch)
2010-07-12 06:41 PDT
,
Yuta Kitamura
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Yuta Kitamura
Comment 1
2010-07-01 23:16:13 PDT
Created
attachment 60341
[details]
Fix
Fumitoshi Ukai
Comment 2
2010-07-02 00:35:41 PDT
Comment on
attachment 60341
[details]
Fix LGTM
Alexey Proskuryakov
Comment 3
2010-07-02 10:29:58 PDT
Comment on
attachment 60341
[details]
Fix The code change looks reasonable, but there are some logical steps missing from the explanation. Why does creating a WebSocket object during onclose() handler of another WebSocket object cause this crash? They have separate channels and bridges. + while (m_workerContext && clientWrapper && !clientWrapper->syncMethodDone() && result != MessageQueueTerminated) { + result = runLoop.runInMode(m_workerContext.get(), m_taskMode); // May dereference this bridge and m_workerContext. clientWrapper = m_workerClientWrapper.get(); } What is the exact mechanism that dereferences worker context while waiting here? Is this part of the change covered by the test?
Yuta Kitamura
Comment 4
2010-07-06 22:52:00 PDT
(In reply to
comment #3
)
> (From update of
attachment 60341
[details]
) > The code change looks reasonable, but there are some logical steps missing from the explanation. Why does creating a WebSocket object during onclose() handler of another WebSocket object cause this crash? They have separate channels and bridges. > > + while (m_workerContext && clientWrapper && !clientWrapper->syncMethodDone() && result != MessageQueueTerminated) { > + result = runLoop.runInMode(m_workerContext.get(), m_taskMode); // May dereference this bridge and m_workerContext. > clientWrapper = m_workerClientWrapper.get(); > } > > What is the exact mechanism that dereferences worker context while waiting here? Is this part of the change covered by the test?
I found the test case first, and then looked into the failure. So I'm not sure about the exact mechanism of why this test causes the failure, but it is 100% reproducible with this test. The source of the failure is that calling WorkerRunLoop::runInMode() may call WebSocket::didClose() (which frees everything). The stack trace is like the following: WebSocket::close() is called (in ws1.close()) -> WorkerThreadableWebSocketChannel::bufferedAmount() -> WorkerThreadableWebSocketChannel::Bridge::bufferedAmount() -> WorkerThreadableWebSocketChannel::Bridge::waitForMethodCompletion() -> WorkerRunLoop::runInMode() -> ... -> workerContextDidClose() -> ThreadableWebSocketChannelClientWrapper::didClose() -> ThreadableWebSocketChannelClientWrapper::processPendingEvents() -> WebSocket::didClose() This causes the channel and other things to get closed, while WebSocket::close() does not think such thing should happen.
> + result = runLoop.runInMode(m_workerContext.get(), m_taskMode); // May dereference this bridge and m_workerContext.
This comment was a bit inaccurate. Since m_workerContext may become null in Bridge::disconnect(), the comment should be "May causes the bridge to be disconnected, which makes m_workerContext become null." I will update the comment in a new patch.
Alexey Proskuryakov
Comment 5
2010-07-07 14:09:45 PDT
Created
attachment 60776
[details]
a simpler test I'll need to think about this patch more deeply, we may be violating some more general ownership rules here. It's awesome that we have a reproducible test case!
> m_bufferedAmountAfterClose = m_channel->bufferedAmount(); // May dereference m_channel. > if (m_channel) > m_channel->close();
This comment at least is wrong - we don't care about m_channel being dereferenced - all we care about to make this call is m_channel being non-null. WebSocket holds its own reference to channel. I have a simpler reproducible case, one that doesn't even need to create another WebSocket. It crashes in several different places.
Alexey Proskuryakov
Comment 6
2010-07-07 17:16:33 PDT
Comment on
attachment 60341
[details]
Fix The title of the bug isn't great - there are multiple crash locations being fixed, not just waitForMethodCompletion(). And this isn't about creating a WebSocket object from onclose(), as the original description said. I think that this patch is fine, and just needs better comments.
Yuta Kitamura
Comment 7
2010-07-09 02:44:40 PDT
Created
attachment 61023
[details]
Fix v2 (Simplify test, add comments)
Yuta Kitamura
Comment 8
2010-07-09 02:47:42 PDT
Apologies for delay in response. In the new patch, I tried to: - Add more comments and clarify the situation. - Simplify the test according to Alexey's proposal. Could you take another look?
Alexey Proskuryakov
Comment 9
2010-07-09 10:23:30 PDT
Comment on
attachment 61023
[details]
Fix v2 (Simplify test, add comments) + m_bufferedAmountAfterClose = m_channel->bufferedAmount(); // May dereference m_channel. This comment is still misleading, we don't care about it being dereferenced. WebSocket holds its own reference to m_channel. I thin that the real explanation is that a didClose notification may be already queued, which we will inadvertently process while waiting for bufferedAmount() to return.
Yuta Kitamura
Comment 10
2010-07-12 06:41:46 PDT
Created
attachment 61222
[details]
Fix v3 (Improve comments as per Alexey's suggestion)
WebKit Commit Bot
Comment 11
2010-07-12 19:42:50 PDT
Comment on
attachment 61222
[details]
Fix v3 (Improve comments as per Alexey's suggestion) Clearing flags on attachment: 61222 Committed
r63159
: <
http://trac.webkit.org/changeset/63159
>
WebKit Commit Bot
Comment 12
2010-07-12 19:42:54 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug