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 383468888..efcf26f31 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1544,8 +1544,6 @@ Cocoa_DestroyWindow(_THIS, SDL_Window * window) 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 @@ Cocoa_DestroyWindow(_THIS, SDL_Window * window) 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 09d409cfa..cb8f1cb5f 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 b6c1a0de9..2b1567778 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -290,13 +290,12 @@ UIKit_DestroyWindow(_THIS, SDL_Window * window) { 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 57bc339ae..3760c0d3b 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 dfc997b6b..94328339f 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 d2d02dd86..5437d7011 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