WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
224017
Crash under GPUProcessProxy::getGPUProcessConnection()
https://bugs.webkit.org/show_bug.cgi?id=224017
Summary
Crash under GPUProcessProxy::getGPUProcessConnection()
Said Abou-Hallawa
Reported
2021-03-31 14:12:51 PDT
The completion handler of some messages may reference members of GPUProcessProxy or WebProcessPool even though they may be already destroyed. A crash tracer may look like this: WebKit: WebKit::GPUProcessProxy::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&) <== WebKit: WTF::Detail::CallableWrapper<WebKit::WebProcessPool::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&)::$_15, void, WebKit::GPUProcessConnectionInfo const&>::call(WebKit::GPUProcessConnectionInfo const&) WebKit: WTF::Detail::CallableWrapper<WebKit::WebProcessPool::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&)::$_15, void, WebKit::GPUProcessConnectionInfo const&>::call(WebKit::GPUProcessConnectionInfo const&) WebKit: WTF::Detail::CallableWrapper<WebKit::GPUProcessProxy::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&)::$_3, void, WTF::Optional<IPC::Attachment>&&>::call(WTF::Optional<IPC::Attachment>&&) WebKit: WTF::Detail::CallableWrapper<unsigned long long WebKit::AuxiliaryProcessProxy::sendWithAsyncReply<Messages::GPUProcess::CreateGPUConnectionToWebProcess, WebKit::GPUProcessProxy::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&)::$_3>(Messages::GPUProcess::CreateGPUConnectionToWebProcess&&, WebKit::GPUProcessProxy::getGPUProcessConnection(WebKit::WebProcessProxy&, WTF::CompletionHandler<void (WebKit::GPUProcessConnectionInfo const&)>&&)::$_3&&, unsigned long long, WTF::OptionSet<IPC::SendOption>, WebKit::AuxiliaryProcessProxy::ShouldStartProcessThrottlerActivity)::'lambda'(IPC::Decoder*), void, IPC::Decoder*>::call(IPC::Decoder*) WebKit: WTF::Detail::CallableWrapper<WebKit::AuxiliaryProcessProxy::sendMessage(std::__1::unique_ptr<IPC::Encoder, std::__1::default_delete<IPC::Encoder> >, WTF::OptionSet<IPC::SendOption>, WTF::Optional<std::__1::pair<WTF::CompletionHandler<void (IPC::Decoder*)>, unsigned long long> >&&, WebKit::AuxiliaryProcessProxy::ShouldStartProcessThrottlerActivity)::$_0, void, IPC::Decoder*>::call(IPC::Decoder*) WebKit: WebKit::AuxiliaryProcessProxy::~AuxiliaryProcessProxy() WebKit: WTF::RefCounted<WebKit::GPUProcessProxy, std::__1::default_delete<WebKit::GPUProcessProxy> >::deref() const WebKit: WebKit::WebProcessPool::~WebProcessPool() WebKit: -[WKProcessPool dealloc] WebKit: WebKit::WebProcessProxy::~WebProcessProxy() WebKit: WebKit::WebProcessProxy::~WebProcessProxy() WebKit: WTF::Detail::CallableWrapper<WebKit::WebPageProxy::close()::$_6, void>::~CallableWrapper() JavaScriptCore: WTF::RunLoop::performWork() JavaScriptCore: WTF::RunLoop::performWork(void*) GPUProcessProxy is being called although its destruction has already begun since we are inside AuxiliaryProcessProxy::~AuxiliaryProcessProxy(). This means we can't deal with this object as a super class of AuxiliaryProcessProxy anymore.
Attachments
Patch
(5.09 KB, patch)
2021-03-31 15:00 PDT
,
Said Abou-Hallawa
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(4.01 KB, patch)
2021-03-31 18:46 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(2.66 KB, patch)
2021-04-27 16:14 PDT
,
Said Abou-Hallawa
no flags
Details
Formatted Diff
Diff
Patch
(3.41 KB, patch)
2021-04-27 17:12 PDT
,
Chris Dumez
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(4.00 KB, patch)
2021-04-27 18:37 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(4.56 KB, patch)
2021-04-27 19:11 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(3.70 KB, patch)
2021-04-27 20:07 PDT
,
Chris Dumez
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(3.83 KB, patch)
2021-04-27 20:20 PDT
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Show Obsolete
(7)
View All
Add attachment
proposed patch, testcase, etc.
Said Abou-Hallawa
Comment 1
2021-03-31 14:35:53 PDT
<
rdar://75146104
>
Said Abou-Hallawa
Comment 2
2021-03-31 15:00:34 PDT
Created
attachment 424823
[details]
Patch
Said Abou-Hallawa
Comment 3
2021-03-31 18:21:24 PDT
Comment on
attachment 424823
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=424823&action=review
> Source/WebKit/UIProcess/WebProcessPool.cpp:365 > + if (m_gpuProcess) > + m_gpuProcess->shutDownProcess();
I was wrong about this change. The life cycle of m_gpuProcess is different from the WebProcesses which are owned by the WebProcessPool. I made this assertion in this code #if ENABLE(GPU_PROCESS) if (m_gpuProcess) { ASSERT(m_gpuProcess->hasOneRef()); m_gpuProcess->shutDownProcess(); } #endif And I ran the canvas layout tests and this assertion fires multiple times. I think the assertion fires because there is a singleton GPU Process for all the WebProcesses. If there are multiple WebProcessPools, i.e. WebProcessPool::allProcessPools() has more than one item, m_gpuProcess will only be destroyed when the last WebProcessPool is destroyed.
Said Abou-Hallawa
Comment 4
2021-03-31 18:46:11 PDT
Created
attachment 424859
[details]
Patch
EWS
Comment 5
2021-04-01 02:04:19 PDT
Committed
r275349
: <
https://commits.webkit.org/r275349
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 424859
[details]
.
Said Abou-Hallawa
Comment 6
2021-04-27 15:53:27 PDT
r275349
does not guarantee all the pending messages of GPUProcessProxy will be processed before starting the deletion of WebProcessPool. Some messages may be processed inside the AuxiliaryProcessProxy destructor.
Said Abou-Hallawa
Comment 7
2021-04-27 15:54:07 PDT
<
rdar://76794645
>
Said Abou-Hallawa
Comment 8
2021-04-27 16:14:20 PDT
Created
attachment 427210
[details]
Patch
Chris Dumez
Comment 9
2021-04-27 16:21:11 PDT
Comment on
attachment 427210
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=427210&action=review
> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:199 > + replyToPendingMessages();
~AuxiliaryProcessProxy() already does that. So why does ~GPUProcessProxy() need to do it too?
> Source/WebKit/UIProcess/WebProcessPool.cpp:364 > + // Force calling the destrsuctor of GPUProcessProxy to ensure the completion
typo: destrsuctor
Chris Dumez
Comment 10
2021-04-27 16:22:40 PDT
Comment on
attachment 427210
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=427210&action=review
> Source/WebKit/UIProcess/WebProcessPool.cpp:366 > + m_gpuProcess = nullptr;
Note that this does not necessarily destroy the GPUProcessProxy since a single GPUProcessProxy may be shared by several WebProcessPool objects.
Chris Dumez
Comment 11
2021-04-27 16:30:05 PDT
Comment on
attachment 427210
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=427210&action=review
> Source/WebKit/UIProcess/WebProcessPool.cpp:-364 > - if (m_gpuProcess)
Note that this previous code was wrong too since a GPUProcessProxy can be shared by several process pool. Having a single WebProcessPool getting destroyed should not cause pending messages from other process pool to get replied to eagerly.
Said Abou-Hallawa
Comment 12
2021-04-27 16:31:56 PDT
Comment on
attachment 427210
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=427210&action=review
>> Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp:199 >> + replyToPendingMessages(); > > ~AuxiliaryProcessProxy() already does that. So why does ~GPUProcessProxy() need to do it too?
See the completion handler in GPUProcessProxy::getGPUProcessConnection(). We capture this as a WeakPtr and if we reply the pending messages from ~AuxiliaryProcessProxy(), GPUProcessProxy will be invalid and a call like this->connection() will crash.
>> Source/WebKit/UIProcess/WebProcessPool.cpp:366 >> + m_gpuProcess = nullptr; > > Note that this does not necessarily destroy the GPUProcessProxy since a single GPUProcessProxy may be shared by several WebProcessPool objects.
So this may not be needed then.
Chris Dumez
Comment 13
2021-04-27 16:45:42 PDT
Comment on
attachment 427210
[details]
Patch I think the safest fix here is to protect the WebProcessPool in the lambda in WebProcessPool::getGPUProcessConnection(), instead of using a WeakPtr.
Chris Dumez
Comment 14
2021-04-27 17:12:48 PDT
Created
attachment 427217
[details]
Patch
Chris Dumez
Comment 15
2021-04-27 18:37:14 PDT
Created
attachment 427225
[details]
Patch
Chris Dumez
Comment 16
2021-04-27 19:11:26 PDT
Created
attachment 427227
[details]
Patch
Chris Dumez
Comment 17
2021-04-27 20:07:41 PDT
Created
attachment 427231
[details]
Patch
Chris Dumez
Comment 18
2021-04-27 20:20:42 PDT
Created
attachment 427232
[details]
Patch
EWS
Comment 19
2021-04-28 08:20:57 PDT
Committed
r276712
(
237117@main
): <
https://commits.webkit.org/237117@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 427232
[details]
.
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