Fixed bug 2629 - Mac: crash when calling SDL_DestroyWindow with an active OpenGL context
authorSam Lantinga <slouken@libsdl.org>
Mon, 07 Jul 2014 10:33:32 -0700
changeset 89787753e4fd3d1d
parent 8977 84ae33058c67
child 8979 1e283b7a1580
Fixed bug 2629 - Mac: crash when calling SDL_DestroyWindow with an active OpenGL context

Alex Szpakowski

Since this commit https://hg.libsdl.org/SDL/rev/1519c462cee6 , calling SDL_DestroyWindow will crash the program if the window has an active OpenGL context.

This is because the Cocoa_DestroyWindow code sets the window's driverdata to NULL and then calls [context setWindow:NULL], which tries to access the window's driverdata, resulting in a null pointer dereference.

I have attached a patch which fixes the issue by moving the line which sets the driverdata to NULL to after the lines which call functions that use the driverdata pointer.
src/video/cocoa/SDL_cocoawindow.m
src/video/mir/SDL_mirwindow.c
src/video/uikit/SDL_uikitwindow.m
src/video/wayland/SDL_waylandwindow.c
src/video/windows/SDL_windowswindow.c
src/video/x11/SDL_x11window.c
     1.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Sun Jul 06 22:15:31 2014 +0100
     1.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Jul 07 10:33:32 2014 -0700
     1.3 @@ -1544,8 +1544,6 @@
     1.4      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     1.5      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     1.6  
     1.7 -    window->driverdata = NULL;
     1.8 -
     1.9      if (data) {
    1.10          [data->listener close];
    1.11          [data->listener release];
    1.12 @@ -1562,6 +1560,8 @@
    1.13  
    1.14          SDL_free(data);
    1.15      }
    1.16 +    window->driverdata = NULL;
    1.17 +
    1.18      [pool release];
    1.19  }
    1.20  
     2.1 --- a/src/video/mir/SDL_mirwindow.c	Sun Jul 06 22:15:31 2014 +0100
     2.2 +++ b/src/video/mir/SDL_mirwindow.c	Mon Jul 07 10:33:32 2014 -0700
     2.3 @@ -149,14 +149,13 @@
     2.4      MIR_Data* mir_data = _this->driverdata;
     2.5      MIR_Window* mir_window = window->driverdata;
     2.6  
     2.7 -    window->driverdata = NULL;
     2.8 -
     2.9      if (mir_data) {
    2.10          SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
    2.11          MIR_mir_surface_release_sync(mir_window->surface);
    2.12  
    2.13          SDL_free(mir_window);
    2.14      }
    2.15 +    window->driverdata = NULL;
    2.16  }
    2.17  
    2.18  SDL_bool
     3.1 --- a/src/video/uikit/SDL_uikitwindow.m	Sun Jul 06 22:15:31 2014 +0100
     3.2 +++ b/src/video/uikit/SDL_uikitwindow.m	Mon Jul 07 10:33:32 2014 -0700
     3.3 @@ -290,13 +290,12 @@
     3.4  {
     3.5      SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
     3.6  
     3.7 -    window->driverdata = NULL;
     3.8 -
     3.9      if (data) {
    3.10          [data->viewcontroller release];
    3.11          [data->uiwindow release];
    3.12          SDL_free(data);
    3.13      }
    3.14 +    window->driverdata = NULL;
    3.15  }
    3.16  
    3.17  SDL_bool
     4.1 --- a/src/video/wayland/SDL_waylandwindow.c	Sun Jul 06 22:15:31 2014 +0100
     4.2 +++ b/src/video/wayland/SDL_waylandwindow.c	Mon Jul 07 10:33:32 2014 -0700
     4.3 @@ -243,8 +243,6 @@
     4.4      SDL_VideoData *data = _this->driverdata;
     4.5      SDL_WindowData *wind = window->driverdata;
     4.6  
     4.7 -    window->driverdata = NULL;
     4.8 -
     4.9      if (data) {
    4.10          SDL_EGL_DestroySurface(_this, wind->egl_surface);
    4.11          WAYLAND_wl_egl_window_destroy(wind->egl_window);
    4.12 @@ -261,6 +259,7 @@
    4.13          SDL_free(wind);
    4.14          WAYLAND_wl_display_flush(data->display);
    4.15      }
    4.16 +    window->driverdata = NULL;
    4.17  }
    4.18  
    4.19  #endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */
     5.1 --- a/src/video/windows/SDL_windowswindow.c	Sun Jul 06 22:15:31 2014 +0100
     5.2 +++ b/src/video/windows/SDL_windowswindow.c	Mon Jul 07 10:33:32 2014 -0700
     5.3 @@ -619,8 +619,6 @@
     5.4  {
     5.5      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     5.6  
     5.7 -    window->driverdata = NULL;
     5.8 -
     5.9      if (data) {
    5.10          ReleaseDC(data->hwnd, data->hdc);
    5.11          if (data->created) {
    5.12 @@ -639,6 +637,7 @@
    5.13          }
    5.14          SDL_free(data);
    5.15      }
    5.16 +    window->driverdata = NULL;
    5.17  }
    5.18  
    5.19  SDL_bool
     6.1 --- a/src/video/x11/SDL_x11window.c	Sun Jul 06 22:15:31 2014 +0100
     6.2 +++ b/src/video/x11/SDL_x11window.c	Mon Jul 07 10:33:32 2014 -0700
     6.3 @@ -1394,8 +1394,6 @@
     6.4  {
     6.5      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     6.6  
     6.7 -    window->driverdata = NULL;
     6.8 -
     6.9      if (data) {
    6.10          SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
    6.11          Display *display = videodata->display;
    6.12 @@ -1424,6 +1422,7 @@
    6.13          }
    6.14          SDL_free(data);
    6.15      }
    6.16 +    window->driverdata = NULL;
    6.17  }
    6.18  
    6.19  SDL_bool