glx: Properly handle cases where screen creation fails
authorChuck Atkins <chuck.atkins@kitware.com>
Thu, 22 Feb 2018 14:19:37 +0000 (09:19 -0500)
committerChuck Atkins <chuck.atkins@kitware.com>
Thu, 22 Feb 2018 15:20:32 +0000 (10:20 -0500)
This fixes a segfault exposed by a29d63ecf7 which occurs when swr is
used on an unsupported architecture.

v2: re-work to place logic in xmesa_init_display

Signed-off-by: Chuck Atkins <chuck.atkins@kitware.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Cc: mesa-stable@lists.freedesktop.org
Cc: George Kyriazis <george.kyriazis@intel.com>
Cc: Bruce Cherniak <bruce.cherniak@intel.com>
src/gallium/state_trackers/glx/xlib/glx_api.c
src/gallium/state_trackers/glx/xlib/xm_api.c
src/gallium/state_trackers/glx/xlib/xm_api.h

index 1994e6823a83aa3f845f3cc4b86d19b85909240c..6ec3a31d5fced1d6748aaf4c2043ab9f627e4ccb 100644 (file)
@@ -743,7 +743,10 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
    int numAux = 0;
    GLint num_samples = 0;
 
-   xmesa_init( dpy );
+   if (xmesa_init( dpy ) != 0) {
+      _mesa_warning(NULL, "Failed to initialize display");
+      return NULL;
+   }
 
    parselist = list;
 
index 934c0aba11812e1e4ec4072047f5a2a2183ca744..e8cbb618cea470bb015315a185fe9f566f1031e2 100644 (file)
@@ -142,8 +142,11 @@ xmesa_close_display(Display *display)
 {
    XMesaExtDisplayInfo *info, *prev;
 
+   /* These assertions are not valid since screen creation can fail and result
+    * in an empty list
    assert(MesaExtInfo.ndisplays > 0);
    assert(MesaExtInfo.head);
+   */
 
    _XLockMutex(_Xglobal_lock);
    /* first find display */
@@ -223,7 +226,30 @@ xmesa_init_display( Display *display )
       return NULL;
    }
    info->display = display;
+
    xmdpy = &info->mesaDisplay; /* to be filled out below */
+   xmdpy->display = display;
+   xmdpy->pipe = NULL;
+
+   xmdpy->smapi = CALLOC_STRUCT(st_manager);
+   if (!xmdpy->smapi) {
+      Xfree(info);
+      mtx_unlock(&init_mutex);
+      return NULL;
+   }
+
+   xmdpy->screen = driver.create_pipe_screen(display);
+   if (!xmdpy->screen) {
+      free(xmdpy->smapi);
+      Xfree(info);
+      mtx_unlock(&init_mutex);
+      return NULL;
+   }
+
+   /* At this point, both smapi and screen are known to be valid */
+   xmdpy->smapi->screen = xmdpy->screen;
+   xmdpy->smapi->get_param = xmesa_get_param;
+   (void) mtx_init(&xmdpy->mutex, mtx_plain);
 
    /* chain to the list of displays */
    _XLockMutex(_Xglobal_lock);
@@ -232,32 +258,6 @@ xmesa_init_display( Display *display )
    MesaExtInfo.ndisplays++;
    _XUnlockMutex(_Xglobal_lock);
 
-   /* now create the new XMesaDisplay info */
-   assert(display);
-
-   xmdpy->display = display;
-   xmdpy->screen = driver.create_pipe_screen(display);
-   xmdpy->smapi = CALLOC_STRUCT(st_manager);
-   xmdpy->pipe = NULL;
-   if (xmdpy->smapi) {
-      xmdpy->smapi->screen = xmdpy->screen;
-      xmdpy->smapi->get_param = xmesa_get_param;
-   }
-
-   if (xmdpy->screen && xmdpy->smapi) {
-      (void) mtx_init(&xmdpy->mutex, mtx_plain);
-   }
-   else {
-      if (xmdpy->screen) {
-         xmdpy->screen->destroy(xmdpy->screen);
-         xmdpy->screen = NULL;
-      }
-      free(xmdpy->smapi);
-      xmdpy->smapi = NULL;
-
-      xmdpy->display = NULL;
-   }
-
    mtx_unlock(&init_mutex);
 
    return xmdpy;
@@ -935,10 +935,10 @@ xmesa_get_name(void)
 /**
  * Do per-display initializations.
  */
-void
+int
 xmesa_init( Display *display )
 {
-   xmesa_init_display(display);
+   return xmesa_init_display(display) ? 0 : 1;
 }
 
 
index 06bf839c96ededc6c65166e5fdfcdec9f44fc147..e420679313e64db430a9a0d73830b6f4b0e6ceba 100644 (file)
@@ -359,7 +359,7 @@ struct xmesa_buffer {
 extern const char *
 xmesa_get_name(void);
 
-extern void
+extern int
 xmesa_init(Display *dpy);
 
 extern XMesaBuffer