Bug 224309

Summary: [WPE] Segfault on atexit handler when loading webkit://gpu
Product: WebKit Reporter: Adrian Perez <aperez>
Component: WPE WebKitAssignee: Claudio Saavedra <csaavedra>
Status: RESOLVED FIXED    
Severity: Normal CC: bugs-noreply, cgarcia, csaavedra, mcatanzaro
Priority: P2    
Version: WebKit Local Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=217655
Attachments:
Description Flags
Patch cgarcia: review+

Description Adrian Perez 2021-04-07 15:31:41 PDT
Steps to reproduce:

 1. Run: cog -P fdo webkit://gpu
 2. Press Ctrl-W to close Cog (or run “cogctl quit”)

Backtrace:

  (gdb) bt
  #0  0x00007ffff2dbf744 in wpe_renderer_backend_egl_destroy () at /usr/lib/libwpe-1.0.so.1
  #1  0x00007ffff544629c in  () at /usr/lib/libWPEWebKit-1.0.so.4
  #2  0x00007ffff54462ba in  () at /usr/lib/libWPEWebKit-1.0.so.4
  #3  0x00007ffff2c2b697 in __run_exit_handlers () at /usr/lib/libc.so.6
  #4  0x00007ffff2c2b83e in  () at /usr/lib/libc.so.6
  #5  0x00007ffff2c13b2c in __libc_start_main () at /usr/lib/libc.so.6
  #6  0x000055555555654e in _start ()
  (gdb)

While I could try and get a backtrace from a build with debug symbols, it won't
add much more. I can see with GDB that wpe_renderer_backend_egl_create() gets called
and returns something sensible, but then wpe_renderer_backend_egl_destroy() ends up
receiving a null pointer 🤷️

