Fixed Bug 5034 - Replugging in a controller crashes on macOS in SDL 2.0.12 The Darwin/macOS joystick driver was freeing its joystick's hwdata field without zeroing it out in any live instance of SDL_Joystick.
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
diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c
index 44d4136..786b94f 100644
--- a/src/joystick/darwin/SDL_sysjoystick.c
+++ b/src/joystick/darwin/SDL_sysjoystick.c
@@ -125,6 +125,7 @@ static recDevice *
FreeDevice(recDevice *removeDevice)
{
recDevice *pDeviceNext = NULL;
+ SDL_Joystick *joystick = NULL;
if (removeDevice) {
if (removeDevice->deviceRef) {
IOHIDDeviceUnscheduleFromRunLoop(removeDevice->deviceRef, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
@@ -146,6 +147,14 @@ FreeDevice(recDevice *removeDevice)
}
removeDevice->pNext = NULL;
+ /* clear out any reference to this recDevice that are being
+ * held by a live instance of SDL_Joystick
+ */
+ joystick = SDL_JoystickFromInstanceID(removeDevice->instance_id);
+ if (joystick) {
+ joystick->hwdata = NULL;
+ }
+
/* free element lists */
FreeElementList(removeDevice->firstAxis);
FreeElementList(removeDevice->firstButton);
@@ -871,6 +880,10 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
/* Scale and average the two rumble strengths */
Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
+ if (!device) {
+ return SDL_SetError("Rumble failed, device disconnected");
+ }
+
if (!device->ffservice) {
return SDL_Unsupported();
}