Bugfix for Detection of Joystick Properties in SDL-1.2.14


I’ve joined this mailing list to report a bug in the 1.2.14 version of the SDL
library. But before I forget, let me say “Thank you!” to Sam Lantinga and to
everyone else who has contributed to this library. (I’m using it via DosBox.)

Problem Description:

On Slackware 13.1, which is running SDL 1.2.14, my CH Products ‘F-16
Combatstick USB’ joystick (USB VID/PID 068e/0504) was erroneously reporting
only 1 axis instead of 3 (and 0 “hats” instead of 1), as evidenced by this run
of the test app which comes with SDL:

==> testjoystick 
There are 1 joysticks attached
Joystick 0: CH Products  CH 3-Axis 10-Button+POV USB Joystick
       axes: 1
      balls: 0
       hats: 0
    buttons: 10

Also, activation of the “coolie hat” switch in any of the 4 positions would
cause an immediate segmentation fault.

As you can see from the name of the joystick, the reported button count (10)
is correct.


After a few hours of scratching my head and testing, I eventually found the
bug. It occurs in this file:


Here’s the offending code, with a bit of context:

if ( test_bit(i, absbit) ) {
	int values[5];

	if ( ioctl(fd, EVIOCGABS(i), values) < 0 )

On my kernel, the structure that is used to pass the ‘values’ back is
defined in ‘linux/input.h’:

struct input_absinfo {
	__s32 value;
	__s32 minimum;
	__s32 maximum;
	__s32 fuzz;
	__s32 flat;
	__s32 resolution;

But the ‘int values[5]’ array is not large enough to hold it. On my system,
this causes the ‘absbit[]’ array to become corrupted, preventing detection of
any joystick axes after the first one. I suppose that the symptoms might be
different on other systems though, depending on compiler issues like alignment
or whatever.

A simple change of ‘5’ to ‘6’ makes my joystick report correctly once again
and, incidentally, seems to prevent the segmentation faults that were
occurring every time I activated the “coolie hat” switch on that joystick.

I see that others had similar problems which were undoubtedly a result of this
same bug. Examples:



With the fixed library installed, I now see the expected output for the ‘F-16
Combatstick USB’ joystick:

==> testjoystick
There are 1 joysticks attached
Joystick 0: CH Products  CH 3-Axis 10-Button+POV USB Joystick
       axes: 3
      balls: 0
       hats: 1
    buttons: 10

All 3 axes (X, Y, and throttle wheel) and 1 hat are now detected – excellent!

Note: I later discovered that a fix has already been made in the 1.3.x source
code. In fact, it was done in a more robust, future-proof manner than the
quick ‘n’ dirty fix I’ve suggested above. The 1.3.x source code smartly uses
the actual structure to define the receiving variable:

if (test_bit(i, absbit)) {
    struct input_absinfo absinfo;

    if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0)

Can such a fix be put into the next 1.2.x release? Is there even going to be a
new 1.2.x release?

Again, my thanks to all who have contributed to this library. I hope some
sort of bug fix might make it into the 1.2.x library. Failing that, I hope
that the 1.3.x library comes out before the next official release of Slackware.

Hopefully, at a minimum, this bugfix report might save someone else the time I
spent chasing this down. I just wish I’d thought to run a ‘diff’ on the 1.2.14
and 1.3.x code before finding the bug the hard way! :^)

Bill Marr

A couple of points that I might have made clearer in my original post on this

(1) This bug only affects Linux users of SDL 1.2.x.

(2) This bug affects all (Linux) joystick users (not just those with a CH
Products ‘F-16 Combatstick USB’ joystick). It undoubtedly affects (Linux)
gamepad users too.

Also, please note that I later discovered that this same bug (inadequate
storage allocation for the EVIOCGABS ioctl call) appears in the SDL 1.3 Linux
"touch" interface code, as described here:


Bill Marr