Title: [201595] trunk/Source/WebCore
Revision
201595
Author
[email protected]
Date
2016-06-02 00:36:21 -0700 (Thu, 02 Jun 2016)

Log 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):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (201594 => 201595)


--- trunk/Source/WebCore/ChangeLog	2016-06-02 05:47:12 UTC (rev 201594)
+++ trunk/Source/WebCore/ChangeLog	2016-06-02 07:36:21 UTC (rev 201595)
@@ -1,3 +1,22 @@
+2016-06-02  Carlos Garcia Campos  <[email protected]>
+
+        [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):
+
 2016-06-01  Brady Eidson  <[email protected]>
 
         Get rid of StringCapture.

Modified: trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp (201594 => 201595)


--- trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp	2016-06-02 05:47:12 UTC (rev 201594)
+++ trunk/Source/WebCore/platform/graphics/PlatformDisplay.cpp	2016-06-02 07:36:21 UTC (rev 201595)
@@ -112,10 +112,8 @@
 
 PlatformDisplay::~PlatformDisplay()
 {
-    // WinCairo crashes when terminating EGL on exit.
-    // https://bugs.webkit.org/show_bug.cgi?id=145832
-#if USE(EGL) && !PLATFORM(WIN)
-    terminateEGLDisplay();
+#if USE(EGL)
+    ASSERT(m_eglDisplay == EGL_NO_DISPLAY);
 #endif
 }
 
@@ -159,10 +157,21 @@
         terminateEGLDisplay();
         return;
     }
+
+    // EGL registers atexit handlers to cleanup its global display list.
+    // Since the global PlatformDisplay instance is created before,
+    // when the PlatformDisplay destructor is called, EGL has already removed the
+    // display from the list, causing eglTerminate() to crash. So, here we register
+    // our own atexit handler, after EGL has been initialized and after the global
+    // instance has been created to ensure we call eglTerminate() before the other
+    // EGL atexit handlers and the PlatformDisplay destructor.
+    // See https://bugs.webkit.org/show_bug.cgi?id=157973.
+    std::atexit([] { PlatformDisplay::sharedDisplay().terminateEGLDisplay(); });
 }
 
 void PlatformDisplay::terminateEGLDisplay()
 {
+    ASSERT(m_eglDisplayInitialized);
     if (m_eglDisplay == EGL_NO_DISPLAY)
         return;
     eglTerminate(m_eglDisplay);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to