This issue can be reproduced with current ToT of WPE WebKit, libwpe and WPEBackend-fdo;
but also with the most recent releases.
Comment 1 Adrian Perez 2021-04-07 15:33:51 PDT
Interestingly enough, opening https://duckduckgo.com or anything
else over HTTP does not trigger this issue.
Comment 2 Adrian Perez 2021-04-07 15:36:54 PDT
(In reply to Adrian Perez from comment #1)
> Interestingly enough, opening https://duckduckgo.com or anything
> else over HTTP does not trigger this issue.

…which makes me wonder whether in the HTTP(s) case the atexit handlers
maybe are not even being run, which would make this related to bug #217655
Comment 3 Adrian Perez 2021-04-08 15:15:29 PDT
Traceback with a build that has symbols:

% lldb -- cog -P fdo webkit://gpu”
...
Process 685007 stopped
* thread #1, name = 'cog', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x00007ffff3e4caa6 libwpe-1.0.so.1`::wpe_renderer_backend_egl_destroy(backend=0x0000000000000000) at renderer-backend-egl.c:58:28
   55   {
   56       fprintf(stderr, "** %s <- %p\n", __func__, backend);
   57  
-> 58       backend->base.interface->destroy(backend->base.interface_data);
   59       backend->base.interface_data = 0;
   60  
   61       free(backend);
(lldb) bt
* thread #1, name = 'cog', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
  * frame #0: 0x00007ffff3e4caa6 libwpe-1.0.so.1`::wpe_renderer_backend_egl_destroy(backend=0x0000000000000000) at renderer-backend-egl.c:58:28
    frame #1: 0x00007ffff59b6bcb libWPEWebKit-1.0.so.3`WebCore::PlatformDisplayLibWPE::~PlatformDisplayLibWPE() [inlined] WebCore::PlatformDisplayLibWPE::~PlatformDisplayLibWPE(this=0x00007fffef6f7240) at PlatformDisplayLibWPE.cpp:71:5
    frame #2: 0x00007ffff59b6bb4 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplayLibWPE::~PlatformDisplayLibWPE(this=0x00007fffef6f7240) at PlatformDisplayLibWPE.cpp:70
    frame #3: 0x00007ffff597cf52 libWPEWebKit-1.0.so.3`std::unique_ptr<WebCore::PlatformDisplay, std::default_delete<WebCore::PlatformDisplay> >::~unique_ptr() [inlined] std::default_delete<WebCore::PlatformDisplay>::operator(this=<unavailable>, __ptr=<unavailable>)(WebCore::PlatformDisplay*) const at unique_ptr.h:85:2
    frame #4: 0x00007ffff597cf4c libWPEWebKit-1.0.so.3`std::unique_ptr<WebCore::PlatformDisplay, std::default_delete<WebCore::PlatformDisplay> >::~unique_ptr(this=0x00007ffff7f5e300) at unique_ptr.h:361
    frame #5: 0x00007ffff38ce697 libc.so.6`__run_exit_handlers + 247
    frame #6: 0x00007ffff38ce83e libc.so.6`exit + 30
    frame #7: 0x00007ffff38b6b2c libc.so.6`__libc_start_main + 220
    frame #8: 0x000055555555765e cog`_start + 46
(lldb)
Comment 4 Adrian Perez 2021-04-08 15:20:53 PDT
Okay, an observation: The backtrace above is from the UIProcess, which
I am quite sure it is NOT expected to instantiate PlatformDisplayLibWPE.
This may explain why wpe_renderer_backend_egl_create() is never called
in the UIProcess (which is good) but somehow the display object is created
and when the atexit handlers run of course they try to destroy an instance
that is not all valid.

Running “cog -P fdo http://wpewebkit.org” indeed does not instantiate
a display object in the UIProcess.
Comment 5 Adrian Perez 2021-04-08 15:29:03 PDT
Here's the traceback following up to the of PlatformDisplayLibWPE
in the *UIProcess* when running “cog -P fdo webkit://gpu”:

Process 686494 stopped
* thread #1, name = 'cog', stop reason = breakpoint 3.2
    frame #0: 0x00007ffff59b6b34 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplayLibWPE::create() [inlined] WebCore::PlatformDisplayLibWPE::PlatformDisplayLibWPE(this=0x00007fffef6f7240) at PlatformDisplayLibWPE.cpp:62:7
   59   }
   60  
   61   PlatformDisplayLibWPE::PlatformDisplayLibWPE()
-> 62       : PlatformDisplay(NativeDisplayOwned::No)
   63   {
   64   #if PLATFORM(GTK)
   65       PlatformDisplay::setSharedDisplayForCompositing(*this);
(lldb) bt
* thread #1, name = 'cog', stop reason = breakpoint 3.2
  * frame #0: 0x00007ffff59b6b34 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplayLibWPE::create() [inlined] WebCore::PlatformDisplayLibWPE::PlatformDisplayLibWPE(this=0x00007fffef6f7240) at PlatformDisplayLibWPE.cpp:62:7
    frame #1: 0x00007ffff59b6b34 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplayLibWPE::create() at PlatformDisplayLibWPE.cpp:58
    frame #2: 0x00007ffff597aadc libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] WebCore::PlatformDisplay::createPlatformDisplay() at PlatformDisplay.cpp:123:12
    frame #3: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] WebCore::PlatformDisplay::sharedDisplay(this=<unavailable>)::$_0::operator()() const at PlatformDisplay.cpp:143
    frame #4: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] void std::__invoke_impl<void, WebCore::PlatformDisplay::sharedDisplay()::$_0>(__f=<unavailable>)::$_0&&) at invoke.h:60
    frame #5: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] std::__invoke_result<WebCore::PlatformDisplay::sharedDisplay()::$_0>::type std::__invoke<WebCore::PlatformDisplay::sharedDisplay(__fn=<unavailable>)::$_0>(WebCore::PlatformDisplay::sharedDisplay()::$_0&&) at invoke.h:95
    frame #6: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(this=<unavailable>)::$_0&&)::'lambda'()::operator()() const at mutex:717
    frame #7: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() [inlined] void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(this=<unavailable>)::$_0&&)::'lambda0'()::operator()() const at mutex:722
    frame #8: 0x00007ffff597aad7 libWPEWebKit-1.0.so.3`void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(std::once_flag&, WebCore::PlatformDisplay::sharedDisplay()::$_0&&)::'lambda0'()::__invoke() at mutex:722
    frame #9: 0x00007ffff13bfc9f libpthread.so.0`__pthread_once_slow + 191
    frame #10: 0x00007ffff5974136 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplay::sharedDisplay() [inlined] __gthread_once(__func=<unavailable>)()) at gthr-default.h:700:12
    frame #11: 0x00007ffff5974119 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplay::sharedDisplay() [inlined] void std::call_once<WebCore::PlatformDisplay::sharedDisplay()::$_0>(__once=<unavailable>, __f=0x00007fffffffc258)::$_0&&) at mutex:729
    frame #12: 0x00007ffff59740e2 libWPEWebKit-1.0.so.3`WebCore::PlatformDisplay::sharedDisplay() at PlatformDisplay.cpp:142
    frame #13: 0x00007ffff59741d3 libWPEWebKit-1.0.so.3`WebCore::GLContext::createOffscreenContext(platformDisplay=<unavailable>) at GLContext.cpp:105:75
    frame #14: 0x00007ffff4852e92 libWPEWebKit-1.0.so.3`WebKit::WebKitProtocolHandler::handleGPU(this=<unavailable>, request=0x00005555557dada0) at WebKitProtocolHandler.cpp:366:22
    frame #15: 0x00007ffff4852b52 libWPEWebKit-1.0.so.3`WebKit::WebKitProtocolHandler::handleRequest(this=<unavailable>, request=0x00005555557dada0) at WebKitProtocolHandler.cpp:93:9
    frame #16: 0x00007ffff4868f31 libWPEWebKit-1.0.so.3`WebKitURISchemeHandler::platformStartTask(this=0x00007fffef6e3000, page=<unavailable>, task=0x00007fffef6ceb40) at WebKitWebContext.cpp:170:9
    frame #17: 0x00007ffff47fa8e9 libWPEWebKit-1.0.so.3`WebKit::WebURLSchemeHandler::startTask(this=0x00007fffef6e3000, page=0x00007fffaf2f3000, process=0x00007fffaf4fc340, webPageID=<unavailable>, parameters=0x00007fffffffcc70, completionHandler=0x00007fffffffc620)>&&) at WebURLSchemeHandler.cpp:62:5
    frame #18: 0x00007ffff47c33b8 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::startURLSchemeTaskShared(this=<unavailable>, process=0x00007fffffffc658, webPageID=<unavailable>, parameters=<unavailable>) at WebPageProxy.cpp:9579:22
    frame #19: 0x00007ffff47c3234 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::startURLSchemeTask(this=<unavailable>, parameters=<unavailable>) at WebPageProxy.cpp:9570:5
    frame #20: 0x00007ffff45093d5 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) [inlined] void IPC::callMemberFunctionImpl<WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WebKit::URLSchemeTaskParameters&&), std::tuple<WebKit::URLSchemeTaskParameters>, 0ul>(object=0x00007fffaf2f3000, function=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, args=0x00007fffffffcc70)(WebKit::URLSchemeTaskParameters&&), std::tuple<WebKit::URLSchemeTaskParameters>&&, std::integer_sequence<unsigned long, 0ul>) at HandleMessage.h:43:5
    frame #21: 0x00007ffff45093c5 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) [inlined] void IPC::callMemberFunction<WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WebKit::URLSchemeTaskParameters&&), std::tuple<WebKit::URLSchemeTaskParameters>, std::integer_sequence<unsigned long, 0ul> >(args=0x00007fffffffcc70, object=0x00007fffaf2f3000, function=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)(WebKit::URLSchemeTaskParameters&&)) at HandleMessage.h:49
    frame #22: 0x00007ffff45093c5 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) [inlined] void IPC::handleMessage<Messages::WebPageProxy::StartURLSchemeTask, WebKit::WebPageProxy, void (WebKit::WebPageProxy::*)(WebKit::URLSchemeTaskParameters&&)>(decoder=0x00007fffef6d1480, object=0x00007fffaf2f3000, function=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)(WebKit::URLSchemeTaskParameters&&)) at HandleMessage.h:121
    frame #23: 0x00007ffff4509397 libWPEWebKit-1.0.so.3`WebKit::WebPageProxy::didReceiveMessage(this=0x00007fffaf2f3000, connection=0x00007fffef6cd168, decoder=0x00007fffef6d1480) at WebPageProxyMessageReceiver.cpp:1602
    frame #24: 0x00007ffff47103a8 libWPEWebKit-1.0.so.3`IPC::MessageReceiverMap::dispatchMessage(this=<unavailable>, connection=0x00007fffef6cd168, decoder=0x00007fffef6d1480) at MessageReceiverMap.cpp:0
    frame #25: 0x00007ffff47f538a libWPEWebKit-1.0.so.3`non-virtual thunk to WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) [inlined] WebKit::WebProcessProxy::didReceiveMessage(this=0x00007fffaf4fc340, connection=0x00007fffef6cd168, decoder=0x00007fffef6d1480) at WebProcessProxy.cpp:819:9
    frame #26: 0x00007ffff47f5382 libWPEWebKit-1.0.so.3`non-virtual thunk to WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) at WebProcessProxy.cpp:0
    frame #27: 0x00007ffff470951e libWPEWebKit-1.0.so.3`IPC::Connection::dispatchMessage(this=<unavailable>, decoder=0x00007fffef6d1480) at Connection.cpp:1020:14
    frame #28: 0x00007ffff470981d libWPEWebKit-1.0.so.3`IPC::Connection::dispatchMessage(this=0x00007fffef6cd168, message=0x7fffef6d1480) at Connection.cpp:1065:9
    frame #29: 0x00007ffff4708bce libWPEWebKit-1.0.so.3`IPC::Connection::dispatchIncomingMessages(this=0x00007fffef6cd168) at Connection.cpp:1169:5
    frame #30: 0x00007ffff70fb3d0 libWPEWebKit-1.0.so.3`WTF::RunLoop::performWork() [inlined] WTF::Function<void ()>::operator(this=<unavailable>)() const at Function.h:83:35
    frame #31: 0x00007ffff70fb3c7 libWPEWebKit-1.0.so.3`WTF::RunLoop::performWork(this=0x00007fffef6f9000) at RunLoop.cpp:133
    frame #32: 0x00007ffff71593e6 libWPEWebKit-1.0.so.3`WTF::RunLoop::RunLoop()::$_1::__invoke(void*) [inlined] WTF::RunLoop::RunLoop(this=<unavailable>, userData=<unavailable>)::$_1::operator()(void*) const at RunLoopGLib.cpp:80:42
    frame #33: 0x00007ffff71593e1 libWPEWebKit-1.0.so.3`WTF::RunLoop::RunLoop(userData=0x00007fffef6f9000)::$_1::__invoke(void*) at RunLoopGLib.cpp:79
    frame #34: 0x00007ffff715885a libWPEWebKit-1.0.so.3`WTF::RunLoop::$_0::__invoke(_GSource*, int (*)(void*), void*) [inlined] WTF::RunLoop::$_0::operator(this=<unavailable>, source=0x0000555555589460, callback=(libWPEWebKit-1.0.so.3`WTF::RunLoop::RunLoop()::$_1::__invoke(void*) at RunLoopGLib.cpp:79), userData=0x00007fffef6f9000)(_GSource*, int (*)(void*), void*) const at RunLoopGLib.cpp:53:28
    frame #35: 0x00007ffff7158821 libWPEWebKit-1.0.so.3`WTF::RunLoop::$_0::__invoke(source=0x0000555555589460, callback=(libWPEWebKit-1.0.so.3`WTF::RunLoop::RunLoop()::$_1::__invoke(void*) at RunLoopGLib.cpp:79), userData=0x00007fffef6f9000)(void*), void*) at RunLoopGLib.cpp:45
    frame #36: 0x00007ffff3aaff30 libglib-2.0.so.0`g_main_context_dispatch + 352
    frame #37: 0x00007ffff3b03b59 libglib-2.0.so.0`___lldb_unnamed_symbol449$$libglib-2.0.so.0 + 521
    frame #38: 0x00007ffff3aad781 libglib-2.0.so.0`g_main_context_iteration + 49
    frame #39: 0x00007ffff3cba22e libgio-2.0.so.0`g_application_run + 462
    frame #40: 0x000055555555760c cog`main(argc=4, argv=0x00007fffffffd6f8) at cog.c:457:12
    frame #41: 0x00007ffff38b6b25 libc.so.6`__libc_start_main + 213
    frame #42: 0x000055555555765e cog`_start + 46
(lldb)
Comment 6 Michael Catanzaro 2021-04-08 15:33:08 PDT
(In reply to Adrian Perez from comment #4)
> Okay, an observation: The backtrace above is from the UIProcess, which
> I am quite sure it is NOT expected to instantiate PlatformDisplayLibWPE.

Hm, I think that's only true for GTK port, where the PlatformDisplayLibWPE is created in WebProcess::platformInitializeWebProcess, and PlatformDisplay::createPlatformDisplay should never create a PlatformDisplayLibWPE.

But this is a WPE port bug. For WPE port, PlatformDisplay::createPlatformDisplay is always going to create a PlatformDisplayLibWPE, and PlatformDisplay::sharedDisplay is routinely used in the UI process.
Comment 7 Adrian Perez 2021-04-08 15:45:10 PDT
So, loading webkit://gpu creates a GL context, which in turn lazily
creates a PlatformDisplayLibWPE singleton by means of a call to the 
PlatformDisplay::sharedDisplay() function.

The thing here is that PlatformDisplayLibWPE::initialize() never
gets called, so its m_backend point is never set to a non-NULL value.
OTOH, PlatformDisplay::initializeEGLDisplay() does get called, and
there is where the atexit() call is done.
Comment 8 Claudio Saavedra 2021-10-08 07:08:14 PDT
Created attachment 440602 [details]
Patch
Comment 9 Adrian Perez 2021-10-08 08:04:41 PDT
Comment on attachment 440602 [details]
Patch

rs=me :)
Comment 10 Claudio Saavedra 2021-10-08 08:08:36 PDT
Committed r283801 (242694@main): <https://commits.webkit.org/242694@main>