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

Mac: HID Manager segfaults after registering, then unregistering input report callback #116

Open
mrpippy opened this issue Apr 13, 2013 · 6 comments

Comments

@mrpippy
Copy link
Contributor

mrpippy commented Apr 13, 2013

This is a bug in the underlying OS X HID Manager, not hidapi itself

When an input report callback is registered (using IOHIDDeviceRegisterInputReportCallback()) and then unregistered (by passing NULL as the callback to the same function), the HID Manager will segfault when the next input report is received.

This can easily be reproduced with the following change to hidapi's mac/hid.c:

--- a/mac/hid.c
+++ b/mac/hid.c
@@ -718,6 +718,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
                IOHIDDeviceRegisterInputReportCallback(
                        dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
                        &hid_report_callback, dev);
+               IOHIDDeviceRegisterInputReportCallback(
+                       dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
+                       NULL, dev);
                IOHIDDeviceRegisterRemovalCallback(dev->device_handle, hid_device_removal_callback, dev);

                /* Start the read thread */

And the backtrace from the segfault:

#0  0x00007fff82d51250 in objc_msgSend ()
#1  0x7000000000000000 in ?? ()
#2  0x00000001000c1a4f in IOHIDDeviceClass::_hidReportHandlerCallback ()
#3  0x00007fff864d0e40 in __CFMachPortPerform ()
#4  0x00007fff864d0d09 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#5  0x00007fff864d0a49 in __CFRunLoopDoSource1 ()
#6  0x00007fff86503c02 in __CFRunLoopRun ()
#7  0x00007fff865030e2 in CFRunLoopRunSpecific ()
#8  0x00000001000026ea in read_thread (param=0x10010ac80) at hid.c:647
#9  0x00007fff8ef607a2 in _pthread_start ()
#10 0x00007fff8ef4d1e1 in thread_start ()

I don't believe this is causing any crashes for hidapi, aside from a possible race condition if an input report is received during hid_close() (between the call to IOHIDDeviceRegisterInputReportCallback() to unregister the callback and the call to IOHIDDeviceClose())

I've tracked down the cause of this bug in the HID Manager code, and I'll add rdar links, etc. once I get those submitted.

@signal11
Copy link
Owner

Hey, this is great news!

I guess the trick now is to find the spot where this unregistration should happen. I remember from before that if you don't unregister and then close the device, it will crash.

@mrpippy
Copy link
Contributor Author

mrpippy commented Apr 13, 2013

From looking at the current 10.7 and 10.8 HID Manager code, I don't believe there is any safe time to unregister the input report callback. hid_close() should just close and then release the device without trying to unregister anything.

We should do more testing to see if the callbacks really need to be unregistered on 10.5/10.6, I think 10.7/10.8 don't need it.

(These bugs/changes started in 10.7 when they added support for registering multiple removal/input report/input value callbacks)

@signal11
Copy link
Owner

That's starting to sound familiar. Thanks Apple, for repeatedly breaking userspace :(

@signal11
Copy link
Owner

signal11 commented Sep 9, 2013

Hi mrpippy, any updates on this?

@mrpippy
Copy link
Contributor Author

mrpippy commented Sep 22, 2013

I never submitted any bugs to Apple for this--I don't think there's any point unless I can reproduce on a Mavericks beta, and I don't currently have access to betas.

@mrpippy
Copy link
Contributor Author

mrpippy commented Sep 27, 2013

BTW, a little off topic, but it looks like the Infiniti Q50 is using hidapi in its iPod interface code :P http://www.globaldenso.com/en/opensource/ivi/nissan/

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

2 participants