Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

segfault when using Teensy 3.2/3.1 based USB devices #4981

Closed
pixjuan opened this issue May 5, 2019 · 39 comments
Closed

segfault when using Teensy 3.2/3.1 based USB devices #4981

pixjuan opened this issue May 5, 2019 · 39 comments

Comments

@pixjuan
Copy link

pixjuan commented May 5, 2019

Hello,
I am designing a custom controller based on a Teensy 3.1 board.
The board just reports as HID device (keyboard) but it probably does something uncommon since Mame crashes on startup when I launch Mame with my controller plugged.
I tried it with other games like FrozenBubble and I had no crash.
I don't think it comes from my code since I can reproduce the problem with the basic Teensy 3.1 keyboard example.
My guess is that the usb library of the Teensy 3 codebase must fill some fields in an unusual way that get parsed wrong by Mame.

Steps to reproduce the crash

  • install Arduino IDE 1.8.1
  • get a teensy3.1 (should work the same with version 3.0 and 3.2, maybe 3.6 as well)
  • in 'tools' menu set car type to Teensy 3.2/3.1
  • set USB-type to 'keyboard'
  • compile and upload the code to the Teensy
  • start mame with : ./mame64 apple2c -window -rp -flop1 sabotage.dsk
  • it should segfault

Plugging the Teensy in after the game doesn't trigger the crash.
Starting Mame with the Teensy plugged in but without parameters doesn't trigger the crash either.

Stack trace

core.gz

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./mame64 apple2c -window -rp <myrompath> -flop1 sabotage.dsk'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000559cfa5b940f in sdl_osd_interface::poll_inputs(running_machine&) ()
[Current thread is 1 (Thread 0x7f83c9bc2880 (LWP 23931))]
(gdb) bt
#0  0x0000559cfa5b940f in sdl_osd_interface::poll_inputs(running_machine&) ()
#1  0x0000559cfa5af81f in sdl_osd_interface::update(bool) ()
#2  0x0000559cfd93a80c in video_manager::frame_update(bool) ()
#3  0x0000559cfa67cf19 in mame_machine_manager::create_ui(running_machine&) ()
#4  0x0000559cfd8abfa5 in running_machine::start() ()
#5  0x0000559cfd8ad551 in running_machine::run(bool) ()
#6  0x0000559cfa67f8d5 in mame_machine_manager::execute() ()
#7  0x0000559cfa70a68a in cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) ()
#8  0x0000559cfa70a892 in cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) ()
#9  0x0000559cfa67da55 in emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&) ()
#10 0x0000559cf6afc6f1 in main ()

My system

Debian stretch on core i7
Mame 209 compiled with a regular "make".
The behavior was identical with the official Debian Mame package (0.206)

lsusb

Here is the output of lusb -v for this device :

Bus 003 Device 021: ID 16c0:04d0 Van Ooijen Technische Informatica 
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x16c0 Van Ooijen Technische Informatica
  idProduct          0x04d0 
  bcdDevice            2.75
  iManufacturer           1 Teensyduino
  iProduct                2 Keyboard
  iSerial                 3 589360
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x005b
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xc0
      Self Powered
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      63
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
         Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      33
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               2
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      40
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
Device Status:     0x0000
  (Bus Powered)
@rb6502
Copy link
Contributor

rb6502 commented May 24, 2019

What's the related output from running MAME with -verbose?

@pixjuan
Copy link
Author

pixjuan commented May 24, 2019

with -verbose I get the following :

Attempting load of mame.ini
Attempting load of mame.ini
Attempting load of horizont.ini
Attempting load of computer.ini
Attempting load of raster.ini
Attempting load of source/apple2e.ini
Attempting load of apple2c.ini
Starting plugin data...
Attempting load of mame.ini
Attempting load of mame.ini
Attempting load of horizont.ini
Attempting load of computer.ini
Attempting load of raster.ini
Attempting load of source/apple2e.ini
Attempting load of apple2c.ini
Available videodrivers: x11 wayland dummy
Current Videodriver: x11
Display #0
Renderdrivers:
opengl (0x0)
opengles2 (0x0)
software (0x0)
Display #1
Renderdrivers:
opengl (0x0)
opengles2 (0x0)
software (0x0)
Available audio drivers:
pulseaudio
alsa
sndio
dsp
disk
dummy
Build version: 0.209 (mame0209)
Build architecure:
Build defines 1: SDLMAME_UNIX=1 SDLMAME_X11=1 SDLMAME_LINUX=1
Build defines 1: LSB_FIRST=1 PTR64=1
SDL/OpenGL defines: SDL_COMPILEDVERSION=2009 USE_OPENGL=1
Compiler defines A: GNUC=8 GNUC_MINOR=3 GNUC_PATCHLEVEL=0 VERSION="8.3.0"
Compiler defines B: amd64=1 x86_64=1 unix=1
Compiler defines C: __USE_FORTIFY_LEVEL=0
Enter init_monitors
Adding monitor screen0 (1920 x 1080)
Adding monitor screen1 (1680 x 1050)
Leave init_monitors
Enter sdlwindow_init
Using SDL multi-window soft driver (SDL 2.0+)

