From d44f392265cdb2562850174be1728cfd6c3142fe Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 7 Jul 2014 10:33:32 -0700 Subject: [PATCH] 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/59b543340d63 , 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 | 4 ++-- src/video/mir/SDL_mirwindow.c | 3 +-- src/video/uikit/SDL_uikitwindow.m | 3 +-- src/video/wayland/SDL_waylandwindow.c | 3 +-- src/video/windows/SDL_windowswindow.c | 3 +-- src/video/x11/SDL_x11window.c | 3 +-- 6 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 38346888899ec..efcf26f314894 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1544,8 +1544,6 @@ - (void)resetCursorRects NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - window->driverdata = NULL; - if (data) { [data->listener close]; [data->listener release]; @@ -1562,6 +1560,8 @@ - (void)resetCursorRects SDL_free(data); } + window->driverdata = NULL; + [pool release]; } diff --git a/src/video/mir/SDL_mirwindow.c b/src/video/mir/SDL_mirwindow.c index 09d409cfa427e..cb8f1cb5fb793 100644 --- a/src/video/mir/SDL_mirwindow.c +++ b/src/video/mir/SDL_mirwindow.c @@ -149,14 +149,13 @@ MIR_DestroyWindow(_THIS, SDL_Window* window) MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; - window->driverdata = NULL; - if (mir_data) { SDL_EGL_DestroySurface(_this, mir_window->egl_surface); MIR_mir_surface_release_sync(mir_window->surface); SDL_free(mir_window); } + window->driverdata = NULL; } SDL_bool diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index b6c1a0de914be..2b15677789cc7 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -290,13 +290,12 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo { SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - window->driverdata = NULL; - if (data) { [data->viewcontroller release]; [data->uiwindow release]; SDL_free(data); } + window->driverdata = NULL; } SDL_bool diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 57bc339ae14b0..3760c0d3b90a1 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -243,8 +243,6 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) SDL_VideoData *data = _this->driverdata; SDL_WindowData *wind = window->driverdata; - window->driverdata = NULL; - if (data) { SDL_EGL_DestroySurface(_this, wind->egl_surface); WAYLAND_wl_egl_window_destroy(wind->egl_window); @@ -261,6 +259,7 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window) SDL_free(wind); WAYLAND_wl_display_flush(data->display); } + window->driverdata = NULL; } #endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */ diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index dfc997b6b85fb..94328339f59d7 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -619,8 +619,6 @@ WIN_DestroyWindow(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - window->driverdata = NULL; - if (data) { ReleaseDC(data->hwnd, data->hdc); if (data->created) { @@ -639,6 +637,7 @@ WIN_DestroyWindow(_THIS, SDL_Window * window) } SDL_free(data); } + window->driverdata = NULL; } SDL_bool diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index d2d02dd86c96b..5437d7011cca8 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1394,8 +1394,6 @@ X11_DestroyWindow(_THIS, SDL_Window * window) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - window->driverdata = NULL; - if (data) { SDL_VideoData *videodata = (SDL_VideoData *) data->videodata; Display *display = videodata->display; @@ -1424,6 +1422,7 @@ X11_DestroyWindow(_THIS, SDL_Window * window) } SDL_free(data); } + window->driverdata = NULL; } SDL_bool