We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2161

Summary: Crash on Windows when opening second HapticFromJoystick
Product: SDL Reporter: Nicholas Hastings <nshastings>
Component: hapticAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: critical    
Priority: P2    
Version: HG 2.0   
Hardware: x86   
OS: Windows 7   

Description Nicholas Hastings 2013-10-18 21:08:05 UTC
As discussed on the mailing list, there is a crash in the haptics subsystem, on Windows, when SDL_HapticOpenFromJoystick is called for a second device. 

The underlying cause may be the same as in bug 2126, but I wanted to file separately in the case that it's not since the trigger is different.

To reproduce, have more than one joystick or game controller supporting haptics connected, such as two Xbox 360 controllers. Then open each as a joystick, and then open a haptic from each with SDL_HapticOpenFromJoystick.

The crash is in SDL_SYS_JoystickSameHaptic on this line,
http://hg.libsdl.org/SDL/file/b7c1c84c33e3/src/haptic/windows/SDL_syshaptic.c#l649


Simplified repro code, assuming at least two haptic joysticks are attached:
> SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC);
>
> int numJoysticks = SDL_NumJoysticks();
>
> for (int i = 0; i < numJoysticks; ++i)
> {
>     SDL_Joystick *pJoy;
>     pJoy = SDL_JoystickOpen(i);
>     if (!pJoy || !SDL_JoystickIsHaptic(pJoy))
>         continue;
>
>     // This will crash on the second invocation
>     SDL_Haptic *pHaptic = SDL_HapticOpenFromJoystick(pJoy);
> }
Comment 1 Ryan C. Gordon 2013-10-21 03:15:48 UTC
This should be fixed by http://hg.libsdl.org/SDL/rev/70f1d63482d0 ...

This line...

    if ((joystick->hwdata->bXInputHaptic == haptic->hwdata->bXInputHaptic) && (haptic->hwdata->userid == joystick->hwdata->userid)) {

...would fail if both devices were different XInput controllers, and then try to use them as bogus pointers through the DirectInput API. If was a goofy piece of logic.

--ryan.