Hints:
SDL_FRAMEBUFFER_ACCELERATION (null)
SDL_RENDER_DRIVER (null)
SDL_RENDER_OPENGL_SHADERS (null)
SDL_RENDER_SCALE_QUALITY (null)
SDL_RENDER_VSYNC (null)
SDL_VIDEO_X11_XVIDMODE (null)
SDL_VIDEO_X11_XINERAMA (null)
SDL_VIDEO_X11_XRANDR (null)
SDL_GRAB_KEYBOARD (null)
SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS (null)
SDL_IOS_IDLE_TIMER_DISABLED (null)
SDL_IOS_ORIENTATIONS (null)
SDL_XINPUT_ENABLED (null)
SDL_GAMECONTROLLERCONFIG (null)
SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS (null)
SDL_ALLOW_TOPMOST (null)
SDL_TIMER_RESOLUTION (null)
SDL_RENDER_DIRECT3D_THREADSAFE (null)
SDL_VIDEO_ALLOW_SCREENSAVER (null)
SDL_ACCELEROMETER_AS_JOYSTICK (null)
SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK (null)
SDL_VIDEO_WIN_D3DCOMPILER (null)
SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT (null)
SDL_VIDEO_MAC_FULLSCREEN_SPACES (null)
SDL_MOUSE_RELATIVE_MODE_WARP (null)
SDL_RENDER_DIRECT3D11_DEBUG (null)
SDL_VIDEO_HIGHDPI_DISABLED (null)
SDL_WINRT_PRIVACY_POLICY_URL (null)
SDL_WINRT_PRIVACY_POLICY_LABEL (null)
SDL_WINRT_HANDLE_BACK_BUTTON (null)
Leave sdlwindow_init
Enter sdl_info::create
window: using renderer opengl
renderer: flag SDL_RENDERER_ACCELERATED
Leave renderer_sdl2::create
Audio: Start initialization
Audio: Driver is pulseaudio
Audio: frequency: 48000, channels: 2, samples: 256
sdl_create_buffers: creating stream buffer of 25600 bytes
Audio: End initialization
Keyboard: Start initialization
Input: Adding keyboard #0: System keyboard (device id: System keyboard)
Keyboard: Registered System keyboard
Keyboard: End initialization
Mouse: Start initialization
Input: Adding mouse #0: System mouse (device id: System mouse)
Mouse: Registered System mouse
Mouse: End initialization
Joystick: Start initialization
Input: Adding joystick #0: DragonRiseInc.GenericUSBJoystick (device id: DragonRiseInc.GenericUSBJoystick)
Joystick: DragonRise Inc. Generic USB Joystick
Joystick: ... 5 axes, 12 buttons 1 hats 0 balls
Joystick: ... Physical id 0 mapped to logical id 1
Joystick: ... Has haptic capability
Input: Adding joystick #1: TeensyduinoKeyboard (device id: TeensyduinoKeyboard)
Joystick: Teensyduino Keyboard
Joystick: ... 33 axes, 143 buttons 2 hats 0 balls
Joystick: ... Physical id 1 mapped to logical id 2
Joystick: ... Does not have haptic capability
Joystick: End initialization
Searching font Liberation Sans in -. path/s
Matching font: /usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttf
Erreur de segmentation (core dumped)

@rb6502
Copy link
Contributor

rb6502 commented May 25, 2019

I suspect the problem is here:

Input: Adding joystick #1: TeensyduinoKeyboard (device id: TeensyduinoKeyboard)
Joystick: Teensyduino Keyboard
Joystick: ... 33 axes, 143 buttons 2 hats 0 balls
Joystick: ... Physical id 1 mapped to logical id 2
Joystick: ... Does not have haptic capability

