⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201595 in webkit


Ignore:
Timestamp:
Jun 2, 2016, 12:36:21 AM (10 years ago)
Author:
Carlos Garcia Campos
Message:

[Wayland] PlatformDisplayWayland destructor is super crashy
https://bugs.webkit.org/show_bug.cgi?id=157973

Reviewed by Michael Catanzaro.

EGL registers two at exist callbacks one to finish the display and another one to unload drivers, the one to
finish the display happens first. When our destructor is called the _eglFiniDisplay callback has already been
called, so we have a valid pointer for an already finished display. Then eglTerminate tries to find the display
in the global display list, but fails and for some reason it crashes when trying to return an error.
If atexit is called after the global PlatformDisplay constructor, the atexit handler is called before the
destructor. The atexit callbacks are called in reverse order, so if we register an atexit handler after the
global instace has been created and after EGL has been initialized, we could terminate the EGL display before
the EGL atexit handlers and the global PlatformDisplay destructor.

  • platform/graphics/PlatformDisplay.cpp:

(WebCore::PlatformDisplay::initializeEGLDisplay):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r201594 r201595  
     12016-06-02  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [Wayland] PlatformDisplayWayland destructor is super crashy
     4        https://bugs.webkit.org/show_bug.cgi?id=157973
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        EGL registers two at exist callbacks one to finish the display and another one to unload drivers, the one to
     9        finish the display happens first. When our destructor is called the _eglFiniDisplay callback has already been
     10        called, so we have a valid pointer for an already finished display. Then eglTerminate tries to find the display
     11        in the global display list, but fails and for some reason it crashes when trying to return an error.
     12        If atexit is called after the global PlatformDisplay constructor, the atexit handler is called before the
     13        destructor. The atexit callbacks are called in reverse order, so if we register an atexit handler after the
     14        global instace has been created and after EGL has been initialized, we could terminate the EGL display before
     15        the EGL atexit handlers and the global PlatformDisplay destructor.
     16
     17        * platform/graphics/PlatformDisplay.cpp:
     18        (WebCore::PlatformDisplay::initializeEGLDisplay):
     19
    1202016-06-01  Brady Eidson  <beidson@apple.com>
    221
  • trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp

    r191856 r201595  
    113113PlatformDisplay::~PlatformDisplay()
    114114{
    115     // WinCairo crashes when terminating EGL on exit.
    116     // https://bugs.webkit.org/show_bug.cgi?id=145832
    117 #if USE(EGL) && !PLATFORM(WIN)
    118     terminateEGLDisplay();
     115#if USE(EGL)
     116    ASSERT(m_eglDisplay == EGL_NO_DISPLAY);
    119117#endif
    120118}
     
    160158        return;
    161159    }
     160
     161    // EGL registers atexit handlers to cleanup its global display list.
     162    // Since the global PlatformDisplay instance is created before,
     163    // when the PlatformDisplay destructor is called, EGL has already removed the
     164    // display from the list, causing eglTerminate() to crash. So, here we register
     165    // our own atexit handler, after EGL has been initialized and after the global
     166    // instance has been created to ensure we call eglTerminate() before the other
     167    // EGL atexit handlers and the PlatformDisplay destructor.
     168    // See https://bugs.webkit.org/show_bug.cgi?id=157973.
     169    std::atexit([] { PlatformDisplay::sharedDisplay().terminateEGLDisplay(); });
    162170}
    163171
    164172void PlatformDisplay::terminateEGLDisplay()
    165173{
     174    ASSERT(m_eglDisplayInitialized);
    166175    if (m_eglDisplay == EGL_NO_DISPLAY)
    167176        return;
Note: See TracChangeset for help on using the changeset viewer.