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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 3834688..efcf26f 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 09d409c..cb8f1cb 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 b6c1a0d..2b15677 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 57bc339..3760c0d 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 dfc997b..9432833 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 d2d02dd..5437d70 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