MAME cannot handle a controller with 143 buttons (and I'm not too sure about 33 axes), but it shouldn't crash in that situation either.

@pixjuan
Copy link
Author

pixjuan commented Jun 3, 2019

When I plug my device, here is what I get from dmesg :

[618329.828425] usb 3-1.2: new full-speed USB device number 48 using ehci-pci
[618329.937543] usb 3-1.2: New USB device found, idVendor=16c0, idProduct=04d0, bcdDevice= 2.75
[618329.937545] usb 3-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[618329.937546] usb 3-1.2: Product: Keyboard
[618329.937547] usb 3-1.2: Manufacturer: Teensyduino
[618329.937547] usb 3-1.2: SerialNumber: 589360
[618329.938604] input: Teensyduino Keyboard as /devices/pci0000:00/0000:00:1d.0/usb3/3-1/3-1.2/3-1.2:1.0/0003:16C0:04D0.012B/input/input880
[618330.000879] hid-generic 0003:16C0:04D0.012B: input,hidraw10: USB HID v1.11 Keyboard [Teensyduino Keyboard] on usb-0000:00:1d.0-1.2/input0
[618330.002064] hid-generic 0003:16C0:04D0.012C: hidraw11: USB HID v1.11 Device [Teensyduino Keyboard] on usb-0000:00:1d.0-1.2/input1
[618330.003039] input: Teensyduino Keyboard as /devices/pci0000:00/0000:00:1d.0/usb3/3-1/3-1.2/3-1.2:1.2/0003:16C0:04D0.012D/input/input881
[618330.060817] hid-generic 0003:16C0:04D0.012D: input,hidraw12: USB HID v1.11 Device [Teensyduino Keyboard] on usb-0000:00:1d.0-1.2/input2

Even if I use my device with Mame, it is supposed to be a keyboard, and Linux identifies it this way.
I didn't write any of the usb code, this is the default USB library, Mame crashes with the Teensy keyboard example as well.
143 buttons seems more consistent with a keyboard.
I added warnings in the Teeny joystick lib, and I don't see them when I compile my code with my usual settings. I have to set the USB mode to "Keyboard+Mouse+Joystick" to see them.
And then here is the output I get from Mame:

Joystick: Start initialization
Input: Adding joystick #0: TeensyduinoKeyboard/Mouse/Joystick (device id: TeensyduinoKeyboard/Mouse/Joystick)
Joystick: Teensyduino Keyboard/Mouse/Joystick
Joystick: ... 6 axes, 32 buttons 1 hats 0 balls
Joystick: ... Physical id 0 mapped to logical id 1
Joystick: ... Does not have haptic capability
Input: Adding joystick #1: TeensyduinoKeyboard/Mouse/Joystick (device id: TeensyduinoKeyboard/Mouse/Joystick)
Joystick: Teensyduino Keyboard/Mouse/Joystick
Joystick: ... 33 axes, 143 buttons 2 hats 0 balls
Joystick: ... Physical id 1 mapped to logical id 2
Joystick: ... Does not have haptic capability
Joystick: End initialization

So the problem is likely that the Teensy keyboard mode is identified as a Joystick by Mame.

By the way, by unplugging my other regular joystick (the one reported as DragonRiseInc.GenericUSBJoystick") I managed to run Mame, play my game and to only have the crash on exit, but it doesn't work every time.
The stack trace is different when it crashes at the end :

Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: Aucun fichier ou dossier de ce type.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007f2cceeae535 in __GI_abort () at abort.c:79
#2 0x00007f2ccef05778 in __libc_message (action=action@entry=do_abort,
fmt=fmt@entry=0x7f2ccf01028d "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007f2ccef0be6a in malloc_printerr (str=str@entry=0x7f2ccf00e376 "corrupted size vs. prev_size")
at malloc.c:5341
#4 0x00007f2ccef0d9fb in _int_free (av=0x7f2ccf047c40 <main_arena>, p=,
have_lock=) at malloc.c:4325
#5 0x000055c4da138561 in ioport_port::~ioport_port() ()
#6 0x000055c4da148e5e in ioport_manager::~ioport_manager() ()
#7 0x000055c4da1847ac in running_machine::~running_machine() ()
#8 0x000055c4d6f5980b in mame_machine_manager::execute() ()
#9 0x000055c4d6fe468a in cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&) ()
#10 0x000055c4d6fe4892 in cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) ()
#11 0x000055c4d6f57a55 in emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) ()
#12 0x000055c4d33d66f1 in main ()

I hopes it helps

@pixjuan
Copy link
Author

pixjuan commented Jun 15, 2019

I did some more tests:

  • First, I changed the usb vendor and product id that the Teensy board reports to the system to mimic the values of a basic Dell keyboard and I changed the reported name to "Evil.Corp.". It failed exactly the same way
  • Then I listed the content of /dev/input/by-id/ and it indeed contains 3 entries related to the Teensy, including joystick ones :

/dev/input/by-id/usb-Evil.Corp.._Keyboard_589360-event-kbd
/dev/input/by-id/usb-Evil.Corp.._Keyboard_589360-if02-event-joystick
/dev/input/by-id/usb-Evil.Corp.._Keyboard_589360-if02-joystick

And when I test them with jstest-gtk, one of them reports an huge number of keys and axis (different from what Mame reports,if that matters).

According to those results it seems that :

  • The Teensy wrongly reports a Joystick interface even when it is disabled
  • Mame correctly detects The Teensy board
  • Mame doesn't support joysticks with huge number of axis and buttons

@pixjuan
Copy link
Author

pixjuan commented Jul 31, 2019

I tried to fix the problem on Mame side :

  • First attempt :
    increasing the maximum number of buttons and axis by editing /src/emu/input.h
constexpr int INPUT_MAX_AXIS = 35; // was 8
constexpr int INPUT_MAX_BUTTONS = 150; // was 32

But it still segfaults when I plug my Teensy...
I found it a bit confusing that other similar constants are defined elsewhere such as MAX_BUTTONS

  • Second attempt :
    I restored the initial values for INPUT_MAX_BUTTONS and INPUT_MAX_AXIS and modified input_sdl.cpp :
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 40fe037f..bcc751fd 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -1049,7 +1049,7 @@ public:
                        }
 
                        // loop over all axes
-                       for (int axis = 0; axis < SDL_JoystickNumAxes(joy); axis++)
+                       for (int axis = 0; axis < std::min(SDL_JoystickNumAxes(joy), INPUT_MAX_AXIS); axis++) //  patch
                        {
                                input_item_id itemid;
 
@@ -1065,7 +1065,7 @@ public:
                        }
 
                        // loop over all buttons
