| Summary: | Infinite loop in SDL_SYS_JoystickClose with QtSixAd & mednafen | ||
|---|---|---|---|
| Product: | SDL | Reporter: | jarrod.b.johnson+sdlbugs |
| Component: | joystick | Assignee: | Sam Lantinga <slouken> |
| Status: | RESOLVED WONTFIX | QA Contact: | Sam Lantinga <slouken> |
| Severity: | normal | ||
| Priority: | P2 | ||
| Version: | 1.2.13 | ||
| Hardware: | x86 | ||
| OS: | Linux | ||
Yes, my quick guess is insufficient, all the code following that check very much is not expecting for that loop to come back empty-handed, and will segfault. I just tried this with QtSixA 0.4.3 on Ubuntu 9.04 x86_64 and it worked just fine:
$ ./testjoystick
There are 1 joysticks attached
Joystick 0: Sony PLAYSTATION(R)3 Controller
axes: 27
balls: 0
hats: 0
buttons: 19
Are you still having trouble with the latest SDL snapshot?
http://www.libsdl.org/tmp/SDL-1.2.zip
Interestingly I wasn't able to get it working in Bluetooth mode, only via USB.
I will try again with latest snapshot, however, I also had no problems in USB mode, only bluetooth mode. In the meantime, one question is can it ever possibly make sense for the fname member of the struct to be null (i.e. is something about the way sixad daemon relays events to the joystick device a valid case for fname being null). Or perhaps is mednafen ultimately doing something wrong/unexpected (i.e. calling close twice?) Is there some code before that point that is intended to protect that loop from seeing that condition, or does that loop need to not loop infinitely when the loop conditions currently cause it to? A good test would be to try testjoystick in the SDL snapshot archive. That at least will tell you whether it's something silly like a double-close (which shouldn't ever be done!) Also, would it be possible for me to log in remotely and debug? If so, please send me login information via private e-mail. No response from the customer, I'm closing this for now. Please reopen this as a 1.3 bug if it's an issue there. |
I'm running QtSixA to allow me to use my PS3 controller with my x86_64 linux system via bluetooth. When I run mednafen and it exits, SDL's attempts to close the joystick enters an infinite loop. Specifically: if (SDL_joylist[joystick->index].fname == NULL) { SDL_joylist_head(i, joystick->index); SDL_JoystickClose(SDL_joylist[i].joy); } It enters this conditional where joystick looks like this: (gdb) print *joystick $9 = {index = 0 '\0', name = 0x0, naxes = 18, axes = 0x1d951e0, nhats = 4, hats = 0x1d92ff0 "", nballs = 0, balls = 0x0, nbuttons = 21, buttons = 0x1d93010 "", hwdata = 0x1d952f0, ref_count = 0} and SDL_joylist at 0 is: (gdb) print SDL_joylist[0] $7 = {fname = 0x0, joy = 0x1d95280, map = 0x0, prev = 0, next = 0, logicalno = 0} So: #define SDL_joylist_head(i, start)\ for(i = start; SDL_joylist[i].fname == NULL;) i = SDL_joylist[i].prev; That loop starts with i==0, fname is indeed NULL, and prev is also zero, making this an infinite loop. My first guess at how to proceed would be for it to look like: for(i = start; SDL_joylist[i].fname == NULL && i != SDL_joylist[i].prev;) \ i = SDL_joylist[i].prev; However, I'm not sure if that would break assertions made by code following invocations of that #define.