larskanis/libusb

Lib crashes after plugging in a usb device and `context.eventmachine_register`

mareczek opened this issue · 4 comments

Code sample:

#!/usr/bin/env ruby
require 'libusb'
require 'libusb/eventmachine'

context = LIBUSB::Context.new

EventMachine.run do
  context.eventmachine_register

  puts "Started!"
end

Error in the console after plugging in / out a usb device:

Starter!
HOTPLUG_EVENT_DEVICE_ARRIVED: #<LIBUSB::Device 20/9 04b8:0e04 EPSON TM-T801FV 535739460006190000 (Printer (01,02))>
/Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/context.rb:394:in `block in on_hotplug_event': hotplug event handler must return :finish or :repeat (ArgumentError)
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/context.rb:192:in `libusb_handle_events_timeout_completed'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/context.rb:192:in `handle_events'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/eventmachine.rb:97:in `block in eventmachine_add_pollfd'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/eventmachine.rb:79:in `block in need_handle_events'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/eventmachine.rb:78:in `each'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/libusb-0.5.1/lib/libusb/eventmachine.rb:78:in `need_handle_events'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/eventmachine-1.2.0.1/lib/eventmachine.rb:194:in `run_machine'
    from /Users/mark/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/eventmachine-1.2.0.1/lib/eventmachine.rb:194:in `run'
    from app/main.rb:22:in `<main>'

I tried also defining a callback:

context.on_hotplug_event do |device, event|
  :repeat
end

EventMachine.run do
  puts "Starting Event Machine ..."

  context.eventmachine_register

  puts "Started!"
end

since the error is that the callback should return :finish or :repeat but still crashes :-(

Hi @mareczek,

there seems to happen something magic in your program: The stack trace shows, that the raise is executed in context.rb:394:in 'block in on_hotplug_event' . So there is a registered hotplug event handler in the LIBUSB Context. However the method on_hotplug_event isn't called anywhere in the libusb code. It must have been called from somewhere else.

I just verified, that the hotplug support works with EventMachine. If I don't register a hotplug event handler per on_hotplug_event , all plug or unplug events are ignored. This is your first sample code. It works as expected on Linux.

If I register a hotplug event handler (as in your second sample) it receives any hotplug events as long as EventMachine.run is running.

Can you please do some debugging on your hand, to find out where the wrong and obviously unintended hotplug event handler registration comes from?

Hi @larskanis,

thank you for your answer. Is it possible that libusb memorized a callback from a different process (pry session) that was already killed?

Will conduct tests on my end.

@larskanis : I rebooted my computer and it works as you described. Meaning it is more likely some callback was persisted by libusb somehow.