-                       for (int button = 0; button < SDL_JoystickNumButtons(joy); button++)
+                       for (int button = 0; button < std::min(SDL_JoystickNumButtons(joy), INPUT_MAX_BUTTONS); button++) // patch
                        {
                                input_item_id itemid;

I didn't dive deep in the code but it seems that in the original code, the axis and buttons that in excess may still be added to the system

	else if (axis < INPUT_MAX_AXIS + INPUT_MAX_ADD_ABSOLUTE)
					itemid = (input_item_id)(ITEM_ID_ADD_ABSOLUTE1 - INPUT_MAX_AXIS + axis);

It's probably a feature, not just a bug.
Any idea on how to fix the problem in a way that could be included in the next release?

@cuavas
Copy link
Member

cuavas commented Sep 19, 2019

It would really be better if you could fix your peripheral so it doesn't erroneously present itself as a joystick with a huge number of buttons.

@pixjuan
Copy link
Author

pixjuan commented Sep 20, 2019

I agree it is an unusual case, but the faulty code here is not mine, it's in the Teensy3 code base. Their basic "keyboard" example just provide this huge number of buttons, so other peripherals are likely to fail as well.
I will try to open an issue on Teensyduino project, but I wanted to have a look at the code first and didn't have the time to.

@spmorton
Copy link

spmorton commented Dec 5, 2019

This is not a teensy problem, I have the same issue with my Corsair k70 Gaming board. Detected by mame as a joystick. never would of thought that, been chasing this for some time now. Looks like it reports properly to me...
Input: Adding mouse #0: System mouse (device id: System mouse)
Mouse: Registered System mouse
Mouse: End initialization
Joystick: Start initialization
Input: Adding joystick #0: CorsairCorsairK70RGamingKeyboard (device id: CorsairCorsairK70RGamingKeyboard)
Joystick: Corsair Corsair K70R Gaming Keyboard
Joystick: ... 0 axes, 174 buttons 0 hats 0 balls
Joystick: ... Physical id 0 mapped to logical id 1
Joystick: ... Does not have haptic capability
Input: Adding joystick #1: ThrustmasterTMiniWireless (device id: ThrustmasterTMiniWireless)
Joystick: Thrustmaster T Mini Wireless
Joystick: ... 4 axes, 13 buttons 1 hats 0 balls
Joystick: ... Physical id 1 mapped to logical id 2
Joystick: ... Does not have haptic capability
Joystick: End initialization
Searching font Liberation Sans in -/usr/share/games/mame/fonts path/s
Matching font: /usr/share/fonts/truetype/liberation2/LiberationSans-Regular.ttf
OpenGL: VBO supported
OpenGL: PBO supported

@spmorton
Copy link

spmorton commented Dec 5, 2019

output of lsusb

Bus 004 Device 002: ID 8087:8002 Intel Corp.
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 005: ID 1b1c:1b05 Corsair
Bus 005 Device 006: ID 044f:d007 ThrustMaster, Inc.
Bus 005 Device 004: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 005 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 005 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:800a Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 002 Device 004: ID 1b1c:1b09 Corsair Vengeance K70R keyboard
Bus 002 Device 003: ID 1b1c:0c09 Corsair
Bus 002 Device 006: ID 0db0:3871 Micro Star International MS-3871 802.11bgn Wireless Module [Ralink RT8070]
Bus 002 Device 005: ID 0db0:a871 Micro Star International
Bus 002 Device 002: ID 03f0:1617 HP, Inc LaserJet 3015
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

@spmorton
Copy link

spmorton commented Dec 5, 2019

I dont have a lot of time to spend on this, but I will take a look around, seems like your joystick detection routine is a little broad ranged. Maybe it is an option for the SDL joystick query.

@cuavas
Copy link
Member

cuavas commented Dec 5, 2019

Can you post the actual HID descriptor, in raw or parsed format? (You can get this with USB Prober on macOS, not sure how to get it on Linux or Windows. I know that's not directly helpful, but it may be a starting point for finding an equivalent tool.)

@rb6502
Copy link
Contributor

rb6502 commented Dec 5, 2019

lsusb --verbose should show the descriptors.

@spmorton
Copy link

spmorton commented Dec 5, 2019

I have come across a potential solution involving udev detecting the kb as a joystick. One potential solution here https://github.com/denilsonsa/udev-joystick-blacklist
libsdl2 provides some great testing methods to help in
libsdl2-doc/html/d8/dee/_r_e_a_d_m_e-linux_8md_source.html

I will see if this is the case when I get home this evening.
However, this does not excuse the poor handling of a devices configuration by Mame. Remove the static limits and it is not a problem. I will note that I do remember the -verbose output did not include a system kb, and this could be a problem if the choice to handle this issue is to disregard the device rather than support it. I thought I looked at a class for the joysticks somewhere in the source code, there is a lot of it and I am not familiar with it. Point me in the right direction and I will fix it for you if you like, nothing like a dynamic array to solve a static problem.

@spmorton
Copy link

spmorton commented Dec 6, 2019

And there it is... my K70 has 3 input events and this one lists it as a joystick
P: /devices/pci0000:00/0000:00:14.0/usb2/2-9/2-9:1.0/0003:1B1C:1B09.002D/input/input61/event3
N: input/event3
L: 0
S: input/by-path/pci-0000:00:14.0-usb-0:9:1.0-event-joystick
S: input/by-id/usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-joystick
E: DEVPATH=/devices/pci0000:00/0000:00:14.0/usb2/2-9/2-9:1.0/0003:1B1C:1B09.002D/input/input61/event3
E: DEVNAME=/dev/input/event3
E: MAJOR=13
E: MINOR=67
E: SUBSYSTEM=input
E: USEC_INITIALIZED=83819980108
E: ID_INPUT=1
E: ID_INPUT_JOYSTICK=1
E: ID_INPUT_KEY=1
E: ID_INPUT_KEYBOARD=1
E: ID_VENDOR=Corsair
E: ID_VENDOR_ENC=Corsair
E: ID_VENDOR_ID=1b1c
E: ID_MODEL=Corsair_K70R_Gaming_Keyboard
E: ID_MODEL_ENC=Corsair\x20K70R\x20Gaming\x20Keyboard
E: ID_MODEL_ID=1b09
E: ID_REVISION=0109
E: ID_SERIAL=Corsair_Corsair_K70R_Gaming_Keyboard
E: ID_TYPE=hid
E: ID_BUS=usb
E: ID_USB_INTERFACES=:030101:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=pci-0000:00:14.0-usb-0:9:1.0
E: ID_PATH_TAG=pci-0000_00_14_0-usb-0_9_1_0
E: XKBMODEL=pc105
E: XKBLAYOUT=us
E: BACKSPACE=guess
E: ID_FOR_SEAT=input-pci-0000_00_14_0-usb-0_9_1_0
E: LIBINPUT_DEVICE_GROUP=3/1b1c/1b09:usb-0000:00:14.0-9
E: DEVLINKS=/dev/input/by-path/pci-0000:00:14.0-usb-0:9:1.0-event-joystick /dev/input/by-id/usb-Corsair_Corsair_K70R_Gaming_Keyboard-event-joystick
E: TAGS=:uaccess:power-switch:seat:

@spmorton
Copy link

spmorton commented Dec 6, 2019

I'm going to rerun this with a debug build, according to Valgrind:

==17784== Memcheck, a memory error detector
==17784== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17784== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==17784== Command: ./mame64
==17784==
[LUA ERROR] in run: /usr/share/games/mame/plugins/boot.lua:41: attempt to index a nil value (field 'entries')
==17784== Invalid write of size 4
==17784== at 0x80BF2FF: sdl_joystick_module::input_init(running_machine&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8053587: osd_common_t::input_init() (in /mnt/store/mame/mame/mame64)
==17784== by 0x8055CDC: osd_common_t::init_subsystems() (in /mnt/store/mame/mame/mame64)
==17784== by 0x8043C24: sdl_osd_interface::init(running_machine&) (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72A664: running_machine::start() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72C623: running_machine::run(bool) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8131914: mame_machine_manager::execute() (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCCD1: cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCEAA: cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x812FAD4: emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x424A480: main (in /mnt/store/mame/mame/mame64)
==17784== Address 0x195b2088 is 0 bytes after a block of size 760 alloc'd
==17784== at 0x1248DDEF: operator new(unsigned long) (vg_replace_malloc.c:334)
==17784== by 0x80BFA94: sdl_joystick_module::input_init(running_machine&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8053587: osd_common_t::input_init() (in /mnt/store/mame/mame/mame64)
==17784== by 0x8055CDC: osd_common_t::init_subsystems() (in /mnt/store/mame/mame/mame64)
==17784== by 0x8043C24: sdl_osd_interface::init(running_machine&) (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72A664: running_machine::start() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72C623: running_machine::run(bool) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8131914: mame_machine_manager::execute() (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCCD1: cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCEAA: cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x812FAD4: emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x424A480: main (in /mnt/store/mame/mame/mame64)
==17784==

valgrind: m_mallocfree.c:307 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 832, hi = 0.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.

host stacktrace:
==17784== at 0x580480A4: show_sched_status_wrk (m_libcassert.c:369)
==17784== by 0x580481B7: report_and_quit (m_libcassert.c:440)
==17784== by 0x58048349: vgPlain_assert_fail (m_libcassert.c:506)
==17784== by 0x58051A72: get_bszB_as_is (m_mallocfree.c:305)
==17784== by 0x58051A72: is_inuse_block (m_mallocfree.c:333)
==17784== by 0x58051A72: deferred_reclaimSuperblock (m_mallocfree.c:1987)
==17784== by 0x58051A72: mergeWithFreeNeighbours (m_mallocfree.c:2083)
==17784== by 0x58004F1B: release_oldest_block (mc_malloc_wrappers.c:169)
==17784== by 0x58004F1B: create_MC_Chunk (mc_malloc_wrappers.c:212)
==17784== by 0x58005C72: vgMemCheck_new_block (mc_malloc_wrappers.c:388)
==17784== by 0x58005C72: vgMemCheck___builtin_new (mc_malloc_wrappers.c:417)
==17784== by 0x580A7883: do_client_request (scheduler.c:1925)
==17784== by 0x580A7883: vgPlain_scheduler (scheduler.c:1488)
==17784== by 0x580F5D80: thread_wrapper (syswrap-linux.c:103)
==17784== by 0x580F5D80: run_a_thread_NORETURN (syswrap-linux.c:156)
==17784== by 0x580F606A: vgModuleLocal_start_thread_NORETURN (syswrap-linux.c:320)
==17784== by 0x580B8A4D: ??? (in /usr/lib/x86_64-linux-gnu/valgrind/memcheck-amd64-linux)
==17784== by 0xDEADBEEFDEADBEEE: ???
==17784== by 0xDEADBEEFDEADBEEE: ???
==17784== by 0xDEADBEEFDEADBEEE: ???

sched status:
running_tid=4

Thread 1: status = VgTs_WaitSys syscall 257 (lwpid 17784)
==17784== at 0x12633D0E: open (open64.c:48)
==17784== by 0xBE2C636: osd_file::open(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned int, std::unique_ptr<osd_file, std::default_delete<osd_file> >&, unsigned long&) (in /mnt/store/mame/mame/mame64)
==17784== by 0xBB6E007: util::archive_file::open_7z(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::unique_ptr<util::archive_file, std::default_deleteutil::archive_file >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0xB695296: emu_file::attempt_zipped() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB695EB7: emu_file::open(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x814E5A6: ui::menu_select_game::load_available_machines() (in /mnt/store/mame/mame/mame64)
==17784== by 0x814F9D3: ui::menu_select_game::menu_select_game(mame_ui_manager&, render_container&, char const*) [clone .constprop.515] (in /mnt/store/mame/mame/mame64)
==17784== by 0x8150270: ui::menu_select_game::force_game_select(mame_ui_manager&, render_container&) (in /mnt/store/mame/mame/mame64)
==17784== by 0xAB824B6: driver_device::device_start() (in /mnt/store/mame/mame/mame64)
==17784== by 0xAB23CE2: device_t::start() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB726978: running_machine::start_all_devices() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72ADDD: running_machine::start() (in /mnt/store/mame/mame/mame64)
==17784== by 0xB72C623: running_machine::run(bool) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8131914: mame_machine_manager::execute() (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCCD1: cli_frontend::start_execution(mame_machine_manager*, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x81BCEAA: cli_frontend::execute(std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x812FAD4: emulator_info::start_frontend(emu_options&, osd_interface&, std::vector<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&) (in /mnt/store/mame/mame/mame64)
==17784== by 0x424A480: main (in /mnt/store/mame/mame/mame64)
client stack range: [0x1FFEFEC000 0x1FFF000FFF] client SP: 0x1FFEFF8310
valgrind stack range: [0x1004C2D000 0x1004D2CFFF] top usage: 18568 of 1048576

Thread 2: status = VgTs_WaitSys syscall 271 (lwpid 17786)
==17784== at 0x14342916: ppoll (ppoll.c:39)
==17784== by 0x14441A20: pa_mainloop_poll (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3)
==17784== by 0x14441FED: pa_mainloop_iterate (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3)
==17784== by 0x1444209F: pa_mainloop_run (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3)
==17784== by 0x125A6E9E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x1254CE8B: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x125C0118: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x12629FA2: start_thread (pthread_create.c:486)
==17784== by 0x1434D4CE: clone (clone.S:95)
client stack range: [0x1CFF3000 0x1D031FFF] client SP: 0x1D031CA0
valgrind stack range: [0x101326F000 0x101336EFFF] top usage: 2904 of 1048576

Thread 3: status = VgTs_WaitSys syscall 1 (lwpid 17787)
==17784== at 0x126334A7: __libc_write (write.c:26)
==17784== by 0x126334A7: write (write.c:24)
==17784== by 0x15446FF4: pa_write (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so)
==17784== by 0x1544E22B: pa_fdsem_post (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so)
==17784== by 0x15466419: pa_srbchannel_write (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so)
==17784== by 0x154646C4: ??? (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so)
==17784== by 0x1546573C: ??? (in /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so)
==17784== by 0x14441DEF: pa_mainloop_dispatch (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3)
==17784== by 0x14441FFB: pa_mainloop_iterate (in /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3)
==17784== by 0x125A6CC6: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x1250395A: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x1254CE8B: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x125C0118: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0)
==17784== by 0x12629FA2: start_thread (pthread_create.c:486)
==17784== by 0x1434D4CE: clone (clone.S:95)
client stack range: [0x3E0FC000 0x3E8FAFFF] client SP: 0x3E8FAB00
valgrind stack range: [0x101358B000 0x101368AFFF] top usage: 5720 of 1048576

Thread 4: status = VgTs_Runnable (lwpid 17788)
==17784== at 0x1248DDEF: operator new(unsigned long) (vg_replace_malloc.c:334)
==17784== by 0x14050EEA: std::__cxx11::basic_string<char, std::char_traits, std::allocator >::_M_mutate(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==17784== by 0x14051C9A: std::__cxx11::basic_string<char, std::char_traits, std::allocator >::_M_replace(unsigned long, unsigned long, char const*, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==17784== by 0xBB705FA: normalize_unicode[abi:cxx11](char const*, unicode_normalization_form, bool) (in /mnt/store/mame/mame/mame64)
==17784== by 0x8154EEC: ui::menu_select_game::persistent_data::do_cache_data() (in /mnt/store/mame/mame/mame64)
==17784== by 0x13FEEB2E: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==17784== by 0x12629FA2: start_thread (pthread_create.c:486)
==17784== by 0x1434D4CE: clone (clone.S:95)
client stack range: [0x3ECFD000 0x3F4FBFFF] client SP: 0x3F4FBAF0
valgrind stack range: [0x1015FD5000 0x10160D4FFF] top usage: 8536 of 1048576

Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn't help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.

@spmorton
Copy link

spmorton commented Dec 7, 2019

gdb with full debug symbols:

Starting program: /mnt/store/mame/mame/mame64d
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffdeff9700 (LWP 16154)]
[New Thread 0x7fffdefb8700 (LWP 16160)]
mame64d: ../../../../../src/emu/inputdev.cpp:295: input_item_id input_device::add_item(const char*, input_item_id, item_get_state_func, void*): Assertion `m_item[itemid] == nullptr' failed.

Thread 1 "mame64d" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) where
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff6077535 in __GI_abort () at abort.c:79
#2 0x00007ffff607740f in __assert_fail_base (fmt=0x7ffff61d9ee0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x555565b62e74 "m_item[itemid] == nullptr",
file=0x555565b62b60 "../../../../../src/emu/inputdev.cpp", line=295, function=) at assert.c:92
#3 0x00007ffff6085102 in __GI___assert_fail (assertion=0x555565b62e74 "m_item[itemid] == nullptr", file=0x555565b62b60 "../../../../../src/emu/inputdev.cpp", line=295,
function=0x555565b63540 <input_device::add_item(char const*, input_item_id, int ()(void, void*), void*)::PRETTY_FUNCTION> "input_item_id input_device::add_item(const char*, input_item_id, item_get_state_func, void*)") at assert.c:101
#4 0x0000555561882bf9 in input_device::add_item () at ../../../../../src/emu/inputdev.cpp:295
#5 0x000055555de19116 in sdl_joystick_module::input_init () at ../../../../../src/osd/modules/input/input_sdl.cpp:1082
#6 0x000055555dda82e0 in osd_common_t::input_init () at ../../../../../src/osd/modules/lib/osdobj_common.cpp:715
#7 0x000055555ddaad8d in osd_common_t::init_subsystems () at ../../../../../src/osd/modules/lib/osdobj_common.cpp:685
#8 0x000055555dd979d3 in sdl_osd_interface::init () at ../../../../../src/osd/sdl/sdlmain.cpp:502
#9 0x00005555618d4f89 in running_machine::start () at ../../../../../src/emu/machine.cpp:205
#10 0x00005555618d6eb3 in running_machine::run () at ../../../../../src/emu/machine.cpp:319
#11 0x000055555de8f3ac in mame_machine_manager::execute () at ../../../../../src/frontend/mame/mame.cpp:261
#12 0x000055555df1e59d in cli_frontend::start_execution () at ../../../../../src/frontend/mame/clifront.cpp:264
#13 0x000055555df1e70e in cli_frontend::execute () at ../../../../../src/frontend/mame/clifront.cpp:280
#14 0x000055555de8d33b in emulator_info::start_frontend () at ../../../../../src/frontend/mame/mame.cpp:392
#15 0x00005555595183b3 in main () at ../../../../../src/osd/sdl/sdlmain.cpp:217

@spmorton
Copy link

spmorton commented Dec 7, 2019

trying to compile a fix now

@spmorton
Copy link

spmorton commented Dec 7, 2019

ok this is an unorthodox way of providing the fix... so what!
Change line 1068 of input_sdl.cpp to be
for (int button = 0; button < SDL_JoystickNumButtons(joy) && button < INPUT_MAX_BUTTONS; button++)
And the problem is worked around
The real problem is in the 3rd party SDL driver crap and 'I aint fixin that'

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

Can you please stop sidestepping and actually post the HID descriptors?

@spmorton
Copy link

spmorton commented Dec 7, 2019

sure by all means...
005:007:002:DESCRIPTOR 1575690431.708598
05 0C 09 01 A1 01 05 0C 19 00 2A FF 0F 15 00 26
FF 0F 75 10 95 02 81 00 C0

005:007:001:DESCRIPTOR 1575690431.711363
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
75 01 95 08 81 02 75 08 95 01 81 01 05 07 19 00
2A FF 00 15 00 26 FF 00 75 08 95 06 81 00 C0

005:007:000:DESCRIPTOR 1575690431.714341
05 01 09 02 A1 01 09 01 A1 00 05 09 19 01 29 10
15 00 25 01 95 10 75 01 81 02 05 01 09 30 09 31
16 01 80 26 FF 7F 75 10 95 02 81 06 09 38 15 81
25 7F 75 08 95 01 81 06 06 00 FF 15 00 26 FF 00
09 DA 75 08 95 08 B1 02 C0 C0

@spmorton
Copy link

spmorton commented Dec 7, 2019

tackling this on a device basis will be maddening as more and more KBs expose other functionality, like volume controls and media player interfaces which is what is going on with the K70. One event is the KB, the other is a volume control and the third is a media player control. The only real solution is to circumvent the excessive number of 'buttons' or deal with them correctly.
As in the case of this loop here:
if the number of buttons exceeds the limit, you start writing with some phony descriptor with 'device()->add_item' but the backend implementation cannot handle the number of items being pushed and the exception is not handled so it goes boom. At least stop writing beyond the capabilities of the back end as I have employed or fix the back end.

		for (int button = 0; button < SDL_JoystickNumButtons(joy) && button < INPUT_MAX_BUTTONS; button++)
		{
			input_item_id itemid;

			devinfo->joystick.buttons[button] = 0;

			if (button < INPUT_MAX_BUTTONS)
				itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
			else if (button < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
				itemid = (input_item_id)(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + button);
			else
				itemid = ITEM_ID_OTHER_SWITCH;

			snprintf(tempname, sizeof(tempname), "button %d", button);
			devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]);
		}

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x05, 0x0C,        //   Usage Page (Consumer)
0x19, 0x00,        //   Usage Minimum (Unassigned)
0x2A, 0xFF, 0x0F,  //   Usage Maximum (0x0FFF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x0F,  //   Logical Maximum (4095)
0x75, 0x10,        //   Report Size (16)
0x95, 0x02,        //   Report Count (2)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

Consumer electronics controls (mostly media control keys).

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        //   Report Size (8)
0x95, 0x01,        //   Report Count (1)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x2A, 0xFF, 0x00,  //   Usage Maximum (0xFF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x06,        //   Report Count (6)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

Keyboard, maximum 256 keys.

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x02,        // Usage (Mouse)
0xA1, 0x01,        // Collection (Application)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x10,        //     Usage Maximum (0x10)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x10,        //     Report Count (16)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x16, 0x01, 0x80,  //     Logical Minimum (-32767)
0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)
0x75, 0x10,        //     Report Size (16)
0x95, 0x02,        //     Report Count (2)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x81,        //     Logical Minimum (-127)
0x25, 0x7F,        //     Logical Maximum (127)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x06, 0x00, 0xFF,  //     Usage Page (Vendor Defined 0xFF00)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x09, 0xDA,        //     Usage (0xDA)
0x75, 0x08,        //     Report Size (8)
0x95, 0x08,        //     Report Count (8)
0xB1, 0x02,        //     Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              //   End Collection
0xC0,              // End Collection

Mouse with 16 buttons, X/Y axes, wheel, and a vendor-defined axis.

I'm still confused about where the joystick with 174 buttons is coming from. There's the consumer electronics controls, the keyboard, and the mouse. I don't see the number 174 (0xAE) anywhere, either. MAME doesn't blow up on every keyboard with media control keys or see them as a joystick. What's actually causing this keyboard to be detected as a joystick?

@spmorton
Copy link

spmorton commented Dec 7, 2019

BTW, my apologies if I come across abrasive and condescending. I love the work you guys have done with all of this. I am just really busy with work and PhD studies, I just need to blow off some steam playing beasterizor (bloody roar)

@spmorton
Copy link

spmorton commented Dec 7, 2019

Its Udev as I post earlier

@spmorton
Copy link

spmorton commented Dec 7, 2019

So SDL reads the /dev/events(x) looking for the JOYSTICK flag.

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

Udev may be detecting it as a joystick, but what is causing Udev to detect it as a joystick? That's the unanswered question. The descriptors you posted look no different to a regular composite keyboard/mouse device (like the Cherry and Sanwa Supply keyboards with integrated trackball/trackpad). There must be something special about it that causes the issue.

@spmorton
Copy link

spmorton commented Dec 7, 2019

I cant answer that, this goes back to kernel driver crap

@spmorton
Copy link

spmorton commented Dec 7, 2019

The K70 has programmable keys, that event id is listed as the joystick

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

Well where's the descriptor for it?

@spmorton
Copy link

spmorton commented Dec 7, 2019

I gotta get my glasses checked, 1b1c:1b09 vs 1b1c:1b05

002:018:002:DESCRIPTOR 1575692877.783694
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
75 01 95 08 81 02 19 00 29 6F 15 00 25 01 75 01
95 70 81 02 C0

002:018:001:DESCRIPTOR 1575692877.784025
05 0C 09 01 A1 01 05 0C 19 00 2A FF 0F 15 00 26
FF 0F 75 10 95 02 81 00 C0

002:018:000:DESCRIPTOR 1575692877.784456
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
75 01 95 08 81 02 75 08 95 01 81 01 05 07 19 00
2A FF 00 15 00 26 FF 00 75 08 95 06 81 00 05 08
19 01 29 03 25 01 75 01 95 03 91 02 95 05 91 01

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0x6F,        //   Usage Maximum (0x6F)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x70,        //   Report Count (112)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

Keyboard, maximum 112 keys.

0x05, 0x0C,        // Usage Page (Consumer)
0x09, 0x01,        // Usage (Consumer Control)
0xA1, 0x01,        // Collection (Application)
0x05, 0x0C,        //   Usage Page (Consumer)
0x19, 0x00,        //   Usage Minimum (Unassigned)
0x2A, 0xFF, 0x0F,  //   Usage Maximum (0x0FFF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x0F,  //   Logical Maximum (4095)
0x75, 0x10,        //   Report Size (16)
0x95, 0x02,        //   Report Count (2)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

Consumer electronics controls.

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x08,        //   Report Size (8)
0x95, 0x01,        //   Report Count (1)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x2A, 0xFF, 0x00,  //   Usage Maximum (0xFF)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x75, 0x08,        //   Report Size (8)
0x95, 0x06,        //   Report Count (6)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x03,        //   Usage Maximum (Scroll Lock)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x03,        //   Report Count (3)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05,        //   Report Count (5)
0x91, 0x01,        //   Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)

Keyboard, maximum 256 keys, 3 LEDs.

Weird, it looks like two keyboards in one? I still don't see where the number 174 comes from.

@rb6502 given the current limitations of the MAME input module interface, and given that I'm planning to address pen/touch/IME edit before I even think about a serious rework of joysticks, what's your opinion on the best way to address this?

@rb6502
Copy link
Contributor

rb6502 commented Dec 7, 2019

@cuavas Given those things I'm inclined to go with his suggested change where we limit the buttons to INPUT_MAX_BUTTONS at the OSD level. It's bad that the keyboard is being detected that way though, the Microsoft keyboard on my Linux desktop has media controls and udev definitely does not report it as a joystick.

@spmorton
Copy link

spmorton commented Dec 7, 2019

I think it is a kernel 4.9 dependency
"A patch has been accepted into Linux kernel 4.9, so that Microsoft devices will not be detected as joysticks anymore. Thus, those devices are not included in after_kernel_4_9/*"
From:
https://github.com/denilsonsa/udev-joystick-blacklist

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

The proposed fix isn't quite right - there's already code that's supposed to deal with excess buttons. Here's the fragment in question (starting at line 1072 in current master):

			// loop over all buttons
			for (int button = 0; button < SDL_JoystickNumButtons(joy); button++)
			{
				input_item_id itemid;

				devinfo->joystick.buttons[button] = 0;

				if (button < INPUT_MAX_BUTTONS)
					itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
				else if (button < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
					itemid = (input_item_id)(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + button);
				else
					itemid = ITEM_ID_OTHER_SWITCH;

				snprintf(tempname, sizeof(tempname), "button %d", button);
				devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]);
			}

Note that it's already supposed to map excess buttons to switches. There's some other limit it's not checking.

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

Oh duh, INPUT_MAX_BUTTONS and MAX_BUTTONS are not the same.

@spmorton
Copy link

spmorton commented Dec 7, 2019

I hate that when it happens, and for me, it happens far too often :-)

@cuavas
Copy link
Member

cuavas commented Dec 7, 2019

a660815 should work around crashes, both on start and if you actually press one of the excess buttons.

@pixjuan
Copy link
Author

pixjuan commented Jan 18, 2020

Hi,
I downloaded the sources for the 0.217 and compiled it on Debian Buster and it's not crashing anymore when I plug my joystick.
As far as I'm concerned, this is fixed.
If it also works for @spmorton I think we can close this issue.
Thanks for your help.

@pixjuan pixjuan closed this as completed Feb 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants